openalgo-charts 1.9.2 → 2.0.0
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 +97 -24
- package/dist/draw/index.d.ts +1154 -125
- package/dist/index.d.ts +834 -7
- package/dist/openalgo-charts.draw.mjs +1 -1
- package/dist/openalgo-charts.draw.mjs.map +1 -1
- package/dist/openalgo-charts.mjs +1 -1
- package/dist/openalgo-charts.mjs.map +1 -1
- package/dist/openalgo-charts.standalone.js +1 -1
- package/dist/openalgo-charts.standalone.js.map +1 -1
- package/dist/openalgo-charts.webgl.mjs +2 -0
- package/dist/openalgo-charts.webgl.mjs.map +1 -0
- package/dist/openalgo-charts.widget.mjs +2 -0
- package/dist/openalgo-charts.widget.mjs.map +1 -0
- package/dist/webgl/index.d.ts +503 -0
- package/dist/widget/index.d.ts +1214 -0
- package/package.json +26 -5
package/README.md
CHANGED
|
@@ -4,17 +4,17 @@
|
|
|
4
4
|
|
|
5
5
|
**A from-scratch, dependency-free HTML5-canvas charting engine for OpenAlgo.**
|
|
6
6
|
|
|
7
|
-
Professional interactive charts, 102 built-in indicators plus your own custom ones, drawing tools, order flow, market replay, linked chart grids,
|
|
7
|
+
Professional interactive charts, 102 built-in indicators plus your own custom ones, 51 drawing tools, order flow, market replay, linked chart grids, on-chart trading, vector SVG export and an optional WebGL2 backend. Eight lazy-loaded tiers, zero runtime dependencies, 66.39 KB Brotli for the base engine, and a one-call widget tier that adds the toolbar, drawing rail, dialogs and shortcuts.
|
|
8
8
|
|
|
9
9
|
[](https://www.npmjs.com/package/openalgo-charts)
|
|
10
10
|
[](./LICENSE)
|
|
11
|
-
[](#size-budget)
|
|
12
|
+
[](#develop)
|
|
13
13
|
[](#principles)
|
|
14
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)
|
|
15
|
+
[**Documentation**](https://marketcalls.github.io/openalgo-charts/) · [**Live examples**](https://marketcalls.github.io/openalgo-charts/examples) · [**Getting started**](./docs/getting-started.md) · [**Migrating to 2.0**](./docs/migrating-to-2.md) · [**Architecture**](./ARCHITECTURE.md)
|
|
16
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, 51 drawing tools, and
|
|
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, 51 drawing tools, and an eight-tier bundle legend" width="920" />
|
|
18
18
|
|
|
19
19
|
</div>
|
|
20
20
|
|
|
@@ -62,7 +62,7 @@ in front of npm rather than being places you upload to. A chart is one HTML file
|
|
|
62
62
|
```html
|
|
63
63
|
<div id="chart" style="width:100vw;height:100vh"></div>
|
|
64
64
|
<script type="module">
|
|
65
|
-
import { createChart } from 'https://unpkg.com/openalgo-charts@
|
|
65
|
+
import { createChart } from 'https://unpkg.com/openalgo-charts@2.0.0/dist/openalgo-charts.mjs';
|
|
66
66
|
const chart = createChart(document.getElementById('chart'), { timezone: 'Asia/Kolkata' });
|
|
67
67
|
chart.addSeries('candlestick').setData(bars);
|
|
68
68
|
</script>
|
|
@@ -70,23 +70,47 @@ in front of npm rather than being places you upload to. A chart is one HTML file
|
|
|
70
70
|
|
|
71
71
|
Each tier is its own file, so `openalgo-charts.indicators.mjs` next to it registers
|
|
72
72
|
all 102 built-ins. Pin the version in anything you leave running. There is no
|
|
73
|
-
stylesheet to load: the engine ships no DOM
|
|
73
|
+
stylesheet to load: the engine ships no DOM, and the one tier that does
|
|
74
|
+
(`openalgo-charts/widget`) injects its own. See
|
|
74
75
|
[Use from a CDN](https://marketcalls.github.io/openalgo-charts/docs/cdn).
|
|
75
76
|
|
|
77
|
+
## The whole terminal in one call
|
|
78
|
+
|
|
79
|
+
```ts
|
|
80
|
+
import { createWidget } from 'openalgo-charts/widget';
|
|
81
|
+
import 'openalgo-charts/indicators';
|
|
82
|
+
import { OpenAlgoDataFeed } from 'openalgo-charts';
|
|
83
|
+
|
|
84
|
+
const widget = createWidget('#terminal', {
|
|
85
|
+
feed: new OpenAlgoDataFeed({ baseUrl: 'http://127.0.0.1:5000', apiKey: 'YOUR_KEY' }),
|
|
86
|
+
symbol: 'RELIANCE', exchange: 'NSE', interval: '5m',
|
|
87
|
+
theme: 'dark',
|
|
88
|
+
persist: true,
|
|
89
|
+
onOrder: (order) => broker.place(order), // the right-click menu offers order entry only when this is set
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
widget.chart; // the Chart underneath, every base API available
|
|
93
|
+
widget.draw; // the DrawingController the rail drives
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
`openalgo-charts/widget` is the eighth tier and the only one that builds DOM: a top bar (symbol search, interval pills, chart type, Indicators, capture, settings, theme), the drawing rail with pins and flyouts, a status line, toasts, a right-click menu, a keymap with a `?` panel, and optional layout persistence. Every dialog is generated from a schema the engine already ships (`chartSettingsSchema`, the indicator descriptor, `drawingSettingsSchema`), so no control exists without something behind it, and the chrome takes its colours from the active `ChartTheme` through `--oac-` tokens, so `setTheme` recolours canvas and chrome together. It drives the engine only through the public API, and the build proves it: the ESLint tier ACL and `npm run shake` keep it out of every other bundle, and importing the module touches no DOM, so it can sit in code that also runs on a server. The guide is [`docs/widget.md`](./docs/widget.md).
|
|
97
|
+
|
|
76
98
|
## Tiers
|
|
77
99
|
|
|
78
100
|
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.
|
|
79
101
|
|
|
80
102
|
| Import | Contents | Brotli |
|
|
81
103
|
|---|---|---|
|
|
82
|
-
| `openalgo-charts` | Engine, 13 chart types, panes & scales, primitives, registries, chart state, chart linking, bar cache, interval registry, trading overlay, OpenAlgo feeds |
|
|
83
|
-
| `openalgo-charts/indicators` | 102 built-in indicators, the `registerIndicator` contract for your own, and the Tier-2 (external-data) contract | 27.
|
|
84
|
-
| `openalgo-charts/draw` |
|
|
85
|
-
| `openalgo-charts/transform` | Heikin Ashi, Renko, Range bars, Line Break, Point & Figure, Kagi | 2.
|
|
86
|
-
| `openalgo-charts/profile` | Volume Profile, Market Profile (TPO), Footprint, order flow | 10.
|
|
87
|
-
| `openalgo-charts/trade` | Order / position / bracket tools + DOM ladder | 7.
|
|
104
|
+
| `openalgo-charts` | Engine, 13 chart types, panes & scales, primitives, registries, chart state, chart linking, bar cache, interval registry, trading overlay, SVG export, render backend port, OpenAlgo feeds | 66.39 KB |
|
|
105
|
+
| `openalgo-charts/indicators` | 102 built-in indicators, the `registerIndicator` contract for your own, and the Tier-2 (external-data) contract | 27.27 KB |
|
|
106
|
+
| `openalgo-charts/draw` | 51 drawing tools + a headless drawing controller, clipboard, settings schema, level palette, freehand geometry and SVG icons | 25.82 KB |
|
|
107
|
+
| `openalgo-charts/transform` | Heikin Ashi, Renko, Range bars, Line Break, Point & Figure, Kagi | 2.66 KB |
|
|
108
|
+
| `openalgo-charts/profile` | Volume Profile, Market Profile (TPO), Footprint, order flow | 10.66 KB |
|
|
109
|
+
| `openalgo-charts/trade` | Order / position / bracket tools + DOM ladder | 7.61 KB |
|
|
110
|
+
| `openalgo-charts/webgl` | WebGL2 series backend: batched, analytically anti-aliased GPU rendering of the standard chart types behind `renderer: 'auto'`, with a session-long fallback to the 2D path | 6.38 KB |
|
|
111
|
+
| `openalgo-charts/widget` | The chart with its chrome in one call: `createWidget` adds a top bar, the drawing rail, a status line, the settings and indicator dialogs, drawing properties, a right-click menu, a keymap with a `?` panel and optional layout persistence. The only tier that ships DOM | 35.56 KB |
|
|
88
112
|
|
|
89
|
-
Everything together is **
|
|
113
|
+
Everything together is **182.34 KB Brotli**; a widget terminal (base + draw + indicators + widget, what one `createWidget` call loads) is 155.03 KB. Figures are the measured `size-limit` output. The trade tier is listed as its delta over the base, so loading base + trade costs 74.00 KB.
|
|
90
114
|
|
|
91
115
|
## What's built
|
|
92
116
|
|
|
@@ -124,6 +148,28 @@ Headless by design: no toolbar, no dialogs. Placement with live preview, selecti
|
|
|
124
148
|
|
|
125
149
|
`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.
|
|
126
150
|
|
|
151
|
+
### Drawing model and feel
|
|
152
|
+
|
|
153
|
+
```ts
|
|
154
|
+
const draw = new DrawingController(chart, { magnet: 'weak' }); // 'off' | 'weak' | 'strong'
|
|
155
|
+
|
|
156
|
+
draw.select([a, b], false); // a selection, not a single id
|
|
157
|
+
draw.nudge(draw.selection(), 0, -1); // one undo entry for the whole group
|
|
158
|
+
draw.sendBehindSeries(a); // zIndex below zero paints under the candles
|
|
159
|
+
|
|
160
|
+
draw.add({ tool: 'text', points: [p], paneIndex: 0,
|
|
161
|
+
text: { value: 'Breakout', bold: true, align: 'center' } }); // text is its own block
|
|
162
|
+
draw.add({ tool: 'fib-retracement', points: [lo, hi], paneIndex: 0,
|
|
163
|
+
style: { levels: [{ ratio: 0.5 }, { ratio: 0.618, color: '#f5a623' }, { ratio: 1, enabled: false }] } });
|
|
164
|
+
|
|
165
|
+
const doc = draw.toJSON(); // { version: 2, drawings }; fromJSON also takes a 1.9.x array
|
|
166
|
+
const fields = drawingSettingsSchema('trend-line'); // what a properties panel may show, and nothing else
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
A drawing carries a paint order (`zIndex`: below zero paints under the series, at or above zero over it, with `bringToFront`, `sendToBack`, `sendBehindSeries` and `bringAboveSeries`), a text block (`drawing.text`, so a label colour is never confused with a stroke colour) and per-level fib rungs (`FibLevel`: ratio, colour, label, enabled), and the controller holds a selection rather than a single id: shift, ctrl or meta click adds, a body drag moves the whole group as one undo step, and `updateMany`, `removeMany`, `duplicate` and `nudge` act on the list. `drawingSettingsSchema(toolId)` describes a properties panel per tool, declaring only fields that tool's renderer reads, and `readDrawingSettings` / `applyDrawingSettings` are its round trip. `toJSON()` returns a versioned document; `fromJSON` and `migrateDrawings` upgrade any 1.9.x payload, so a layout saved by an older host opens with its text and levels intact. See [Migrating to 2.0](./docs/migrating-to-2.md).
|
|
170
|
+
|
|
171
|
+
Under the hand: the drawing under the pointer shows its handles faintly before it is grabbed (`hovered()`, `drawing:hover`), at the cost of the overlay tier only; Shift locks a line to 45 degree steps while placing or dragging a handle; the magnet paints a ring on the bar centre where the next click will land, and `'weak'` pulls only when an O/H/L/C is within a few pixels; grab targets grow for a touch pointer; Escape, Enter and Backspace cancel, finish or pop an anchor while placing, through `keyToDrawingAction`, which also maps undo, redo, copy, cut, paste, duplicate, delete and arrow nudge as a pure function you wire yourself. Line tools take a `showStats` readout of change, percent, bars and angle. The brush and highlighter ink every coalesced pointer sample, thin on release and paint as a spline, with pen pressure driving the width when `style.pressure` is on. Every tool icon and a chrome set ship as path data with builders for an inline `<svg>`, a sprite with `<use>` and a CSS cursor (`iconSvg`, `iconSprite`, `iconUse`, `toolCursor`), so a rail, a flyout and the armed cursor derive from one registry.
|
|
172
|
+
|
|
127
173
|
### Panes, scales & legends
|
|
128
174
|
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.
|
|
129
175
|
|
|
@@ -218,6 +264,27 @@ An interval code resolves through a registry whose entry is a **bucketing rule,
|
|
|
218
264
|
### State
|
|
219
265
|
`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.
|
|
220
266
|
|
|
267
|
+
### Vector export
|
|
268
|
+
|
|
269
|
+
```ts
|
|
270
|
+
const svg = chart.exportSVG(); // a standalone SVG string at the live size
|
|
271
|
+
const print = chart.exportSVG({ width: 1600, height: 900, background: false }); // transparent, for an embedded figure
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
The ordinary paint of every pane, run once into a serialising 2D context at pixel ratio 1, so axis labels and tags stay text, lines stay lines, and there is no second renderer to drift from the canvas one. Nothing transient is in it: no crosshair, hover or drag. A different size lays the chart out for the export and puts the live layout back without a blank frame. `SvgContext` is exported for a host that wants to run its own primitive into one. `takeScreenshot()` still returns a canvas when a picture is what you want.
|
|
275
|
+
|
|
276
|
+
### Render backends
|
|
277
|
+
|
|
278
|
+
```ts
|
|
279
|
+
import 'openalgo-charts/webgl';
|
|
280
|
+
|
|
281
|
+
const chart = createChart(el, { renderer: 'auto' }); // 'canvas2d' (default) | 'webgl2' | 'auto'
|
|
282
|
+
chart.rendererKind; // what it actually paints with
|
|
283
|
+
chart.on('renderer:fallback', ({ from, to, reason }) => log(reason));
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
The series pass on each pane goes through a render backend port; the shipped Canvas2D backend is pixel-identical to 1.9.2, and the `openalgo-charts/webgl` tier registers a WebGL2 backend that batches every standard chart type into one shared offscreen surface per page with analytic anti-aliasing and composites it into the pane's own canvas, so screenshots, the SVG export and the DOM are unchanged and a dashboard of panes never opens more than one GL context. `'webgl2'` throws until the tier is imported and falls back to the 2D path with one warning on a device without WebGL2; `'auto'` is the silent form. A lost context moves the chart to `canvas2d` for the session and emits `renderer:fallback`. Text, dashed lines, gradients, drawings and custom types stay on the 2D context, which already does them well.
|
|
287
|
+
|
|
221
288
|
### Data
|
|
222
289
|
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.
|
|
223
290
|
|
|
@@ -227,13 +294,16 @@ Enforced in CI by [`size-limit`](./.size-limit.json). Nothing is excluded, becau
|
|
|
227
294
|
|
|
228
295
|
| Bundle | Limit | Actual |
|
|
229
296
|
|---|---|---|
|
|
230
|
-
| Base engine |
|
|
231
|
-
| Base + trade |
|
|
297
|
+
| Base engine | 67 KB | 66.39 KB |
|
|
298
|
+
| Base + trade | 75 KB | 74.00 KB |
|
|
232
299
|
| Indicators tier | 30 KB | 27.27 KB |
|
|
233
|
-
| Draw tier |
|
|
300
|
+
| Draw tier | 26 KB | 25.82 KB |
|
|
234
301
|
| Transform tier | 5 KB | 2.66 KB |
|
|
235
302
|
| Profile tier | 11 KB | 10.66 KB |
|
|
236
|
-
|
|
|
303
|
+
| WebGL2 tier | 7 KB | 6.38 KB |
|
|
304
|
+
| Widget tier | 36 KB | 35.56 KB |
|
|
305
|
+
| Widget terminal (base + draw + indicators + widget) | 156 KB | 155.03 KB |
|
|
306
|
+
| **Everything** | **183 KB** | **182.34 KB** |
|
|
237
307
|
|
|
238
308
|
## Documentation
|
|
239
309
|
|
|
@@ -248,6 +318,8 @@ npm run build # build the library (dist/) the live
|
|
|
248
318
|
cd website && npm install && npm run dev # http://localhost:3000/openalgo-charts
|
|
249
319
|
```
|
|
250
320
|
|
|
321
|
+
For charts that remain open through a market session, see [Performance & Operations](https://marketcalls.github.io/openalgo-charts/docs/performance-and-operations/) for bounded history, canvas memory, feed cleanup, cache limits, and soak checks.
|
|
322
|
+
|
|
251
323
|
## Agent skills
|
|
252
324
|
|
|
253
325
|
Teach your AI coding assistant this library:
|
|
@@ -256,7 +328,7 @@ Teach your AI coding assistant this library:
|
|
|
256
328
|
npx skills add https://github.com/marketcalls/openalgo-charts
|
|
257
329
|
```
|
|
258
330
|
|
|
259
|
-
Installs six skills from [`.github/skills/`](./.github/skills) - a reference hub with
|
|
331
|
+
Installs six skills from [`.github/skills/`](./.github/skills) - a reference hub with 22 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.
|
|
260
332
|
|
|
261
333
|
## Examples
|
|
262
334
|
|
|
@@ -265,7 +337,8 @@ Runnable demos in [`examples/`](./examples), including a full **yfinance termina
|
|
|
265
337
|
```bash
|
|
266
338
|
npm run build
|
|
267
339
|
cd examples/yfinance && pip install -r requirements.txt && python server.py
|
|
268
|
-
#
|
|
340
|
+
# serves http://127.0.0.1:8000/examples/yfinance/index.html
|
|
341
|
+
python server.py --fixture # no yfinance, no network: deterministic synthetic bars
|
|
269
342
|
```
|
|
270
343
|
|
|
271
344
|
## Develop
|
|
@@ -273,11 +346,11 @@ cd examples/yfinance && pip install -r requirements.txt && python server.py
|
|
|
273
346
|
```bash
|
|
274
347
|
npm install # install dev toolchain
|
|
275
348
|
npm run typecheck # strict TypeScript check
|
|
276
|
-
npm test # unit tests (vitest) -
|
|
349
|
+
npm test # unit tests (vitest) - 3999 across 170 files
|
|
277
350
|
npm run build # Rollup -> dist/ (minified ESM per tier + types)
|
|
278
351
|
npm run size # size-limit (Brotli) against the budget
|
|
279
352
|
npm run e2e # Playwright Chromium smoke tests
|
|
280
|
-
npm run verify # typecheck + test + build + size
|
|
353
|
+
npm run verify # lint + typecheck + test + build + demo tests + dts + size + shake
|
|
281
354
|
```
|
|
282
355
|
|
|
283
356
|
## Principles
|
|
@@ -290,7 +363,7 @@ npm run verify # typecheck + test + build + size
|
|
|
290
363
|
|
|
291
364
|
## Status & limitations
|
|
292
365
|
|
|
293
|
-
Version **
|
|
366
|
+
Version **2.0.0**. All engine build phases are implemented with 3999 unit tests across 170 files. Upgrading a 1.9.x host: [Migrating to 2.0](./docs/migrating-to-2.md).
|
|
294
367
|
|
|
295
368
|
Known gaps, stated plainly:
|
|
296
369
|
|
|
@@ -298,7 +371,7 @@ Known gaps, stated plainly:
|
|
|
298
371
|
- **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`.
|
|
299
372
|
- 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.
|
|
300
373
|
- **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.
|
|
301
|
-
-
|
|
374
|
+
- **The WebGL2 backend draws the standard chart types.** Kagi, point-and-figure and custom chart types, drawings, text and every primitive stay on the 2D context; `renderer: 'auto'` is a speed-up for the series pass, not a second renderer for everything.
|
|
302
375
|
|
|
303
376
|
See [`ARCHITECTURE.md`](./ARCHITECTURE.md) §13a for the full deferred list.
|
|
304
377
|
|