Angular User Annotated Stock Chart

This demo shows you how to create a Angular User Annotated Stock Chart 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.

Fullscreen

Edit

 Edit

Docs

drawExample.ts

angular.ts

binanceRestClient.ts

ExampleDataProvider.ts

theme.ts

CreateLineAnnotationModifier.ts

CreateTradeMarkerModifier.ts

RulerModifier.ts

Copy to clipboard
Minimise
Fullscreen
1// SCICHART EXAMPLE
2import {
3    AnnotationClickEventArgs,
4    buildDataSeries,
5    CategoryAxis,
6    chartReviver,
7    configure2DSurface,
8    CursorModifier,
9    CursorTooltipSvgAnnotation,
10    CustomAnnotation,
11    DateTimeNumericAxis,
12    EAutoRange,
13    EBaseType,
14    ECoordinateMode,
15    EDataSeriesType,
16    EExecuteOn,
17    EFillPaletteMode,
18    EHorizontalAnchorPoint,
19    EMultiLineAlignment,
20    ENumericFormat,
21    ESeriesType,
22    EVerticalAnchorPoint,
23    FastCandlestickRenderableSeries,
24    FastColumnRenderableSeries,
25    FastLineRenderableSeries,
26    FastMountainRenderableSeries,
27    FastOhlcRenderableSeries,
28    GradientParams,
29    IFillPaletteProvider,
30    IPointMetadata,
31    IRenderableSeries,
32    MouseWheelZoomModifier,
33    NativeTextAnnotation,
34    NumberRange,
35    NumericAxis,
36    OhlcDataSeries,
37    OhlcSeriesInfo,
38    parseColorToUIntArgb,
39    Point,
40    registerFunction,
41    SciChartOverview,
42    SciChartSurface,
43    SeriesInfo,
44    SmartDateLabelProvider,
45    TOhlcSeriesData,
46    XyDataSeries,
47    XyMovingAverageFilter,
48    ZoomExtentsModifier,
49    ZoomPanModifier,
50} from "scichart";
51import { appTheme } from "../../../theme";
52import { CreateTradeMarkerModifier } from "./CreateTradeMarkerModifier";
53import { CreateLineAnnotationModifier } from "./CreateLineAnnotationModifier";
54import { VerticalYRulerModifier } from "./RulerModifier";
55import { simpleBinanceRestClient } from "../../../ExampleData/binanceRestClient";
56import { ExampleDataProvider } from "../../../ExampleData/ExampleDataProvider";
57
58const deleteOnClick = (args: AnnotationClickEventArgs) => {
59    if (args.sender.isSelected && args.mouseArgs.ctrlKey) {
60        args.sender.parentSurface.annotations.remove(args.sender, true);
61    }
62};
63
64registerFunction(EBaseType.OptionFunction, "deleteOnClick", deleteOnClick);
65
66export const drawExample = async (divElementId: string | HTMLDivElement) => {
67    // Create a SciChartSurface
68    const { sciChartSurface, wasmContext } = await SciChartSurface.create(divElementId, {
69        theme: appTheme.SciChartJsTheme,
70    });
71
72    const xAxis = new CategoryAxis(wasmContext, {
73        // autoRange.never as we're setting visibleRange explicitly below. If you dont do this, leave this flag default
74        autoRange: EAutoRange.Never,
75        labelProvider: new SmartDateLabelProvider(),
76    });
77    sciChartSurface.xAxes.add(xAxis);
78
79    // Create a NumericAxis on the YAxis with 2 Decimal Places
80    sciChartSurface.yAxes.add(
81        new NumericAxis(wasmContext, {
82            growBy: new NumberRange(0.1, 0.1),
83            labelFormat: ENumericFormat.Decimal,
84            labelPrecision: 2,
85            labelPrefix: "$",
86            autoRange: EAutoRange.Always,
87        })
88    );
89
90    const day = 24 * 60 * 60;
91    const startDate = new Date(Date.now() - 300 * day);
92    const { xValues, openValues, highValues, lowValues, closeValues } = ExampleDataProvider.getRandomOHLCVData(
93        300,
94        1.5,
95        startDate,
96        day
97    );
98
99    // Create and add the Candlestick series
100    // The Candlestick Series requires a special dataseries type called OhlcDataSeries with o,h,l,c and date values
101    const candleDataSeries = new OhlcDataSeries(wasmContext, {
102        xValues,
103        openValues,
104        highValues,
105        lowValues,
106        closeValues,
107        dataSeriesName: "BTC/USDT",
108    });
109    const candlestickSeries = new FastCandlestickRenderableSeries(wasmContext, {
110        id: "Candles",
111        dataSeries: candleDataSeries,
112        stroke: appTheme.ForegroundColor, // used by cursorModifier below
113        strokeThickness: 1,
114        brushUp: appTheme.VividGreen + "77",
115        brushDown: appTheme.MutedRed + "77",
116        strokeUp: appTheme.VividGreen,
117        strokeDown: appTheme.MutedRed,
118    });
119    sciChartSurface.renderableSeries.add(candlestickSeries);
120
121    // Add some moving averages using SciChart's filters/transforms API
122    // when candleDataSeries updates, XyMovingAverageFilter automatically recomputes
123    sciChartSurface.renderableSeries.add(
124        new FastLineRenderableSeries(wasmContext, {
125            dataSeries: new XyMovingAverageFilter(candleDataSeries, {
126                dataSeriesName: "Moving Average (20)",
127                length: 20,
128            }),
129            stroke: appTheme.VividSkyBlue,
130        })
131    );
132
133    sciChartSurface.renderableSeries.add(
134        new FastLineRenderableSeries(wasmContext, {
135            dataSeries: new XyMovingAverageFilter(candleDataSeries, {
136                dataSeriesName: "Moving Average (50)",
137                length: 50,
138            }),
139            stroke: appTheme.VividPink,
140        })
141    );
142
143    // Optional: Add some interactivity modifiers
144    sciChartSurface.chartModifiers.add(
145        new ZoomExtentsModifier(),
146        new MouseWheelZoomModifier(),
147        new ZoomPanModifier({ id: "pan" }),
148        new CreateTradeMarkerModifier({ id: "marker" }),
149        new CreateLineAnnotationModifier({ id: "line" })
150    );
151    sciChartSurface.chartModifiers.getById("marker").isEnabled = false;
152    sciChartSurface.chartModifiers.getById("line").isEnabled = false;
153
154    const helpAnnotation = new NativeTextAnnotation({
155        x1: 20,
156        y1: 20,
157        xCoordinateMode: ECoordinateMode.Pixel,
158        yCoordinateMode: ECoordinateMode.Pixel,
159        verticalAnchorPoint: EVerticalAnchorPoint.Top,
160        multiLineAlignment: EMultiLineAlignment.Left,
161        textColor: appTheme.ForegroundColor,
162    });
163    // Add this to modifierAnnotations so it is not saved/loaded
164    sciChartSurface.modifierAnnotations.add(helpAnnotation);
165
166    const getDefinition = () => {
167        return {
168            visibleRange: xAxis.visibleRange,
169            annotations: sciChartSurface.annotations.asArray().map((annotation) => annotation.toJSON()),
170            data: candleDataSeries.toJSON(),
171        };
172    };
173    const applyDefinition = (definition: any) => {
174        if (definition) {
175            configure2DSurface({ annotations: definition.annotations }, sciChartSurface, wasmContext);
176            xAxis.visibleRange = definition.visibleRange;
177            const newData = definition.data.options as TOhlcSeriesData;
178            candleDataSeries.clear();
179            candleDataSeries.appendRange(
180                newData.xValues,
181                newData.openValues,
182                newData.highValues,
183                newData.lowValues,
184                newData.closeValues
185            );
186        }
187    };
188
189    const setChartMode = (mode: string) => {
190        if (mode === "pan") {
191            sciChartSurface.chartModifiers.getById("marker").isEnabled = false;
192            sciChartSurface.chartModifiers.getById("line").isEnabled = false;
193            sciChartSurface.chartModifiers.getById("pan").isEnabled = true;
194            helpAnnotation.text = `Click and drag to pan the chart`;
195        } else if (mode === "line") {
196            sciChartSurface.chartModifiers.getById("marker").isEnabled = false;
197            sciChartSurface.chartModifiers.getById("line").isEnabled = true;
198            sciChartSurface.chartModifiers.getById("pan").isEnabled = false;
199            helpAnnotation.text = `Click and drag to draw a line.
200Ctrl + click a line to delete it`;
201        } else if (mode === "marker") {
202            sciChartSurface.chartModifiers.getById("marker").isEnabled = true;
203            sciChartSurface.chartModifiers.getById("line").isEnabled = false;
204            sciChartSurface.chartModifiers.getById("pan").isEnabled = false;
205            helpAnnotation.text = `Left click to place a buy marker.
206Right click to place a sell marker
207Ctrl + Click to delete a marker`;
208        }
209    };
210
211    const resetChart = () => {
212        sciChartSurface.annotations.clear(true);
213        // Zoom to the latest 100 candles
214        xAxis.visibleRange = new NumberRange(xValues.length - 100, xValues.length - 1);
215    };
216
217    resetChart();
218    setChartMode("line");
219
220    return {
221        sciChartSurface,
222        controls: { getDefinition, applyDefinition, resetChart, setChartMode },
223    };
224};
225

See Also: Financial Charts (8 Demos)

Angular Candlestick Chart | Chart Examples | SciChart.js | SciChart.js Demo

Angular Candlestick Chart

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

Angular OHLC Chart | JavaScript Chart Examples | SciChart | SciChart.js Demo

Angular OHLC Chart

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

Angular Realtime Ticking Stock Chart | SciChart.js | SciChart.js Demo

Angular Realtime Ticking Stock Charts

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.

Angular Multi-Pane Stock Chart using Subcharts | View JavaScript Charts | SciChart.js Demo

Angular Multi-Pane Stock Charts using Subcharts

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

Tenor Curves Demo | SciChart.js Demo

Tenor Curves Demo

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.

Angular Multi-Pane Stock Chart | View JavaScript Charts | SciChart.js Demo

Angular Multi-Pane Stock Charts using Sync Multi-Chart

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

Angular Market Depth Chart | SciChart.js Demo

Angular Market Depth Chart

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

Angular Chart Hoverable Buy Sell Marker Annotations | SciChart.js Demo

Angular Chart Hoverable Buy Sell Marker Annotations

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

SciChart Ltd, 16 Beaufort Court, Admirals Way, Docklands, London, E14 9XL.