openalgo-charts 2.4.6 → 2.4.8

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 CHANGED
@@ -2,23 +2,64 @@
2
2
 
3
3
  # OpenAlgo Charts
4
4
 
5
- **A from-scratch, dependency-free HTML5-canvas charting engine for OpenAlgo.**
5
+ **A JavaScript and TypeScript library for financial charts.**
6
6
 
7
- Professional interactive charts, 105 built-in indicators plus your own custom ones, 85 drawing tools, order flow, market replay, linked chart grids, on-chart trading, vector SVG export and an optional WebGL2 backend. Nine lazy-loaded tiers, zero runtime dependencies, 91.55 kB Brotli for the base engine, and a one-call widget tier that adds the toolbar, drawing rail, dialogs and shortcuts.
7
+ Show market prices, add indicators and drawings, set alerts, and replay historical
8
+ data in your web app. Use your own data and interface, or add the optional widget
9
+ for a toolbar, menus and dialogs. Built for OpenAlgo and custom trading apps,
10
+ with no runtime dependencies.
8
11
 
9
12
  [![npm version](https://img.shields.io/npm/v/openalgo-charts.svg?color=cb3837&label=npm)](https://www.npmjs.com/package/openalgo-charts)
10
13
  [![license](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](./LICENSE)
11
- [![bundle](https://img.shields.io/badge/brotli-91.55%20kB%20base%20%C2%B7%20245.21%20kB%20all%20tiers-brightgreen.svg)](#size-budget)
12
- [![tests](https://img.shields.io/badge/engine%20tests-5804%20passing-brightgreen.svg)](#develop)
14
+ [![npm downloads](https://img.shields.io/npm/dm/openalgo-charts.svg?color=0ea5e9&label=npm%20downloads)](https://www.npmjs.com/package/openalgo-charts)
15
+ [![tests](https://img.shields.io/badge/engine%20tests-5854%20passing-brightgreen.svg)](#develop)
13
16
  [![dependencies](https://img.shields.io/badge/runtime%20deps-0-brightgreen.svg)](#principles)
14
17
 
15
18
  [**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
19
 
17
- <img src="docs/architecture-diagram.svg" alt="OpenAlgo Charts architecture: seven layers from the public API down to feeds and data, with 105 built-in plus custom indicators, 85 drawing tools, and a nine-tier bundle legend" width="920" />
18
-
19
20
  </div>
20
21
 
21
- ---
22
+ ## Install
23
+
24
+ ```bash
25
+ npm install openalgo-charts
26
+ ```
27
+
28
+ Current version: **2.4.8**. Hold the plot to move it in any direction; release to stop.
29
+ See the [changelog](./CHANGELOG.md) for release notes.
30
+
31
+ ## Quick start
32
+
33
+ Give the chart a container with a height:
34
+
35
+ ```html
36
+ <div id="chart" style="width:100%;height:420px"></div>
37
+ ```
38
+
39
+ Then create a chart and supply its data:
40
+
41
+ ```ts
42
+ import { createChart, generateBars } from 'openalgo-charts';
43
+
44
+ const container = document.getElementById('chart');
45
+ if (!container) throw new Error('Chart container not found');
46
+
47
+ const chart = createChart(container);
48
+ chart.addSeries('candlestick').setData(generateBars(1700000000, 200, 3600));
49
+ chart.fitContent();
50
+ ```
51
+
52
+ `generateBars` supplies sample prices. Replace them with data from your feed.
53
+ Bar timestamps use UTC seconds. See [getting started](./docs/getting-started.md)
54
+ for setup, [data feeds](https://marketcalls.github.io/openalgo-charts/docs/data-feeds/)
55
+ for live data, or [the widget example](#the-whole-terminal-in-one-call) for chart controls.
56
+
57
+ ## Architecture
58
+
59
+ <a href="docs/architecture-diagram.svg"><img src="docs/architecture-diagram.svg" alt="OpenAlgo Charts 2.4.8 architecture: host responsibilities, the base data-to-rendering pipeline with alerts and shared replay, and eight optional tiers including workspace storage, trading tools and the widget" width="920" /></a>
60
+
61
+ How data reaches the chart, what your app owns, and which features you can import.
62
+ [Open the full-size diagram](docs/architecture-diagram.svg).
22
63
 
23
64
  ## Walkthrough video
24
65
 
@@ -51,31 +92,6 @@ Every chart in the [live gallery](https://marketcalls.github.io/openalgo-charts/
51
92
  <img src="docs/demo4.png" alt="More live OpenAlgo Charts examples" width="49%" />
52
93
  </p>
53
94
 
54
- ## Install
55
-
56
- Current version: **2.4.6**.
57
-
58
- This release adds optional study source buttons, candle-anchored signal markers
59
- and configurable legend controls. It fixes missing markers at plot gaps, marker
60
- price scales and transparent legend readings. Existing studies keep plot anchoring
61
- by default; hosts opt in to price anchoring and supply their own source editor.
62
- See the [2.4.6 changelog](./CHANGELOG.md#246).
63
-
64
- To try these controls locally, run the [yfinance reference host](./examples/yfinance/README.md)
65
- and add **Source signal sample** from Indicators. Its source button opens the
66
- host-owned code, and Readout settings include **Legend button size** for each chart.
67
-
68
- ```bash
69
- npm install openalgo-charts
70
- ```
71
-
72
- ```ts
73
- import { createChart, generateBars } from 'openalgo-charts';
74
-
75
- const chart = createChart(document.getElementById('chart'));
76
- chart.addSeries('candlestick').setData(generateBars(1700000000, 200, 3600));
77
- ```
78
-
79
95
  ## Branding and optional watermark
80
96
 
81
97
  Version 2.1.9 adds default corner branding and an optional background
@@ -86,22 +102,22 @@ See the [branding guide](https://marketcalls.github.io/openalgo-charts/docs/bran
86
102
 
87
103
  ## No build step
88
104
 
89
- Every release is on unpkg and jsDelivr the moment it is published, because both sit
90
- in front of npm rather than being places you upload to. A chart is one HTML file:
105
+ You can also load the library from a CDN in a plain HTML page:
91
106
 
92
107
  ```html
93
108
  <div id="chart" style="width:100vw;height:100vh"></div>
94
109
  <script type="module">
95
- import { createChart } from 'https://unpkg.com/openalgo-charts@2.4.6/dist/openalgo-charts.mjs';
110
+ import { createChart, generateBars } from 'https://unpkg.com/openalgo-charts@2.4.8/dist/openalgo-charts.mjs';
96
111
  const chart = createChart(document.getElementById('chart'), { timezone: 'Asia/Kolkata' });
97
- chart.addSeries('candlestick').setData(bars);
112
+ chart.addSeries('candlestick').setData(generateBars(1700000000, 200, 3600));
113
+ chart.fitContent();
98
114
  </script>
99
115
  ```
100
116
 
101
- Each tier is its own file, so `openalgo-charts.indicators.mjs` next to it registers
102
- all 105 built-ins. Pin the version in anything you leave running. There is no
103
- stylesheet to load: the engine ships no DOM, and the one tier that does
104
- (`openalgo-charts/widget`) injects its own. See
117
+ Each optional tier has its own file. For example,
118
+ `openalgo-charts.indicators.mjs` registers all 105 built-in indicators. Pin the
119
+ version in production. The base chart needs no stylesheet; the widget adds its
120
+ own styles. See
105
121
  [Use from a CDN](https://marketcalls.github.io/openalgo-charts/docs/cdn).
106
122
 
107
123
  ## The whole terminal in one call
@@ -124,27 +140,34 @@ widget.chart; // the Chart underneath, every base API available
124
140
  widget.draw; // the DrawingController the rail drives
125
141
  ```
126
142
 
127
- `openalgo-charts/widget` is the optional interface 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, responsive mobile header and bottom controls, 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).
143
+ The optional widget adds symbol search, interval and chart-type controls, a drawing
144
+ toolbar, settings, indicators, a status line, mobile controls and layout persistence.
145
+ Its dialogs use the chart's settings schemas and follow the active theme.
146
+
147
+ The widget uses the same public API as a custom interface. Your app supplies the
148
+ data feed and handles order requests; the widget does not choose a broker or send
149
+ orders on its own. See the [widget guide](./docs/widget.md).
128
150
 
129
151
  Widget controls and accessible labels accept a typed translation callback with English fallback. See [widget localization](./docs/widget-localization.md). The separate `openalgo-charts/workspace` tier provides validated named layouts, indicator templates and asynchronous storage, with an IndexedDB adapter and revision conflict detection. See [workspaces](./docs/workspaces.md).
130
152
 
131
153
  ## Tiers
132
154
 
133
- 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.
155
+ Import only the features you need. A tier is a separate bundle of features.
156
+ Unused optional tiers stay out of the base chart download.
134
157
 
135
158
  | Import | Contents | Brotli |
136
159
  |---|---|---|
137
- | `openalgo-charts` | Engine, 13 chart types, panes &amp; scales, primitives, registries, chart state, chart linking, bar cache, interval registry, trading overlay, SVG export, render backend port, OpenAlgo feeds | 91.55 kB |
138
- | `openalgo-charts/indicators` | 105 built-in indicators, the `registerIndicator` contract for your own, and the Tier-2 (external-data) contract | 29.84 kB |
160
+ | `openalgo-charts` | Engine, 13 chart types, panes and scales, custom indicator registry, primitives, alerts, replay, comparisons, chart linking, state, feeds, bar cache, trading overlays, CSV and SVG export | 92.94 kB |
161
+ | `openalgo-charts/indicators` | 105 built-in indicators, calculation helpers and helpers for studies that use external data | 29.84 kB |
139
162
  | `openalgo-charts/draw` | 85 drawing tools + a headless drawing controller, clipboard, settings schema, level palette, freehand geometry and SVG icons | 35.43 kB |
140
163
  | `openalgo-charts/transform` | Heikin Ashi, Renko, Range bars, Line Break, Point &amp; Figure, Kagi, and symbol arithmetic (`AAPL/MSFT`) | 4.50 kB |
141
164
  | `openalgo-charts/profile` | Volume Profile, Market Profile (TPO) with compact pixel letters, Footprint, order flow | 14.96 kB |
142
- | `openalgo-charts/trade` | Order / position / bracket tools + DOM ladder | 8.01 kB |
143
- | `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.39 kB |
144
- | `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 | 49.00 kB |
165
+ | `openalgo-charts/trade` | Order, position and bracket tools, plus a depth-of-market ladder | 8.01 kB |
166
+ | `openalgo-charts/webgl` | GPU drawing for supported series, with Canvas 2D fallback | 6.39 kB |
167
+ | `openalgo-charts/widget` | `createWidget`: toolbar, drawing controls, dialogs, mobile controls, status line, shortcuts and optional layout persistence | 49.03 kB |
145
168
  | `openalgo-charts/workspace` | Validated workspace and indicator-template documents, named catalogs with revision checks, asynchronous storage and an IndexedDB adapter; no DOM | 5.52 kB |
146
169
 
147
- Everything together is **245.21 kB Brotli**; a widget terminal with built-in indicators (base + draw + indicators + widget) is 205.83 kB. Figures are measured from the 2.4.6 release build. The trade tier is 8.01 kB on its own; base + trade costs 99.56 kB. Sizes use decimal kB.
170
+ Everything together is **246.63 kB Brotli**; a widget terminal with built-in indicators (base + draw + indicators + widget) is 207.24 kB. Figures are measured from the 2.4.8 release build. The trade tier is 8.01 kB on its own; base + trade costs 100.95 kB. Sizes use decimal kB.
148
171
 
149
172
  ## What's built
150
173
 
@@ -169,11 +192,28 @@ Every built-in is measured against its standard definition bar by bar, at severa
169
192
 
170
193
  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 arrives independently of the chart's bars (CVD or an external feed).
171
194
 
172
- The development data contract includes optional per-bar `oi` for open interest.
195
+ The bar data contract includes optional per-bar `oi` for open interest.
173
196
  It is a level, not a flow: folds retain the latest reading instead of summing it.
174
197
  Zero and absence remain distinct, and live quotes without a reading leave a gap.
175
198
  See [Open interest data](docs/open-interest.md).
176
199
 
200
+ ### Alerts
201
+
202
+ Set conditions on price, study values, drawing levels or bars. The chart evaluates
203
+ them and your app handles notification delivery. Alerts default to confirmed bar
204
+ closes and keep their state when restored.
205
+
206
+ Drag a price or study alert line to preview a new level, then release to save it.
207
+ Escape cancels the draft, and range bounds stay ordered. Stored thresholds and
208
+ live evaluation keep their original values during the drag. See the
209
+ [alert guide](https://marketcalls.github.io/openalgo-charts/docs/alerts/),
210
+ [2.4.7 changelog](./CHANGELOG.md#247) and
211
+ [live example](https://marketcalls.github.io/openalgo-charts/examples/#alert-threshold-dragging).
212
+
213
+ To try it locally, run the [yfinance reference host](./examples/yfinance/README.md),
214
+ create a price alert from the chart context menu, and drag its dashed line or
215
+ **Alert** badge. Study and range alerts use the same controls.
216
+
177
217
  ### Drawing tools
178
218
 
179
219
  ```ts
@@ -449,17 +489,17 @@ Enforced in CI by [`size-limit`](./.size-limit.json). Nothing is excluded, becau
449
489
 
450
490
  | Bundle | Limit | Actual |
451
491
  |---|---|---|
452
- | Base engine | 92 kB | 91.55 kB |
453
- | Base + trade | 100 kB | 99.56 kB |
492
+ | Base engine | 93.5 kB | 92.94 kB |
493
+ | Base + trade | 101.5 kB | 100.95 kB |
454
494
  | Indicators tier | 30 kB | 29.84 kB |
455
495
  | Draw tier | 36 kB | 35.43 kB |
456
496
  | Transform tier | 6 kB | 4.50 kB |
457
497
  | Profile tier | 15 kB | 14.96 kB |
458
498
  | WebGL2 tier | 7 kB | 6.39 kB |
459
- | Widget tier | 49.25 kB | 49.00 kB |
460
- | Widget terminal (base + draw + indicators + widget) | 206 kB | 205.83 kB |
499
+ | Widget tier | 49.25 kB | 49.03 kB |
500
+ | Widget terminal (base + draw + indicators + widget) | 207.75 kB | 207.24 kB |
461
501
  | Workspace tier | 6 kB | 5.52 kB |
462
- | **Everything** | 245.5 kB | 245.21 kB |
502
+ | **Everything** | 247.25 kB | 246.63 kB |
463
503
 
464
504
  ## Documentation
465
505
 
@@ -504,7 +544,7 @@ See [Contributing](./CONTRIBUTING.md) for setup, targeted checks, documentation
504
544
  ```bash
505
545
  npm install # install dev toolchain
506
546
  npm run typecheck # strict TypeScript check
507
- npm test # engine unit tests (Vitest): 5804 across 246 files
547
+ npm test # engine unit tests (Vitest): 5854 across 246 files
508
548
  npm run test:demo # reference-host tests: 401 across 31 files
509
549
  npm run test:endurance # node endurance-harness tests: 7 cases
510
550
  npm run build # Rollup -> dist/ (minified ESM per tier + types)
@@ -523,7 +563,7 @@ npm run verify # lint + types + unit + endurance harness + build + demo + dt
523
563
 
524
564
  ## Status &amp; limitations
525
565
 
526
- Version **2.4.6**. All engine build phases are implemented. Upgrading a 1.9.x host: [Migrating to 2.0](./docs/migrating-to-2.md).
566
+ Version **2.4.8**. All engine build phases are implemented. Upgrading a 1.9.x host: [Migrating to 2.0](./docs/migrating-to-2.md).
527
567
 
528
568
  Known gaps, stated plainly:
529
569
 
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { TradingCapabilitySource as TradingCapabilitySource$1 } from 'openalgo-charts';
2
2
 
3
3
  /** Library version string. Matches package.json (including locally prepared releases). */
4
- declare const VERSION = "2.4.6";
4
+ declare const VERSION = "2.4.8";
5
5
  /** Returns the current library version. */
6
6
  declare function version(): string;
7
7
 
@@ -812,6 +812,8 @@ interface PrimitiveHit {
812
812
  * declares it here, and the drag callbacks receive time as well as price.
813
813
  */
814
814
  draggable?: boolean;
815
+ /** Opt into Escape cancellation without a release. Listen for `drag:cancel` to discard the preview. */
816
+ cancelOnEscape?: boolean;
815
817
  }
816
818
  /** Injected when a primitive is attached; lets it request a repaint. */
817
819
  interface PrimitiveHost {
@@ -4339,7 +4341,7 @@ interface PointerSample {
4339
4341
  }
4340
4342
  /**
4341
4343
  * What the engine reports about the physical pointer behind a gesture.
4342
- * `crosshair:move`, `click`, `drag` and `drag:end` all carry these keys.
4344
+ * `crosshair:move`, `click`, `drag:start`, `drag` and `drag:end` all carry these keys.
4343
4345
  */
4344
4346
  interface PointerInfo {
4345
4347
  modifiers: PointerModifiers;
@@ -4393,7 +4395,7 @@ interface ChartDragEvent extends PointerInfo {
4393
4395
  */
4394
4396
  samples: PointerSample[];
4395
4397
  }
4396
- /** Payload of the `drag:end` event: the release that finished a primitive drag. */
4398
+ /** Payload of `drag:start` (press) and `drag:end` (release) for a primitive drag. */
4397
4399
  interface ChartDragEndEvent extends PointerInfo {
4398
4400
  id: string;
4399
4401
  price: number;
@@ -4634,6 +4636,7 @@ declare class Chart {
4634
4636
  /** Pressure at the press; a click reports this, since its release always reads 0. */
4635
4637
  private _downPressure;
4636
4638
  private _dragId;
4639
+ private _dragCancelOnEscape;
4637
4640
  private _hoverId;
4638
4641
  /** Whether that primitive draws below the overlay, so leaving it must repaint the base. */
4639
4642
  private _hoverOnBase;
@@ -5488,6 +5491,7 @@ declare class Chart {
5488
5491
  */
5489
5492
  private readonly _onPointerUpNative;
5490
5493
  private readonly _onPointerCancel;
5494
+ private readonly _onLostPointerCapture;
5491
5495
  private _brandingHit;
5492
5496
  private readonly _onPointerLeave;
5493
5497
  private readonly _onWheel;
@@ -5506,6 +5510,7 @@ declare class Chart {
5506
5510
  private readonly _onDblClick;
5507
5511
  private _beginPinch;
5508
5512
  private _updatePinch;
5513
+ private _cancelPrimitiveDrag;
5509
5514
  private readonly _onKeyDown;
5510
5515
  /** Scope gating: hover keeps keys chart-local; global always acts. */
5511
5516
  private _shortcutsActive;
@@ -9579,7 +9584,14 @@ declare class AlertController {
9579
9584
  private _replay;
9580
9585
  private _destroyed;
9581
9586
  private _revision;
9587
+ private _drag;
9582
9588
  constructor(_chart: AlertChartHost, options?: AlertControllerOptions);
9589
+ private _dragAvailability;
9590
+ private _dragPrice;
9591
+ private _startDrag;
9592
+ private _cancelDrag;
9593
+ /** Market evaluation keeps the committed source until a moved, owned gesture ends. */
9594
+ private _onDrag;
9583
9595
  add(input: AlertInput): Alert;
9584
9596
  update(id: string, patch: AlertPatch): Alert | undefined;
9585
9597
  remove(id: string): boolean;