Shows one seeded OHLC data set toggled between no filter, Heikin-Ashi, Renko, and Point & Figure views.
drawExample.ts
angular.ts
1import {
2 EllipsePointMarker,
3 FastCandlestickRenderableSeries,
4 MouseWheelZoomModifier,
5 NumberRange,
6 NumericAxis,
7 OhlcDataSeries,
8 RolloverModifier,
9 SciChartJsNavyTheme,
10 SciChartSurface,
11 XPointMarker,
12 XyDataSeries,
13 XyScatterRenderableSeries,
14 ZoomExtentsModifier,
15 ZoomPanModifier,
16} from "scichart";
17import { OhlcHeikinAshiFilter, OhlcRenkoFilter, PointAndFigureFilter } from "scichart-financial-tools";
18
19export type TFilterMode = "source" | "heikinAshi" | "renko" | "pointAndFigure";
20
21const SOURCE_POINT_COUNT = 90;
22const RENKO_BRICK_SIZE = 1.4;
23const RENKO_REVERSAL_AMOUNT = 2;
24const PNF_BOX_SIZE = 1.2;
25const PNF_REVERSAL_AMOUNT = 2;
26
27const createSeededRandom = (seed: number) => {
28 let state = seed >>> 0;
29 return () => {
30 state = (1664525 * state + 1013904223) >>> 0;
31 return state / 0x100000000;
32 };
33};
34
35const createSeededOhlcData = (count: number) => {
36 const random = createSeededRandom(20260514);
37 const xValues: number[] = [];
38 const openValues: number[] = [];
39 const highValues: number[] = [];
40 const lowValues: number[] = [];
41 const closeValues: number[] = [];
42
43 let close = 116;
44 for (let i = 0; i < count; i++) {
45 const trend = Math.sin(i / 9) * 0.9 + Math.cos(i / 18) * 0.45;
46 const noise = (random() - 0.5) * 1.9;
47 const open = close + (random() - 0.5) * 1.2;
48 close = Math.max(78, open + trend + noise);
49 const high = Math.max(open, close) + 0.5 + random() * 1.6;
50 const low = Math.min(open, close) - 0.5 - random() * 1.5;
51
52 xValues.push(i);
53 openValues.push(Number(open.toFixed(2)));
54 highValues.push(Number(high.toFixed(2)));
55 lowValues.push(Number(low.toFixed(2)));
56 closeValues.push(Number(close.toFixed(2)));
57 }
58
59 return { xValues, openValues, highValues, lowValues, closeValues };
60};
61
62export const drawExample = async (rootElement: string | HTMLDivElement) => {
63 const { sciChartSurface, wasmContext } = await SciChartSurface.create(rootElement, {
64 theme: new SciChartJsNavyTheme(),
65 });
66
67 const xAxis = new NumericAxis(wasmContext, {
68 axisTitle: "Source Index",
69 growBy: new NumberRange(0.01, 0.01),
70 labelPrecision: 0,
71 });
72 const yAxis = new NumericAxis(wasmContext, {
73 axisTitle: "Price",
74 growBy: new NumberRange(0.08, 0.18),
75 labelPrecision: 2,
76 });
77 sciChartSurface.xAxes.add(xAxis);
78 sciChartSurface.yAxes.add(yAxis);
79
80 const sourceData = createSeededOhlcData(SOURCE_POINT_COUNT);
81 const sourceSeries = new OhlcDataSeries(wasmContext, {
82 ...sourceData,
83 dataSeriesName: "Source OHLC",
84 });
85 const heikinAshiFilter = new OhlcHeikinAshiFilter(sourceSeries, {
86 dataSeriesName: "Heikin-Ashi",
87 });
88 const renkoFilter = new OhlcRenkoFilter(sourceSeries, {
89 dataSeriesName: "Renko",
90 brickSize: RENKO_BRICK_SIZE,
91 reversalAmount: RENKO_REVERSAL_AMOUNT,
92 });
93 const pointAndFigureFilter = new PointAndFigureFilter(sourceSeries, {
94 dataSeriesName: "Point & Figure",
95 boxSize: PNF_BOX_SIZE,
96 reversalAmount: PNF_REVERSAL_AMOUNT,
97 });
98
99 const candleSeries = new FastCandlestickRenderableSeries(wasmContext, {
100 dataSeries: sourceSeries,
101 dataPointWidth: 0.62,
102 strokeThickness: 1,
103 });
104
105 const xMarksData = new XyDataSeries(wasmContext, { dataSeriesName: "Rising X" });
106 const oMarksData = new XyDataSeries(wasmContext, { dataSeriesName: "Falling O" });
107 const xMarks = new XyScatterRenderableSeries(wasmContext, {
108 dataSeries: xMarksData,
109 pointMarker: new XPointMarker(wasmContext, {
110 width: 16,
111 height: 16,
112 stroke: "#41D6A4",
113 strokeThickness: 3,
114 }),
115 });
116 const oMarks = new XyScatterRenderableSeries(wasmContext, {
117 dataSeries: oMarksData,
118 pointMarker: new EllipsePointMarker(wasmContext, {
119 width: 15,
120 height: 15,
121 stroke: "#FF6B6B",
122 fill: "transparent",
123 strokeThickness: 3,
124 }),
125 });
126
127 sciChartSurface.renderableSeries.add(candleSeries, xMarks, oMarks);
128 sciChartSurface.chartModifiers.add(
129 new ZoomPanModifier(),
130 new ZoomExtentsModifier(),
131 new MouseWheelZoomModifier(),
132 new RolloverModifier()
133 );
134
135 const syncPointAndFigureData = () => {
136 const result = pointAndFigureFilter.lastResult;
137 xMarksData.clear();
138 oMarksData.clear();
139 xMarksData.appendRange(
140 result.xMarks.map((mark) => mark.columnIndex),
141 result.xMarks.map((mark) => mark.price)
142 );
143 oMarksData.appendRange(
144 result.oMarks.map((mark) => mark.columnIndex),
145 result.oMarks.map((mark) => mark.price)
146 );
147 return result;
148 };
149
150 const setFilterMode = (mode: TFilterMode) => {
151 candleSeries.isVisible = mode !== "pointAndFigure";
152 xMarks.isVisible = mode === "pointAndFigure";
153 oMarks.isVisible = mode === "pointAndFigure";
154 xAxis.axisTitle = mode === "pointAndFigure" ? "P&F Column" : "Source Index";
155
156 if (mode === "source") {
157 candleSeries.dataSeries = sourceSeries;
158 } else if (mode === "heikinAshi") {
159 candleSeries.dataSeries = heikinAshiFilter;
160 } else if (mode === "renko") {
161 candleSeries.dataSeries = renkoFilter;
162 } else {
163 syncPointAndFigureData();
164 }
165
166 sciChartSurface.zoomExtents(300);
167 };
168
169 setFilterMode("source");
170
171 return { sciChartSurface, setFilterMode };
172};
173In Angular, bind the selected filter mode to template controls and call the same chart update function from click handlers. The seeded OHLC source and filter instances can live on the component class after chart initialization.

Discover how to create a Angular Candlestick Chart or Stock Chart using SciChart.js. For high Performance JavaScript Charts, get your free demo now.

Easily create Angular OHLC Chart or Stock Chart using feature-rich SciChart.js chart library. Supports custom colors. Get your free trial now.

Create a Angular Realtime Ticking Candlestick / Stock Chart with live ticking and updating, using the high performance SciChart.js chart library. Get free demo now.

Create an Angular heatmap chart showing historical orderbook levels, using the high performance SciChart.js chart library. Get free demo now.

Create a Angular Multi-Pane Candlestick / Stock Chart with indicator panels, synchronized zooming, panning and cursors. Get your free trial of SciChart.js now.

Demonstrating the capability of SciChart.js to create a composite 2D & 3D Chart application. An example like this could be used to visualize Tenor curves in a financial setting, or other 2D/3D data combined on a single screen.

Create a Angular Multi-Pane Candlestick / Stock Chart with indicator panels, synchronized zooming, panning and cursors. Get your free trial of SciChart.js now.

Create a Angular Depth Chart, using the high performance SciChart.js chart library. Get free demo now.

Demonstrates how to place Buy/Sell arrow markers on a Angular Stock Chart using SciChart.js - Annotations API

This demo shows you how to create a <strong>{frameworkName} User Annotated Stock Chart</strong> using SciChart.js. Custom modifiers allow you to add lines and markers, then use the built in serialisation functions to save and reload the chart, including the data and all your custom annotations.

Build high-performance financial apps with Angular trading drawing tools. Try SciChart’s demo to see the advanced drawing tools for trading apps in action.

Create a custom Angular stock chart annotation by extending SciChart.js PolyLineAnnotation with paired dashed connectors.

Deploy the ultimate Angular freehand drawing tool in your app. Render complex freehand drawing tools with a smooth UI experience. Try the SciChart demo today.