openalgo-charts 1.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.
@@ -0,0 +1,178 @@
1
+ /**
2
+ * Internal time is always **UTC seconds** (integer). Feed adapters convert
3
+ * broker formats (IST strings, epoch ms) to this at the edge; see ARCHITECTURE.md §4.0.
4
+ */
5
+ type UTCSeconds = number;
6
+ /** A single OHLC(V) bar. `volume` is optional (not all feeds carry it). */
7
+ interface Bar {
8
+ time: UTCSeconds;
9
+ open: number;
10
+ high: number;
11
+ low: number;
12
+ close: number;
13
+ volume?: number;
14
+ }
15
+
16
+ /**
17
+ * Series transform pipeline (ARCHITECTURE.md §6A, Family B). A transform
18
+ * re-buckets raw OHLC into a derived element series driven by price movement,
19
+ * not the clock. Transforms are incremental (streaming) so live ticks extend
20
+ * the series without recomputing history.
21
+ *
22
+ * Each derived element is a Bar carrying its source formation time. Because the
23
+ * time scale is index-based, derived elements get uniform spacing automatically
24
+ * (the "ordinal" axis); axis labels read each element's formation time. We only
25
+ * post-process times to be strictly increasing so the shared DataLayer keeps
26
+ * every element on its own logical index (no collisions when many elements form
27
+ * within one source bar).
28
+ */
29
+
30
+ interface ISeriesTransform {
31
+ /** Reset to initial state (start of a fresh batch / re-subscribe). */
32
+ reset(): void;
33
+ /** Feed one source bar; return 0..n newly *completed* derived elements. */
34
+ push(bar: Bar): Bar[];
35
+ /** Optional: emit any in-progress element at end of data. */
36
+ flush?(): Bar[];
37
+ }
38
+ /**
39
+ * Make times strictly increasing (collisions bumped by +1s) so the DataLayer
40
+ * assigns one logical index per element. Labels stay within a few seconds of
41
+ * the real formation time.
42
+ */
43
+ declare function ensureIncreasingTimes(bars: readonly Bar[]): Bar[];
44
+ /** Run a transform over a full batch of bars (history load). */
45
+ declare function runTransform(transform: ISeriesTransform, bars: readonly Bar[]): Bar[];
46
+
47
+ /**
48
+ * Heikin Ashi (ARCHITECTURE.md §6A). 1:1 with input bars (keeps real times);
49
+ * renders with the candlestick renderer.
50
+ * haClose = (o+h+l+c)/4
51
+ * haOpen = first: (o+c)/2 ; else (prevHaOpen + prevHaClose)/2
52
+ * haHigh = max(h, haOpen, haClose) ; haLow = min(l, haOpen, haClose)
53
+ */
54
+
55
+ declare class HeikinAshiTransform implements ISeriesTransform {
56
+ private _prevOpen;
57
+ private _prevClose;
58
+ reset(): void;
59
+ push(bar: Bar): Bar[];
60
+ }
61
+
62
+ /**
63
+ * Renko bricks (ARCHITECTURE.md §6A). Each fixed box-size move of the close
64
+ * emits one brick. Renders with the candlestick renderer (brick = a body).
65
+ * Simplified single-box step (no 2× reversal rule) — deterministic and
66
+ * incremental for live updates.
67
+ */
68
+
69
+ interface RenkoOptions {
70
+ boxSize: number;
71
+ }
72
+ declare class RenkoTransform implements ISeriesTransform {
73
+ private readonly _box;
74
+ private _edge;
75
+ constructor(options: RenkoOptions);
76
+ reset(): void;
77
+ push(bar: Bar): Bar[];
78
+ }
79
+
80
+ /**
81
+ * Range bars (ARCHITECTURE.md §6A). A new bar completes when its high−low
82
+ * reaches the configured range. Built from the close sequence; renders with the
83
+ * candlestick renderer. Incremental: the in-progress bar is emitted by flush().
84
+ */
85
+
86
+ interface RangeOptions {
87
+ range: number;
88
+ }
89
+ declare class RangeBarsTransform implements ISeriesTransform {
90
+ private readonly _range;
91
+ private _cur;
92
+ constructor(options: RangeOptions);
93
+ reset(): void;
94
+ push(bar: Bar): Bar[];
95
+ flush(): Bar[];
96
+ }
97
+
98
+ /**
99
+ * Line Break (ARCHITECTURE.md §6A). A new line forms only when the close breaks
100
+ * beyond the extreme of the prior N lines (default 3). Renders with the
101
+ * candlestick renderer (each line = a body). Incremental.
102
+ */
103
+
104
+ interface LineBreakOptions {
105
+ lines: number;
106
+ }
107
+ declare class LineBreakTransform implements ISeriesTransform {
108
+ private readonly _n;
109
+ private _lines;
110
+ constructor(options?: LineBreakOptions);
111
+ reset(): void;
112
+ push(bar: Bar): Bar[];
113
+ }
114
+
115
+ /**
116
+ * Point & Figure (ARCHITECTURE.md §6A). Columns of X (up) / O (down); a new
117
+ * column starts only after a reversal of `reversal` boxes. Each column is
118
+ * encoded as a Bar spanning the column's price range, with up = close ≥ open
119
+ * (X) and down = close < open (O). The point-figure renderer stacks the glyphs
120
+ * using `boxSize` from the series style.
121
+ */
122
+
123
+ interface PointFigureOptions {
124
+ boxSize: number;
125
+ reversal: number;
126
+ }
127
+ declare class PointFigureTransform implements ISeriesTransform {
128
+ private readonly _box;
129
+ private readonly _reversal;
130
+ private _dir;
131
+ private _topBox;
132
+ private _botBox;
133
+ private _time;
134
+ constructor(options: PointFigureOptions);
135
+ reset(): void;
136
+ private _column;
137
+ push(bar: Bar): Bar[];
138
+ flush(): Bar[];
139
+ }
140
+
141
+ /**
142
+ * Kagi (ARCHITECTURE.md §6A). A continuous line that reverses direction only
143
+ * after a move of at least `reversal`. Turning points are emitted as vertices.
144
+ * Line thickness (yang/yin) is encoded in `volume` (1 = thick, 0 = thin) using
145
+ * a simplified rule: thick once the line exceeds the previous up-turn (higher
146
+ * shoulder), thin once it falls below the previous down-turn (lower waist).
147
+ * The kagi renderer connects vertices with a stepped line of varying width.
148
+ */
149
+
150
+ interface KagiOptions {
151
+ reversal: number;
152
+ }
153
+ declare class KagiTransform implements ISeriesTransform {
154
+ private readonly _reversal;
155
+ private _dir;
156
+ private _ext;
157
+ private _prevShoulder;
158
+ private _prevWaist;
159
+ private _thick;
160
+ constructor(options: KagiOptions);
161
+ reset(): void;
162
+ push(bar: Bar): Bar[];
163
+ flush(): Bar[];
164
+ }
165
+
166
+ declare const TRANSFORM_TIER: "transform";
167
+ /**
168
+ * Register the Family-B custom renderers (point-figure, kagi). Called as a side
169
+ * effect when this tier is imported, and also exported so consumers whose
170
+ * bundler aggressively tree-shakes a bare `import 'openalgo-charts/transform'`
171
+ * can call it explicitly. Idempotent.
172
+ *
173
+ * (Heikin Ashi / Renko / Range / Line Break render as a 'candlestick' series and
174
+ * need no new type — only P&F and Kagi have custom renderers.)
175
+ */
176
+ declare function registerTransformChartTypes(): void;
177
+
178
+ export { HeikinAshiTransform, type ISeriesTransform, type KagiOptions, KagiTransform, type LineBreakOptions, LineBreakTransform, type PointFigureOptions, PointFigureTransform, RangeBarsTransform, type RangeOptions, type RenkoOptions, RenkoTransform, TRANSFORM_TIER, ensureIncreasingTimes, registerTransformChartTypes, runTransform };
package/package.json ADDED
@@ -0,0 +1,71 @@
1
+ {
2
+ "name": "openalgo-charts",
3
+ "version": "1.0.0",
4
+ "description": "From-scratch, dependency-free canvas charting engine for OpenAlgo: professional-grade interactive rendering plus advanced on-chart trading.",
5
+ "license": "Apache-2.0",
6
+ "author": "marketcalls",
7
+ "homepage": "https://github.com/marketcalls/openalgo-charts#readme",
8
+ "repository": { "type": "git", "url": "git+https://github.com/marketcalls/openalgo-charts.git" },
9
+ "bugs": { "url": "https://github.com/marketcalls/openalgo-charts/issues" },
10
+ "keywords": ["charts", "charting", "candlestick", "trading", "finance", "canvas", "openalgo", "technical-analysis", "footprint", "renko", "heikin-ashi"],
11
+ "type": "module",
12
+ "module": "dist/openalgo-charts.mjs",
13
+ "types": "dist/index.d.ts",
14
+ "exports": {
15
+ ".": {
16
+ "types": "./dist/index.d.ts",
17
+ "import": "./dist/openalgo-charts.mjs"
18
+ },
19
+ "./trade": {
20
+ "types": "./dist/trade/index.d.ts",
21
+ "import": "./dist/openalgo-charts.trade.mjs"
22
+ },
23
+ "./transform": {
24
+ "types": "./dist/transform/index.d.ts",
25
+ "import": "./dist/openalgo-charts.transform.mjs"
26
+ },
27
+ "./profile": {
28
+ "types": "./dist/profile/index.d.ts",
29
+ "import": "./dist/openalgo-charts.profile.mjs"
30
+ }
31
+ },
32
+ "files": [
33
+ "dist/**",
34
+ "!dist/openalgo-charts.all.mjs",
35
+ "!dist/openalgo-charts.all.mjs.map"
36
+ ],
37
+ "sideEffects": [
38
+ "**/transform/**",
39
+ "./dist/openalgo-charts.transform.mjs"
40
+ ],
41
+ "scripts": {
42
+ "clean": "rimraf dist",
43
+ "build": "rollup -c",
44
+ "build:watch": "rollup -c --watch",
45
+ "typecheck": "tsc --noEmit",
46
+ "test": "vitest run",
47
+ "test:watch": "vitest",
48
+ "e2e": "playwright test",
49
+ "size": "size-limit",
50
+ "docs": "typedoc",
51
+ "verify": "npm run typecheck && npm run test && npm run build && npm run size",
52
+ "prepublishOnly": "npm run verify"
53
+ },
54
+ "engines": {
55
+ "node": ">=20"
56
+ },
57
+ "devDependencies": {
58
+ "@playwright/test": "^1.49.1",
59
+ "@rollup/plugin-terser": "0.4.4",
60
+ "@rollup/plugin-typescript": "12.1.2",
61
+ "@size-limit/file": "11.1.6",
62
+ "rimraf": "6.0.1",
63
+ "rollup": "4.30.1",
64
+ "rollup-plugin-dts": "6.1.1",
65
+ "size-limit": "11.1.6",
66
+ "tslib": "2.8.1",
67
+ "typedoc": "0.27.6",
68
+ "typescript": "5.7.3",
69
+ "vitest": "2.1.8"
70
+ }
71
+ }