openalgo-charts 1.2.0 → 1.3.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 +73 -20
- package/dist/index.d.ts +1762 -45
- package/dist/indicators/index.d.ts +4 -3
- 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.mjs.map +1 -1
- package/dist/openalgo-charts.profile.mjs +1 -1
- package/dist/openalgo-charts.profile.mjs.map +1 -1
- package/dist/openalgo-charts.standalone.js +1 -1
- package/dist/openalgo-charts.standalone.js.map +1 -1
- package/dist/profile/index.d.ts +50 -7
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -4,12 +4,12 @@
|
|
|
4
4
|
|
|
5
5
|
**A from-scratch, dependency-free HTML5-canvas charting engine for OpenAlgo.**
|
|
6
6
|
|
|
7
|
-
Professional interactive charts, indicators, drawing tools, order flow, and on-chart trading
|
|
7
|
+
Professional interactive charts, indicators, drawing tools, order flow, market replay, and on-chart trading. Six lazy-loaded tiers, zero runtime dependencies, ~49 KB Brotli for the base engine.
|
|
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
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)
|
|
@@ -60,14 +60,14 @@ Import only what you use. Each tier is a separate bundle that registers into the
|
|
|
60
60
|
|
|
61
61
|
| Import | Contents | Brotli |
|
|
62
62
|
|---|---|---|
|
|
63
|
-
| `openalgo-charts` | Engine, 13 chart types, panes & scales, primitives, registries, chart state, trading overlay, OpenAlgo feeds |
|
|
64
|
-
| `openalgo-charts/indicators` | 91 built-in indicators + the Tier-2 (external-data) contract | 24.
|
|
63
|
+
| `openalgo-charts` | Engine, 13 chart types, panes & scales, primitives, registries, chart state, trading overlay, OpenAlgo feeds | 49.4 KB |
|
|
64
|
+
| `openalgo-charts/indicators` | 91 built-in indicators + the Tier-2 (external-data) contract | 24.9 KB |
|
|
65
65
|
| `openalgo-charts/draw` | 43 drawing tools + a headless drawing controller | 11.7 KB |
|
|
66
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.
|
|
67
|
+
| `openalgo-charts/profile` | Volume Profile, Market Profile (TPO), Footprint, order flow | 10.7 KB |
|
|
68
68
|
| `openalgo-charts/trade` | Order / position / bracket tools + DOM ladder | 6.6 KB |
|
|
69
69
|
|
|
70
|
-
Everything together is **
|
|
70
|
+
Everything together is **105.9 KB Brotli**. Figures are the measured `size-limit` output; the trade tier is a delta over the base, which is why base + trade (56.0 KB) is less than their listed sum.
|
|
71
71
|
|
|
72
72
|
## What's built
|
|
73
73
|
|
|
@@ -101,8 +101,61 @@ draw.setTool('trend-line'); // the next two clicks place it
|
|
|
101
101
|
|
|
102
102
|
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.
|
|
103
103
|
|
|
104
|
-
### Panes & legends
|
|
105
|
-
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.
|
|
104
|
+
### Panes, scales & legends
|
|
105
|
+
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.
|
|
106
|
+
|
|
107
|
+
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.
|
|
108
|
+
|
|
109
|
+
### Reference levels and axis chrome
|
|
110
|
+
|
|
111
|
+
```ts
|
|
112
|
+
import { PriceLevels } from 'openalgo-charts';
|
|
113
|
+
|
|
114
|
+
const levels = new PriceLevels({
|
|
115
|
+
levels: { previousClose: { line: true, label: true }, sessionHigh: { line: true, label: false } },
|
|
116
|
+
});
|
|
117
|
+
chart.addPrimitive(levels, 0);
|
|
118
|
+
levels.available('bid'); // false until a quote is fed: render that control disabled, not hidden
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
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.
|
|
122
|
+
|
|
123
|
+
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.
|
|
124
|
+
|
|
125
|
+
### Timezones
|
|
126
|
+
|
|
127
|
+
```ts
|
|
128
|
+
const chart = createChart(el, { timezone: 'America/New_York' });
|
|
129
|
+
chart.setTimezone('Europe/London'); // relabels and recomputes on the next frame
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
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.
|
|
133
|
+
|
|
134
|
+
### Market replay
|
|
135
|
+
|
|
136
|
+
```ts
|
|
137
|
+
import { ReplayController } from 'openalgo-charts';
|
|
138
|
+
|
|
139
|
+
const replay = new ReplayController(chart, { bars, startIndex: 200, barMs: 500 });
|
|
140
|
+
replay.play({ speed: 2 }); // emits replay:frame per bar
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
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.
|
|
144
|
+
|
|
145
|
+
### Symbol comparison
|
|
146
|
+
|
|
147
|
+
```ts
|
|
148
|
+
import { addComparison } from 'openalgo-charts';
|
|
149
|
+
|
|
150
|
+
const bn = addComparison(chart, { symbol: 'BANKNIFTY', bars });
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
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.
|
|
154
|
+
|
|
155
|
+
### Settings & context menu
|
|
156
|
+
`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.
|
|
157
|
+
|
|
158
|
+
`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.
|
|
106
159
|
|
|
107
160
|
### Trading
|
|
108
161
|
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).
|
|
@@ -111,10 +164,10 @@ Order, position, and bracket lines with live P&L, one-click and drag-to-modi
|
|
|
111
164
|
Volume Profile, Market Profile (TPO), Footprint, and cumulative delta.
|
|
112
165
|
|
|
113
166
|
### State
|
|
114
|
-
`chart.getState()` / `chart.restoreState()` capture the viewport, grid, panes, price scales, indicator instances, and
|
|
167
|
+
`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.
|
|
115
168
|
|
|
116
169
|
### Data
|
|
117
|
-
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, and custom price/time formatters.
|
|
170
|
+
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.
|
|
118
171
|
|
|
119
172
|
## Size budget
|
|
120
173
|
|
|
@@ -122,13 +175,13 @@ Enforced in CI by [`size-limit`](./.size-limit.json) — nothing is excluded, be
|
|
|
122
175
|
|
|
123
176
|
| Bundle | Limit | Actual |
|
|
124
177
|
|---|---|---|
|
|
125
|
-
| Base engine |
|
|
126
|
-
| Base + trade |
|
|
127
|
-
| Indicators tier |
|
|
178
|
+
| Base engine | 55 KB | 49.37 KB |
|
|
179
|
+
| Base + trade | 62 KB | 55.95 KB |
|
|
180
|
+
| Indicators tier | 27 KB | 24.88 KB |
|
|
128
181
|
| Draw tier | 14 KB | 11.73 KB |
|
|
129
182
|
| Transform tier | 5 KB | 2.66 KB |
|
|
130
|
-
| Profile tier | 11 KB | 10.
|
|
131
|
-
| **Everything** | **
|
|
183
|
+
| Profile tier | 11 KB | 10.66 KB |
|
|
184
|
+
| **Everything** | **120 KB** | **105.88 KB** |
|
|
132
185
|
|
|
133
186
|
## Documentation
|
|
134
187
|
|
|
@@ -151,7 +204,7 @@ Teach your AI coding assistant this library:
|
|
|
151
204
|
npx skills add https://github.com/marketcalls/openalgo-charts
|
|
152
205
|
```
|
|
153
206
|
|
|
154
|
-
Installs six skills from [`.github/skills/`](./.github/skills) - a reference hub with
|
|
207
|
+
Installs six skills from [`.github/skills/`](./.github/skills) - a reference hub with 20 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.
|
|
155
208
|
|
|
156
209
|
## Examples
|
|
157
210
|
|
|
@@ -168,7 +221,7 @@ cd examples/yfinance && pip install -r requirements.txt && python server.py
|
|
|
168
221
|
```bash
|
|
169
222
|
npm install # install dev toolchain
|
|
170
223
|
npm run typecheck # strict TypeScript check
|
|
171
|
-
npm test # unit tests (vitest) -
|
|
224
|
+
npm test # unit tests (vitest) - 1543 across 81 files
|
|
172
225
|
npm run build # Rollup -> dist/ (minified ESM per tier + types)
|
|
173
226
|
npm run size # size-limit (Brotli) against the budget
|
|
174
227
|
npm run e2e # Playwright Chromium smoke tests
|
|
@@ -185,14 +238,14 @@ npm run verify # typecheck + test + build + size
|
|
|
185
238
|
|
|
186
239
|
## Status & limitations
|
|
187
240
|
|
|
188
|
-
Version **1.
|
|
241
|
+
Version **1.3.0**. All engine build phases are implemented with 1558 unit tests across 84 files.
|
|
189
242
|
|
|
190
243
|
Known gaps, stated plainly:
|
|
191
244
|
|
|
192
245
|
- **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.
|
|
193
246
|
- **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`.
|
|
194
247
|
- 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.
|
|
195
|
-
-
|
|
248
|
+
- **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.
|
|
196
249
|
- An optional **DOM chrome package** (toolbar, dialogs, command palette, objects panel) is the next planned piece; today that UI lives in the examples.
|
|
197
250
|
|
|
198
251
|
See [`ARCHITECTURE.md`](./ARCHITECTURE.md) §13a for the full deferred list.
|