openalgo-charts 1.8.2 → 1.8.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +288 -286
- package/dist/draw/index.d.ts +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/indicators/index.d.ts +166 -6
- package/dist/openalgo-charts.indicators.mjs +1 -1
- package/dist/openalgo-charts.indicators.mjs.map +1 -1
- package/dist/openalgo-charts.mjs +1 -1
- package/dist/openalgo-charts.standalone.js +1 -1
- package/package.json +104 -103
package/README.md
CHANGED
|
@@ -1,286 +1,288 @@
|
|
|
1
|
-
<div align="center">
|
|
2
|
-
|
|
3
|
-
# OpenAlgo Charts
|
|
4
|
-
|
|
5
|
-
**A from-scratch, dependency-free HTML5-canvas charting engine for OpenAlgo.**
|
|
6
|
-
|
|
7
|
-
Professional interactive charts, indicators, drawing tools, order flow, market replay, linked chart grids, and on-chart trading. Six lazy-loaded tiers, zero runtime dependencies, ~
|
|
8
|
-
|
|
9
|
-
[](https://www.npmjs.com/package/openalgo-charts)
|
|
10
|
-
[](./LICENSE)
|
|
11
|
-
[](#principles)
|
|
14
|
-
|
|
15
|
-
[**Documentation**](https://marketcalls.github.io/openalgo-charts/) · [**Live examples**](https://marketcalls.github.io/openalgo-charts/examples) · [**Getting started**](./docs/getting-started.md) · [**Architecture**](./ARCHITECTURE.md)
|
|
16
|
-
|
|
17
|
-
<img src="docs/architecture-diagram.
|
|
18
|
-
|
|
19
|
-
</div>
|
|
20
|
-
|
|
21
|
-
---
|
|
22
|
-
|
|
23
|
-
## Live OpenAlgo trading terminal
|
|
24
|
-
|
|
25
|
-
Right-click the chart to place market / limit / stop orders, drag the order and TP/SL bracket lines to modify, and watch live P&L on the position line - all on real OpenAlgo history + WebSocket tick data, with an analyzer (sandbox) mode so nothing goes live until you arm it.
|
|
26
|
-
|
|
27
|
-
<p align="center">
|
|
28
|
-
<img src="docs/trading.png" alt="OpenAlgo Charts live trading terminal: RELIANCE 5m candles with order lines, a right-click order menu, a long position with live P&L, and volume" width="920" />
|
|
29
|
-
</p>
|
|
30
|
-
|
|
31
|
-
## Examples gallery
|
|
32
|
-
|
|
33
|
-
Every chart in the [live gallery](https://marketcalls.github.io/openalgo-charts/examples) is the real library running in your browser - switch tabs, hover the crosshair, drag the order lines, place a drawing. What you see is the code that ran.
|
|
34
|
-
|
|
35
|
-
<p align="center">
|
|
36
|
-
<img src="docs/demo1.png" alt="Chart-type switcher, custom themes, data tooltips, and event markers" width="49%" />
|
|
37
|
-
<img src="docs/demo2.png" alt="Range switcher, legend, series compare, and indicators and markers" width="49%" />
|
|
38
|
-
</p>
|
|
39
|
-
<p align="center">
|
|
40
|
-
<img src="docs/demo3.png" alt="More live OpenAlgo Charts examples" width="49%" />
|
|
41
|
-
<img src="docs/demo4.png" alt="More live OpenAlgo Charts examples" width="49%" />
|
|
42
|
-
</p>
|
|
43
|
-
|
|
44
|
-
## Install
|
|
45
|
-
|
|
46
|
-
```bash
|
|
47
|
-
npm install openalgo-charts
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
```ts
|
|
51
|
-
import { createChart, generateBars } from 'openalgo-charts';
|
|
52
|
-
|
|
53
|
-
const chart = createChart(document.getElementById('chart'));
|
|
54
|
-
chart.addSeries('candlestick').setData(generateBars(1700000000, 200, 3600));
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
## Tiers
|
|
58
|
-
|
|
59
|
-
Import only what you use. Each tier is a separate bundle that registers into the base engine's registries, so the cost of a feature you don't load is zero.
|
|
60
|
-
|
|
61
|
-
| Import | Contents | Brotli |
|
|
62
|
-
|---|---|---|
|
|
63
|
-
| `openalgo-charts` | Engine, 13 chart types, panes & scales, primitives, registries, chart state, chart linking, bar cache, interval registry, trading overlay, OpenAlgo feeds |
|
|
64
|
-
| `openalgo-charts/indicators` |
|
|
65
|
-
| `openalgo-charts/draw` | 43 drawing tools + a headless drawing controller and clipboard | 13.1 KB |
|
|
66
|
-
| `openalgo-charts/transform` | Heikin Ashi, Renko, Range bars, Line Break, Point & Figure, Kagi | 2.7 KB |
|
|
67
|
-
| `openalgo-charts/profile` | Volume Profile, Market Profile (TPO), Footprint, order flow | 10.7 KB |
|
|
68
|
-
| `openalgo-charts/trade` | Order / position / bracket tools + DOM ladder |
|
|
69
|
-
|
|
70
|
-
Everything together is **
|
|
71
|
-
|
|
72
|
-
## What's built
|
|
73
|
-
|
|
74
|
-
### Chart types & transforms
|
|
75
|
-
Candles, hollow and volume candles, OHLC bars, high-low, line, line+markers, step, area, HLC-area, baseline, columns, histogram, plus Heikin Ashi, Renko, Range bars, Line Break, **Point & Figure** (fixed / percent / ATR box sizing, high-low or close construction), and Kagi.
|
|
76
|
-
|
|
77
|
-
### Indicators
|
|
78
|
-
|
|
79
|
-
```ts
|
|
80
|
-
import 'openalgo-charts/indicators';
|
|
81
|
-
|
|
82
|
-
chart.addIndicator('bollinger'); // overlays the price pane
|
|
83
|
-
const macd = chart.addIndicator('macd', { fastPeriod: 8 }); // gets its own pane
|
|
84
|
-
macd.setSettings({ 'macd:width': 2, 'macd:lineStyle': 'dashed' });
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
group
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
`chart
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
|
210
|
-
|
|
211
|
-
|
|
|
212
|
-
|
|
|
213
|
-
|
|
|
214
|
-
|
|
|
215
|
-
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
```
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
npm
|
|
256
|
-
npm run
|
|
257
|
-
npm
|
|
258
|
-
npm run
|
|
259
|
-
npm run
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
- **
|
|
267
|
-
- **
|
|
268
|
-
- **
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
-
|
|
279
|
-
- **
|
|
280
|
-
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
3
|
+
# OpenAlgo Charts
|
|
4
|
+
|
|
5
|
+
**A from-scratch, dependency-free HTML5-canvas charting engine for OpenAlgo.**
|
|
6
|
+
|
|
7
|
+
Professional interactive charts, 102 built-in indicators plus your own custom ones, drawing tools, order flow, market replay, linked chart grids, and on-chart trading. Six lazy-loaded tiers, zero runtime dependencies, ~59 KB Brotli for the base engine.
|
|
8
|
+
|
|
9
|
+
[](https://www.npmjs.com/package/openalgo-charts)
|
|
10
|
+
[](./LICENSE)
|
|
11
|
+
[](#size-budget)
|
|
12
|
+
[](#develop)
|
|
13
|
+
[](#principles)
|
|
14
|
+
|
|
15
|
+
[**Documentation**](https://marketcalls.github.io/openalgo-charts/) · [**Live examples**](https://marketcalls.github.io/openalgo-charts/examples) · [**Getting started**](./docs/getting-started.md) · [**Architecture**](./ARCHITECTURE.md)
|
|
16
|
+
|
|
17
|
+
<img src="docs/architecture-diagram.svg" alt="OpenAlgo Charts architecture: seven layers from the public API down to feeds and data, with 102 built-in plus custom indicators, 43 drawing tools, and a six-tier bundle legend" width="920" />
|
|
18
|
+
|
|
19
|
+
</div>
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Live OpenAlgo trading terminal
|
|
24
|
+
|
|
25
|
+
Right-click the chart to place market / limit / stop orders, drag the order and TP/SL bracket lines to modify, and watch live P&L on the position line - all on real OpenAlgo history + WebSocket tick data, with an analyzer (sandbox) mode so nothing goes live until you arm it.
|
|
26
|
+
|
|
27
|
+
<p align="center">
|
|
28
|
+
<img src="docs/trading.png" alt="OpenAlgo Charts live trading terminal: RELIANCE 5m candles with order lines, a right-click order menu, a long position with live P&L, and volume" width="920" />
|
|
29
|
+
</p>
|
|
30
|
+
|
|
31
|
+
## Examples gallery
|
|
32
|
+
|
|
33
|
+
Every chart in the [live gallery](https://marketcalls.github.io/openalgo-charts/examples) is the real library running in your browser - switch tabs, hover the crosshair, drag the order lines, place a drawing. What you see is the code that ran.
|
|
34
|
+
|
|
35
|
+
<p align="center">
|
|
36
|
+
<img src="docs/demo1.png" alt="Chart-type switcher, custom themes, data tooltips, and event markers" width="49%" />
|
|
37
|
+
<img src="docs/demo2.png" alt="Range switcher, legend, series compare, and indicators and markers" width="49%" />
|
|
38
|
+
</p>
|
|
39
|
+
<p align="center">
|
|
40
|
+
<img src="docs/demo3.png" alt="More live OpenAlgo Charts examples" width="49%" />
|
|
41
|
+
<img src="docs/demo4.png" alt="More live OpenAlgo Charts examples" width="49%" />
|
|
42
|
+
</p>
|
|
43
|
+
|
|
44
|
+
## Install
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
npm install openalgo-charts
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
```ts
|
|
51
|
+
import { createChart, generateBars } from 'openalgo-charts';
|
|
52
|
+
|
|
53
|
+
const chart = createChart(document.getElementById('chart'));
|
|
54
|
+
chart.addSeries('candlestick').setData(generateBars(1700000000, 200, 3600));
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Tiers
|
|
58
|
+
|
|
59
|
+
Import only what you use. Each tier is a separate bundle that registers into the base engine's registries, so the cost of a feature you don't load is zero.
|
|
60
|
+
|
|
61
|
+
| Import | Contents | Brotli |
|
|
62
|
+
|---|---|---|
|
|
63
|
+
| `openalgo-charts` | Engine, 13 chart types, panes & scales, primitives, registries, chart state, chart linking, bar cache, interval registry, trading overlay, OpenAlgo feeds | 59.1 KB |
|
|
64
|
+
| `openalgo-charts/indicators` | 102 built-in indicators, the `registerIndicator` contract for your own, and the Tier-2 (external-data) contract | 27.2 KB |
|
|
65
|
+
| `openalgo-charts/draw` | 43 drawing tools + a headless drawing controller and clipboard | 13.1 KB |
|
|
66
|
+
| `openalgo-charts/transform` | Heikin Ashi, Renko, Range bars, Line Break, Point & Figure, Kagi | 2.7 KB |
|
|
67
|
+
| `openalgo-charts/profile` | Volume Profile, Market Profile (TPO), Footprint, order flow | 10.7 KB |
|
|
68
|
+
| `openalgo-charts/trade` | Order / position / bracket tools + DOM ladder | 7.6 KB |
|
|
69
|
+
|
|
70
|
+
Everything together is **120.3 KB Brotli**. Figures are the measured `size-limit` output. The trade tier is listed as its delta over the base, so loading base + trade costs 66.7 KB.
|
|
71
|
+
|
|
72
|
+
## What's built
|
|
73
|
+
|
|
74
|
+
### Chart types & transforms
|
|
75
|
+
Candles, hollow and volume candles, OHLC bars, high-low, line, line+markers, step, area, HLC-area, baseline, columns, histogram, plus Heikin Ashi, Renko, Range bars, Line Break, **Point & Figure** (fixed / percent / ATR box sizing, high-low or close construction), and Kagi.
|
|
76
|
+
|
|
77
|
+
### Indicators
|
|
78
|
+
|
|
79
|
+
```ts
|
|
80
|
+
import 'openalgo-charts/indicators';
|
|
81
|
+
|
|
82
|
+
chart.addIndicator('bollinger'); // overlays the price pane
|
|
83
|
+
const macd = chart.addIndicator('macd', { fastPeriod: 8 }); // gets its own pane
|
|
84
|
+
macd.setSettings({ 'macd:width': 2, 'macd:lineStyle': 'dashed' });
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
102 built-ins across Trend, Momentum, Volatility and Volume, from the everyday (SMA, EMA, WMA, VWAP, Bollinger Bands, RSI, MACD, Stochastic, ADX/DMI, ATR) through Supertrend, HalfTrend, Ichimoku, Keltner, Donchian, Chandelier Exit and CPR with floor pivots to Connors RSI, Fisher Transform, Woodies CCI, Klinger, Vortex, WaveTrend Pro, Chop Zone and Williams Fractals, with a least-squares family (Least Squares Moving Average, Linear Regression Slope, Standard Error, Standard Error Bands) and a Smoothed Moving Average alongside them, joined in 1.8.3 by the T3 average, the Hull Suite (Hma / Ehma / Thma with a displaced band) and Consolidation and Breakout, which tracks inside-bar ranges and marks the bar that leaves one. Twenty-eight of them draw shaded bands, six emit named buy/sell markers, two recolour the price candles, and Seasonality draws a monthly return heatmap as a table over the chart. The full catalogue with ids and defaults is in the docs.
|
|
88
|
+
|
|
89
|
+
Every built-in is measured against its standard definition bar by bar, at several parameter sets, and each one's warmup (the first bar it can honestly produce a value for) is part of that check rather than an afterthought. A study draws nothing until it has the history it needs.
|
|
90
|
+
|
|
91
|
+
The chart owns the whole lifecycle: series, pane placement, reference levels, fixed ranges (RSI 0..100), recompute on data change, teardown. Every plot gets colour, opacity, thickness, and line style for free, generated from the descriptor. Write your own with `registerIndicator`, or use the **Tier-2 contract** for indicators whose data isn't derived from OHLCV (open interest, CVD, any external feed).
|
|
92
|
+
|
|
93
|
+
### Drawing tools
|
|
94
|
+
|
|
95
|
+
```ts
|
|
96
|
+
import { DrawingController } from 'openalgo-charts/draw';
|
|
97
|
+
|
|
98
|
+
const draw = new DrawingController(chart, { magnet: true });
|
|
99
|
+
draw.setTool('trend-line'); // the next two clicks place it
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
43 tools. Lines: trend line, ray, extended line, arrow, horizontal line/ray, vertical line, cross line. Shapes: rectangle, rotated rectangle, ellipse, circle, triangle. Paths: path, polyline, arc, curve, double curve. Channels: parallel channel, fib channel. Fibonacci: retracement, extension, time zone, speed fan. Gann: fan, box. Cycles: cyclic lines, time cycles, sine line. Forecasting: long/short position (1:1 from one click, with risk/reward and risk-based sizing), forecast. Measurers: price range, date range, measure. Arrows: mark up, mark down. Text and notes: text, price label, callout, flag mark. Brushes: brush, highlighter (freehand).
|
|
103
|
+
|
|
104
|
+
Headless by design: no toolbar, no dialogs. Placement with live preview, selection, whole-shape and per-anchor dragging, magnet snap to O/H/L/C, undo/redo (a drag is one step), and persistence. Anchors are `{ time, price }`, never pixels, so they survive zoom and resolve inside collapsed session gaps and past the last bar.
|
|
105
|
+
|
|
106
|
+
`draw.copy()`, `draw.cut()` and `draw.paste()` move drawings through the OS clipboard, including between two charts on the page. The payload is JSON under one namespaced key, so foreign text pastes nothing instead of throwing at your Ctrl+V handler, and every field is validated before it reaches the model. A refused clipboard permission does not lose the copy: every write also lands in a shared in-memory clipboard, and a cut deletes only after the write succeeds. A paste is one undo step of fresh objects, nudged two bars and 16 px so it is visibly a second shape. The key bindings stay yours; the engine installs no listeners.
|
|
107
|
+
|
|
108
|
+
### Panes, scales & legends
|
|
109
|
+
Draggable pane dividers, move / maximize / remove, and pane legends showing one reading per plot in that plot's own colour, with inline show-hide / settings / move / delete controls revealed on hover. The status line is switchable field by field (logo, title, market status, OHLC, bar change, volume, last day change, last value) over a host-supplied data source.
|
|
110
|
+
|
|
111
|
+
Each pane carries a right, a left and a hidden overlay price scale, in four modes: linear, logarithmic, and the two rebasing modes **percentage** (`+3.42%`) and **indexed-to-100** (`103.42`), which quote every price against a baseline taken from the first visible bar, so panning re-bases the axis.
|
|
112
|
+
|
|
113
|
+
### Reference levels and axis chrome
|
|
114
|
+
|
|
115
|
+
```ts
|
|
116
|
+
import { PriceLevels } from 'openalgo-charts';
|
|
117
|
+
|
|
118
|
+
const levels = new PriceLevels({
|
|
119
|
+
levels: { previousClose: { line: true, label: true }, sessionHigh: { line: true, label: false } },
|
|
120
|
+
});
|
|
121
|
+
chart.addPrimitive(levels, 0);
|
|
122
|
+
levels.available('bid'); // false until a quote is fed: render that control disabled, not hidden
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
One primitive over ten levels: previous close, session high and low, last price, the four extended-hours opens and closes, and bid and ask. Each level's line across the plot and its tag on the price axis are two flags in the same options group, so they cannot drift apart. The session comes from the gaps in the bars rather than from a calendar midnight, and the session in view follows the viewport's right edge, so scrolling back through history moves the previous close back with it. A level with no data is `null`, never `0`: nothing draws at zero, and `available(kind)` is the signal to render that control disabled with its state visible instead of hiding it.
|
|
126
|
+
|
|
127
|
+
Axis chrome is off until a chart asks for it. `createChart(el, { axisChrome: { sessionClock: true, barCountdown: true } })` puts a live clock in the corner where the two axis strips meet, in the chart's own timezone with the zone's UTC offset under it, and a countdown to the current bar's close as a second row inside the last-price tag, with the interval read back off the bars so a timeframe switch is followed. Tick labels that the last-price tag would cover are dropped rather than drawn through it, on a priority order that puts the crosshair above the last price, above a price line, above a session level.
|
|
128
|
+
|
|
129
|
+
### Timezones
|
|
130
|
+
|
|
131
|
+
```ts
|
|
132
|
+
const chart = createChart(el, { timezone: 'America/New_York' });
|
|
133
|
+
chart.setTimezone('Europe/London'); // relabels and recomputes on the next frame
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
An IANA name, never a fixed offset, so daylight saving is followed rather than approximated. The zone drives the time axis (including which ticks escalate to a day, month or year label), the crosshair time tag, and every calendar-anchored study (VWAP and TWAP anchors, CPR's weekly and monthly frames, the month a Seasonality bar counts in), and it rides along in `getState()`. Profile session windows carry their own zone, so `TRADING_HOURS['us-regular']` reads as 09:30-16:00 `America/New_York` whatever the chart is displayed in. The default is `Asia/Kolkata` on the same fixed-offset arithmetic it always used, so a chart that names no zone labels and computes exactly as before.
|
|
137
|
+
|
|
138
|
+
### Market replay
|
|
139
|
+
|
|
140
|
+
```ts
|
|
141
|
+
import { ReplayController } from 'openalgo-charts';
|
|
142
|
+
|
|
143
|
+
const replay = new ReplayController(chart, { bars, startIndex: 200, barMs: 500 });
|
|
144
|
+
replay.play({ speed: 2 }); // emits replay:frame per bar
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
Headless: the controller owns the playhead and ships no DOM, so the transport bar is yours to draw from `state()` and the `replay:*` events. Each step hands the series a prefix of the session through the ordinary `setData` path, which is what makes every indicator, level, fill, marker and legend row reconstruct itself as it stood at that bar. `stop()` puts the full history and the exact viewport back.
|
|
148
|
+
|
|
149
|
+
### Symbol comparison
|
|
150
|
+
|
|
151
|
+
```ts
|
|
152
|
+
import { addComparison } from 'openalgo-charts';
|
|
153
|
+
|
|
154
|
+
const bn = addComparison(chart, { symbol: 'BANKNIFTY', bars });
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
The comparison rides the pane's hidden overlay scale in its own real prices, the pane rebases to percentage (or indexed-to-100), and the overlay's range is mirrored from the primary's, so equal percentage moves land on equal pixels instead of each line filling the pane. Alignment is by timestamp: a comparison print with no primary bar is dropped, a primary bar with no print becomes a gap.
|
|
158
|
+
|
|
159
|
+
### Linked chart grids
|
|
160
|
+
|
|
161
|
+
```ts
|
|
162
|
+
import { createLinkGroup } from 'openalgo-charts';
|
|
163
|
+
|
|
164
|
+
const group = createLinkGroup({ crosshair: true, viewport: true, symbol: false });
|
|
165
|
+
group.add(daily);
|
|
166
|
+
group.add(hourly, { symbol: 'RELIANCE', onSymbol: (s, c) => loadBars(s, c) });
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
Hover one chart and the same **instant** is marked on the others; pan or zoom one and the others move to the same wall-clock window. Each channel switches on its own, because mirroring the cursor across four timeframes while keeping each zoom is a different thing from slaving every chart's instrument.
|
|
170
|
+
|
|
171
|
+
Nothing crosses a chart boundary as a logical index. The x axis is a gapless index over each chart's own bars, so index 300 is a different instant on every chart: every value is converted index to time on the sender and time back to index on the receiver, against that chart's own data. A daily chart and an hourly chart with different history depth therefore stay on the same instant, which the naive index copy gets right only when both charts hold the same bars. An instant outside a follower's first or last bar is an absence, not a gap, so it draws nothing; inside its range with no bar there it snaps to the nearest bar in time, or draws nothing under `whenMissing: 'hide'`. The linked crosshair is a vertical line only, at reduced opacity: a mirrored horizontal line would assert a price that belongs to another instrument.
|
|
172
|
+
|
|
173
|
+
Headless like the rest, and the engine has no instrument concept, so symbol sync is a partnership: the host emits `'symbol'` on the chart's bus (or calls `group.setSymbol`) and supplies the per-member `onSymbol` that loads the bars. A member with no `onSymbol` broadcasts but never follows, which is how you pin one chart of a grid.
|
|
174
|
+
|
|
175
|
+
### Settings & context menu
|
|
176
|
+
`chartSettingsSchema(chart)` describes a full settings dialog as tabs of controls, in the same descriptor vocabulary the indicator settings form already uses; `readChartSettings` and `applyChartSettings` are its round trip over flat, JSON-safe keys. Five tabs (Price, Readout, Axes, Appearance, Trading), and a bullish/bearish pair is **one** `colorPair` row carrying its switch and both swatches instead of two stacked rows. Grid, crosshair, scale text, plot margins, status-line fields, the chart timezone, trading colours and the primary series' own style are all real options behind it, so no control in the schema is inert.
|
|
177
|
+
|
|
178
|
+
`chart.on('contextmenu', ...)` reports the pane, price, time, logical index and what sits under the pointer: a drawing, an indicator instance, a legend, a primitive, a series, a price scale (with the side and the scale id it names), the time scale, or empty plot. For a menu raised on a price axis, `chart.priceAxisState(pane, scaleId)` reads back every item that menu draws (auto-fit, invert, scale mode, price-per-bar lock, whether the axis is movable) and `setPriceAxisOptions`, `setPriceAxisAutoFit`, `setPriceAxisLockRatio` and `movePriceAxis` act on it, so no row is ticked with nothing behind it.
|
|
179
|
+
|
|
180
|
+
### Trading
|
|
181
|
+
Order, position, and bracket lines with live P&L, one-click and drag-to-modify, OCO, validation, an order state machine, analyzer (sandbox) mode, and a depth-of-market ladder (5 to 200 levels).
|
|
182
|
+
|
|
183
|
+
### Profiles & order flow
|
|
184
|
+
Volume Profile, Market Profile (TPO), Footprint, and cumulative delta.
|
|
185
|
+
|
|
186
|
+
### Warm-load cache & interval registry
|
|
187
|
+
|
|
188
|
+
```ts
|
|
189
|
+
import { withBarCache, registerInterval } from 'openalgo-charts';
|
|
190
|
+
|
|
191
|
+
const feed = withBarCache(new OpenAlgoDataFeed(cfg), { ttlMs: 60_000 });
|
|
192
|
+
registerInterval({ code: '1MO', bucketing: { mode: 'calendar', unit: 'month' } });
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
`withBarCache` wraps **any** `DataFeed`, so a custom feed warms up too. One entry per `symbol|exchange|interval` holds the widest range fetched so far and a narrower request is sliced out of it, because keying on the range would miss on every pan. **The forming bar is never stored**: a frozen snapshot of a live candle reaching the last-price line, the header LTP and every indicator computed off that close is worse than no cache at all, so coverage ends at the last closed bar and a hit is short by the one bar a live subscription re-supplies. Freshness is two gates, a TTL and "nothing new can have closed", the second measured on the feed's own bar grid rather than UTC midnight. Bounded LRU on entries and on total bars, in-memory by default with an injectable store if you want localStorage or IndexedDB, and `noCache`, `invalidate()`, `clear()` and `stats()` for the rest.
|
|
196
|
+
|
|
197
|
+
An interval code resolves through a registry whose entry is a **bucketing rule, not a duration**: fixed seconds, a calendar month/quarter/year that opens at local midnight in a named zone, N ticks, or N traded quantity. That is the vocabulary the tick aggregator already used, widened by one case. An unrecognised code now throws `UnknownIntervalError` instead of quietly meaning 60 seconds, so a subscription fails at subscribe time rather than drawing minute bars under someone else's label; `tryResolveInterval` and `isKnownInterval` are the non-throwing probes for validating a picker.
|
|
198
|
+
|
|
199
|
+
### State
|
|
200
|
+
`chart.getState()` / `chart.restoreState()` capture the viewport, grid, panes, price scales, indicator instances, drawings, and the whole settings block (canvas, status line, trading colours, event filters) as one JSON payload: saved layouts and templates with no extra storage plumbing.
|
|
201
|
+
|
|
202
|
+
### Data
|
|
203
|
+
OpenAlgo REST history + WebSocket ticks with auto-reconnect and resubscribe, live candle aggregation, tick/volume bars, a unified `chart.on(...)` event bus, markers and signals, earnings/dividend/expiry event markers, an IANA chart timezone, and custom price/time formatters.
|
|
204
|
+
|
|
205
|
+
## Size budget
|
|
206
|
+
|
|
207
|
+
Enforced in CI by [`size-limit`](./.size-limit.json). Nothing is excluded, because there are no runtime dependencies to exclude.
|
|
208
|
+
|
|
209
|
+
| Bundle | Limit | Actual |
|
|
210
|
+
|---|---|---|
|
|
211
|
+
| Base engine | 60 KB | 59.06 KB |
|
|
212
|
+
| Base + trade | 68 KB | 66.67 KB |
|
|
213
|
+
| Indicators tier | 30 KB | 27.21 KB |
|
|
214
|
+
| Draw tier | 14 KB | 13.13 KB |
|
|
215
|
+
| Transform tier | 5 KB | 2.66 KB |
|
|
216
|
+
| Profile tier | 11 KB | 10.66 KB |
|
|
217
|
+
| **Everything** | **124 KB** | **120.32 KB** |
|
|
218
|
+
|
|
219
|
+
## Documentation
|
|
220
|
+
|
|
221
|
+
Full docs, the interactive example gallery, and the generated API reference live at:
|
|
222
|
+
|
|
223
|
+
**https://marketcalls.github.io/openalgo-charts/**
|
|
224
|
+
|
|
225
|
+
The site is built with Nextra (in [`website/`](./website)) and statically exported to GitHub Pages on every push. Every code sample on a docs page is a *live* chart running the real library, so what you read is what runs. To run the site locally:
|
|
226
|
+
|
|
227
|
+
```bash
|
|
228
|
+
npm run build # build the library (dist/) the live demos import
|
|
229
|
+
cd website && npm install && npm run dev # http://localhost:3000/openalgo-charts
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
## Agent skills
|
|
233
|
+
|
|
234
|
+
Teach your AI coding assistant this library:
|
|
235
|
+
|
|
236
|
+
```bash
|
|
237
|
+
npx skills add https://github.com/marketcalls/openalgo-charts
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
Installs six skills from [`.github/skills/`](./.github/skills) - a reference hub with 21 deep-dive files covering the whole API surface and its foot-guns, plus task skills for scaffolding a chart, adding indicators, building a terminal, writing a plugin, and debugging. Works with Claude Code, Cursor, Codex, Copilot, Gemini CLI and the rest of the `skills` CLI's supported agents.
|
|
241
|
+
|
|
242
|
+
## Examples
|
|
243
|
+
|
|
244
|
+
Runnable demos in [`examples/`](./examples), including a full **yfinance terminal** ([`examples/yfinance`](./examples/yfinance)) with a full terminal shell: symbol search, interval pills, chart-type picker, indicator menu, a vertical drawing rail, a floating properties bar, generated indicator settings, and layout persistence.
|
|
245
|
+
|
|
246
|
+
```bash
|
|
247
|
+
npm run build
|
|
248
|
+
cd examples/yfinance && pip install -r requirements.txt && python server.py
|
|
249
|
+
# → http://127.0.0.1:8000/examples/yfinance/index.html
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
## Develop
|
|
253
|
+
|
|
254
|
+
```bash
|
|
255
|
+
npm install # install dev toolchain
|
|
256
|
+
npm run typecheck # strict TypeScript check
|
|
257
|
+
npm test # unit tests (vitest) - 2408 across 129 files
|
|
258
|
+
npm run build # Rollup -> dist/ (minified ESM per tier + types)
|
|
259
|
+
npm run size # size-limit (Brotli) against the budget
|
|
260
|
+
npm run e2e # Playwright Chromium smoke tests
|
|
261
|
+
npm run verify # typecheck + test + build + size
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
## Principles
|
|
265
|
+
|
|
266
|
+
- **Single canvas pipeline** (no SVG, no DOM-per-bar): small and fast.
|
|
267
|
+
- **Gapless time axis by default**: weekends, holidays, and session breaks collapse.
|
|
268
|
+
- **Registries, not switches**: chart types, indicators, and drawing tools are all descriptors. Adding one is a registration, never a core change.
|
|
269
|
+
- **Zero runtime dependencies**: nothing is excluded from the size budget.
|
|
270
|
+
- **Apache-2.0**, original code.
|
|
271
|
+
|
|
272
|
+
## Status & limitations
|
|
273
|
+
|
|
274
|
+
Version **1.8.3**. All engine build phases are implemented with 2408 unit tests across 129 files.
|
|
275
|
+
|
|
276
|
+
Known gaps, stated plainly:
|
|
277
|
+
|
|
278
|
+
- **Footprint and order flow need trade-by-trade data classified bid/ask.** OpenAlgo does not store this by default, so it is live-session-only unless you add a tick recorder: `FootprintAggregator` is the live path. See [`ARCHITECTURE.md`](./ARCHITECTURE.md) §6A.
|
|
279
|
+
- **Only `Footprint` is theme-aware among the profile primitives.** `VolumeProfile`, `MarketProfile` and `HorizontalProfile` never read `rc.theme`; their defaults are dark-tuned, so a light theme needs explicit colours. `HorizontalProfile` also hardcodes its POC / value-area line colours and has no `setOptions`.
|
|
280
|
+
- The OpenAlgo **WS/trade adapter wire schemas** ship with injectable transports and offline tests, but the exact field names should be verified against your running OpenAlgo build.
|
|
281
|
+
- **A pane has exactly one hidden overlay scale**, so every symbol comparison on a pane shares one baseline. That is right for a single comparison, the common case, but a second one on the same pane is quoted against the first instrument's price; put further instruments on their own pane with `paneIndex` until the overlay scales are keyed.
|
|
282
|
+
- An optional **DOM chrome package** (toolbar, dialogs, command palette, objects panel) is the next planned piece; today that UI lives in the examples.
|
|
283
|
+
|
|
284
|
+
See [`ARCHITECTURE.md`](./ARCHITECTURE.md) §13a for the full deferred list.
|
|
285
|
+
|
|
286
|
+
## License
|
|
287
|
+
|
|
288
|
+
[Apache-2.0](./LICENSE). See [`NOTICE`](./NOTICE).
|