@luxalgo/vela 0.5.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/LICENSE +201 -0
- package/NOTICE +28 -0
- package/README.md +135 -0
- package/dist/DataProvider-DKNDHpNv.d.cts +134 -0
- package/dist/DataProvider-Dzd-Erlk.d.ts +134 -0
- package/dist/chunk-7UFX5ZIG.js +5976 -0
- package/dist/chunk-GYD2THPV.js +252 -0
- package/dist/chunk-KCCZNKH7.js +19137 -0
- package/dist/chunk-KM6LHB3Y.js +76 -0
- package/dist/chunk-OVQKKXLZ.js +3978 -0
- package/dist/chunk-Q3XQHLIH.js +7 -0
- package/dist/chunk-RHIDOUFL.js +698 -0
- package/dist/contributions-hX3EUyjG.d.ts +1528 -0
- package/dist/contributions-o1GRKPI_.d.cts +1528 -0
- package/dist/history-Dzxz-MQj.d.ts +298 -0
- package/dist/history-LJkz4-sS.d.cts +298 -0
- package/dist/icons-BZYbJXSV.d.cts +10 -0
- package/dist/icons-BZYbJXSV.d.ts +10 -0
- package/dist/index.cjs +25294 -0
- package/dist/index.d.cts +1189 -0
- package/dist/index.d.ts +1189 -0
- package/dist/index.js +5 -0
- package/dist/keymap-CGOz5F5f.d.cts +64 -0
- package/dist/keymap-CGOz5F5f.d.ts +64 -0
- package/dist/options-Q-576hIi.d.cts +1545 -0
- package/dist/options-Q-576hIi.d.ts +1545 -0
- package/dist/plugin-D94muTV-.d.cts +405 -0
- package/dist/plugin-aGUD1epn.d.ts +405 -0
- package/dist/plugin.cjs +5967 -0
- package/dist/plugin.d.cts +7 -0
- package/dist/plugin.d.ts +7 -0
- package/dist/plugin.js +3 -0
- package/dist/providers/binance.cjs +390 -0
- package/dist/providers/binance.d.cts +62 -0
- package/dist/providers/binance.d.ts +62 -0
- package/dist/providers/binance.js +388 -0
- package/dist/providers/coinbase.cjs +462 -0
- package/dist/providers/coinbase.d.cts +59 -0
- package/dist/providers/coinbase.d.ts +59 -0
- package/dist/providers/coinbase.js +460 -0
- package/dist/providers/hyperliquid.cjs +361 -0
- package/dist/providers/hyperliquid.d.cts +54 -0
- package/dist/providers/hyperliquid.d.ts +54 -0
- package/dist/providers/hyperliquid.js +359 -0
- package/dist/side-panel-CT9ZwIGz.d.cts +63 -0
- package/dist/side-panel-CT9ZwIGz.d.ts +63 -0
- package/dist/ui.cjs +1030 -0
- package/dist/ui.d.cts +188 -0
- package/dist/ui.d.ts +188 -0
- package/dist/ui.js +3 -0
- package/dist/vela.global.js +26509 -0
- package/dist/vela.global.min.js +230 -0
- package/dist/widget.cjs +31178 -0
- package/dist/widget.d.cts +799 -0
- package/dist/widget.d.ts +799 -0
- package/dist/widget.js +1060 -0
- package/dist/workspace.cjs +31692 -0
- package/dist/workspace.d.cts +579 -0
- package/dist/workspace.d.ts +579 -0
- package/dist/workspace.js +1694 -0
- package/package.json +95 -0
|
@@ -0,0 +1,1545 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Canonical time in Vela: Unix epoch **milliseconds**.
|
|
3
|
+
*
|
|
4
|
+
* This matches JS `Date` and the bar `openTime` every provider and scripting
|
|
5
|
+
* engine speaks. Each renderer converts to its own unit at its boundary (a
|
|
6
|
+
* second-based adapter divides by 1000).
|
|
7
|
+
*/
|
|
8
|
+
type Millis = number;
|
|
9
|
+
|
|
10
|
+
/** A single price bar. `time` is the bar's open time in epoch ms. */
|
|
11
|
+
interface OHLCV {
|
|
12
|
+
time: Millis;
|
|
13
|
+
open: number;
|
|
14
|
+
high: number;
|
|
15
|
+
low: number;
|
|
16
|
+
close: number;
|
|
17
|
+
volume?: number;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/** Value-series kinds drawn as a connected/point series. */
|
|
21
|
+
type LineLikeKind = 'line' | 'area' | 'step' | 'histogram' | 'columns' | 'circles' | 'cross';
|
|
22
|
+
/**
|
|
23
|
+
* All renderable series kinds. NOTE: `fill`, `background`, and `hline` are
|
|
24
|
+
* intentionally NOT series kinds — they are modeled as overlays on a pane
|
|
25
|
+
* (see scene.ts), and `barcolor` is a recolor of the price candles, not a
|
|
26
|
+
* series.
|
|
27
|
+
*/
|
|
28
|
+
type SeriesKind = LineLikeKind | 'candle' | 'bar' | 'markers';
|
|
29
|
+
type LineStyle = 'solid' | 'dashed' | 'dotted';
|
|
30
|
+
/** A single point of a value series. `value: null` marks a gap (whitespace). */
|
|
31
|
+
interface SeriesPoint {
|
|
32
|
+
time: Millis;
|
|
33
|
+
value: number | null;
|
|
34
|
+
/** Per-point color override (e.g. `plot(x, color = cond ? c1 : c2)`). */
|
|
35
|
+
color?: string;
|
|
36
|
+
}
|
|
37
|
+
interface LineLikeStyle {
|
|
38
|
+
color: string;
|
|
39
|
+
width: number;
|
|
40
|
+
lineStyle: LineStyle;
|
|
41
|
+
/** Baseline for histogram/area; ignored by the line family. */
|
|
42
|
+
base?: number;
|
|
43
|
+
}
|
|
44
|
+
interface CandleStyle {
|
|
45
|
+
up: string;
|
|
46
|
+
down: string;
|
|
47
|
+
wickUp?: string;
|
|
48
|
+
wickDown?: string;
|
|
49
|
+
borderUp?: string;
|
|
50
|
+
borderDown?: string;
|
|
51
|
+
}
|
|
52
|
+
/** Per-bar plotcandle/plotbar override (body / wick / border colours). */
|
|
53
|
+
interface CandleBarColor {
|
|
54
|
+
color?: string;
|
|
55
|
+
wickColor?: string;
|
|
56
|
+
borderColor?: string;
|
|
57
|
+
}
|
|
58
|
+
interface MarkerPoint {
|
|
59
|
+
time: Millis;
|
|
60
|
+
position: 'aboveBar' | 'belowBar' | 'inBar';
|
|
61
|
+
/** Neutral shape token (e.g. 'arrowUp', 'circle', 'square'); mapped per renderer. */
|
|
62
|
+
shape: string;
|
|
63
|
+
color: string;
|
|
64
|
+
text?: string;
|
|
65
|
+
size?: 'tiny' | 'small' | 'normal' | 'large' | 'huge';
|
|
66
|
+
}
|
|
67
|
+
interface SeriesBase {
|
|
68
|
+
/** Content-addressed, stable across re-runs of identical source (see identity.ts). */
|
|
69
|
+
id: string;
|
|
70
|
+
title: string;
|
|
71
|
+
/** Pane this series belongs to; resolved by the orchestrator. */
|
|
72
|
+
paneId: string;
|
|
73
|
+
/** Declared draw-order intent; the renderer owns final z-ordering. */
|
|
74
|
+
zOrder?: number;
|
|
75
|
+
visible?: boolean;
|
|
76
|
+
}
|
|
77
|
+
interface LineLikeSeries extends SeriesBase {
|
|
78
|
+
kind: LineLikeKind;
|
|
79
|
+
points: SeriesPoint[];
|
|
80
|
+
style: LineLikeStyle;
|
|
81
|
+
}
|
|
82
|
+
interface CandleSeries extends SeriesBase {
|
|
83
|
+
kind: 'candle' | 'bar';
|
|
84
|
+
bars: OHLCV[];
|
|
85
|
+
style?: Partial<CandleStyle>;
|
|
86
|
+
/** Per-bar plotcandle/plotbar colours, aligned to `bars` by index (null ≡ use defaults). */
|
|
87
|
+
barColors?: Array<CandleBarColor | null>;
|
|
88
|
+
}
|
|
89
|
+
interface MarkerSeries extends SeriesBase {
|
|
90
|
+
kind: 'markers';
|
|
91
|
+
markers: MarkerPoint[];
|
|
92
|
+
}
|
|
93
|
+
type SeriesSpec = LineLikeSeries | CandleSeries | MarkerSeries;
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Renderer-neutral models for Pine drawing objects (`line.new`, `box.new`, …).
|
|
97
|
+
* Coordinates are kept in their Pine form, tagged by {@link DrawingXLoc}: the
|
|
98
|
+
* renderer converts a bar index or epoch-ms time to a pixel via the time scale.
|
|
99
|
+
*/
|
|
100
|
+
/** How a drawing's x-coordinates are interpreted (Pine `xloc`). */
|
|
101
|
+
type DrawingXLoc = 'bar_index' | 'bar_time';
|
|
102
|
+
/** Pine `extend`: which side(s) the drawing runs out to the chart edge. */
|
|
103
|
+
type DrawingExtend = 'none' | 'left' | 'right' | 'both';
|
|
104
|
+
type BoxTextSize = 'auto' | 'tiny' | 'small' | 'normal' | 'large' | 'huge';
|
|
105
|
+
type BoxHAlign = 'left' | 'center' | 'right';
|
|
106
|
+
type BoxVAlign = 'top' | 'center' | 'bottom';
|
|
107
|
+
type BoxFontFamily = 'default' | 'monospace';
|
|
108
|
+
/**
|
|
109
|
+
* A Pine `line.new(...)`. `x1/x2` are bar indices (xloc `bar_index`) or epoch ms
|
|
110
|
+
* (xloc `bar_time`); `y1/y2` are prices.
|
|
111
|
+
*/
|
|
112
|
+
interface DrawingLine {
|
|
113
|
+
id: string;
|
|
114
|
+
paneId: string;
|
|
115
|
+
xloc: DrawingXLoc;
|
|
116
|
+
x1: number;
|
|
117
|
+
y1: number;
|
|
118
|
+
x2: number;
|
|
119
|
+
y2: number;
|
|
120
|
+
extend: DrawingExtend;
|
|
121
|
+
/** Stroke color. `undefined` → use the renderer's default foreground color. */
|
|
122
|
+
color?: string;
|
|
123
|
+
/** `na` color → the line exists but is not stroked (e.g. a linefill anchor). */
|
|
124
|
+
invisible: boolean;
|
|
125
|
+
/** Pine line width in px (uncapped, unlike a series `lineWidth`). */
|
|
126
|
+
width: number;
|
|
127
|
+
style: LineStyle;
|
|
128
|
+
/** Arrowhead at the first point (`style_arrow_left` / `style_arrow_both`). */
|
|
129
|
+
arrowLeft: boolean;
|
|
130
|
+
/** Arrowhead at the second point (`style_arrow_right` / `style_arrow_both`). */
|
|
131
|
+
arrowRight: boolean;
|
|
132
|
+
/** `force_overlay` → render on the price pane regardless of the indicator's pane. */
|
|
133
|
+
overlay?: boolean;
|
|
134
|
+
}
|
|
135
|
+
/** A Pine `box.new(...)`. `left/right` follow `xloc`; `top/bottom` are prices. */
|
|
136
|
+
interface DrawingBox {
|
|
137
|
+
id: string;
|
|
138
|
+
paneId: string;
|
|
139
|
+
xloc: DrawingXLoc;
|
|
140
|
+
left: number;
|
|
141
|
+
top: number;
|
|
142
|
+
right: number;
|
|
143
|
+
bottom: number;
|
|
144
|
+
extend: DrawingExtend;
|
|
145
|
+
/** Fill color (may carry alpha). `undefined` → no fill (`na`). */
|
|
146
|
+
bgColor?: string;
|
|
147
|
+
/** Border color. `undefined` → no border (`na`). */
|
|
148
|
+
borderColor?: string;
|
|
149
|
+
borderWidth: number;
|
|
150
|
+
borderStyle: LineStyle;
|
|
151
|
+
/** Box text. `undefined`/empty → no text drawn. */
|
|
152
|
+
text?: string;
|
|
153
|
+
/** Text color. `undefined` → auto-contrast against the fill. */
|
|
154
|
+
textColor?: string;
|
|
155
|
+
textSize: BoxTextSize;
|
|
156
|
+
hAlign: BoxHAlign;
|
|
157
|
+
vAlign: BoxVAlign;
|
|
158
|
+
/** `text.wrap_auto` → wrap to the box width; otherwise single line per `\n`. */
|
|
159
|
+
wrap: boolean;
|
|
160
|
+
fontFamily: BoxFontFamily;
|
|
161
|
+
bold: boolean;
|
|
162
|
+
italic: boolean;
|
|
163
|
+
/** `force_overlay` → render on the price pane regardless of the indicator's pane. */
|
|
164
|
+
overlay?: boolean;
|
|
165
|
+
}
|
|
166
|
+
/** Pine `label.style_*` (the bubble/pointer variants and the point-marker shapes). */
|
|
167
|
+
type LabelStyle = 'label_up' | 'label_down' | 'label_left' | 'label_right' | 'label_center' | 'label_lower_left' | 'label_lower_right' | 'label_upper_left' | 'label_upper_right' | 'circle' | 'square' | 'diamond' | 'flag' | 'arrowup' | 'arrowdown' | 'triangleup' | 'triangledown' | 'cross' | 'xcross' | 'text_outline' | 'none';
|
|
168
|
+
/**
|
|
169
|
+
* Where a label/marker anchors vertically. Pine `yloc` (price/abovebar/belowbar)
|
|
170
|
+
* plus the `plotshape` pane-relative `location.top`/`location.bottom`.
|
|
171
|
+
*/
|
|
172
|
+
type LabelYLoc = 'price' | 'abovebar' | 'belowbar' | 'top' | 'bottom';
|
|
173
|
+
/** A Pine `label.new(...)`. `x` follows `xloc`; `y` is a price (used when yloc='price'). */
|
|
174
|
+
interface DrawingLabel {
|
|
175
|
+
id: string;
|
|
176
|
+
paneId: string;
|
|
177
|
+
xloc: DrawingXLoc;
|
|
178
|
+
x: number;
|
|
179
|
+
y: number;
|
|
180
|
+
yloc: LabelYLoc;
|
|
181
|
+
text?: string;
|
|
182
|
+
style: LabelStyle;
|
|
183
|
+
/** Bubble / marker color. `undefined` → renderer default. */
|
|
184
|
+
color?: string;
|
|
185
|
+
textColor?: string;
|
|
186
|
+
size: BoxTextSize;
|
|
187
|
+
textAlign: BoxHAlign;
|
|
188
|
+
tooltip?: string;
|
|
189
|
+
fontFamily: BoxFontFamily;
|
|
190
|
+
/** na bubble/marker color → render text only (no bubble/shape fill). */
|
|
191
|
+
noFill?: boolean;
|
|
192
|
+
/** `force_overlay` → render on the price pane regardless of the indicator's pane. */
|
|
193
|
+
overlay?: boolean;
|
|
194
|
+
}
|
|
195
|
+
/** One vertex of a polyline (Pine `chart.point`). `x` follows `xloc`; `price` is y. */
|
|
196
|
+
interface PolylinePoint {
|
|
197
|
+
xloc: DrawingXLoc;
|
|
198
|
+
x: number;
|
|
199
|
+
price: number;
|
|
200
|
+
}
|
|
201
|
+
/** A Pine `polyline.new(...)` — a multi-point path, optionally curved and/or closed. */
|
|
202
|
+
interface DrawingPolyline {
|
|
203
|
+
id: string;
|
|
204
|
+
paneId: string;
|
|
205
|
+
points: PolylinePoint[];
|
|
206
|
+
curved: boolean;
|
|
207
|
+
closed: boolean;
|
|
208
|
+
/** Stroke color. `undefined` → no stroke. */
|
|
209
|
+
lineColor?: string;
|
|
210
|
+
/** Fill color (closed paths). `undefined` → no fill. */
|
|
211
|
+
fillColor?: string;
|
|
212
|
+
lineWidth: number;
|
|
213
|
+
lineStyle: LineStyle;
|
|
214
|
+
/** Arrowheads at segment starts/ends (`line.style_arrow_*`). */
|
|
215
|
+
arrowLeft: boolean;
|
|
216
|
+
arrowRight: boolean;
|
|
217
|
+
/** `force_overlay` → render on the price pane regardless of the indicator's pane. */
|
|
218
|
+
overlay?: boolean;
|
|
219
|
+
}
|
|
220
|
+
/** A Pine `linefill.new(line1, line2, color)` — the band between two lines. */
|
|
221
|
+
interface DrawingLinefill {
|
|
222
|
+
id: string;
|
|
223
|
+
paneId: string;
|
|
224
|
+
line1: DrawingLine;
|
|
225
|
+
line2: DrawingLine;
|
|
226
|
+
/** Fill color. `undefined` → nothing drawn. */
|
|
227
|
+
color?: string;
|
|
228
|
+
/** `force_overlay` → render on the price pane regardless of the indicator's pane. */
|
|
229
|
+
overlay?: boolean;
|
|
230
|
+
}
|
|
231
|
+
/** Pine `position.*` — which chart corner/edge a table anchors to. */
|
|
232
|
+
type TablePosition = 'top_left' | 'top_center' | 'top_right' | 'middle_left' | 'middle_center' | 'middle_right' | 'bottom_left' | 'bottom_center' | 'bottom_right';
|
|
233
|
+
/** One `table.cell(...)`. */
|
|
234
|
+
interface TableCell {
|
|
235
|
+
text?: string;
|
|
236
|
+
textColor?: string;
|
|
237
|
+
bgColor?: string;
|
|
238
|
+
hAlign: BoxHAlign;
|
|
239
|
+
vAlign: BoxVAlign;
|
|
240
|
+
textSize: BoxTextSize;
|
|
241
|
+
fontFamily: BoxFontFamily;
|
|
242
|
+
tooltip?: string;
|
|
243
|
+
bold: boolean;
|
|
244
|
+
italic: boolean;
|
|
245
|
+
/** A non-origin cell absorbed by a `table.merge_cells` region → not rendered. */
|
|
246
|
+
merged?: boolean;
|
|
247
|
+
}
|
|
248
|
+
/** A `table.merge_cells` region (inclusive, in column/row coordinates). */
|
|
249
|
+
interface TableMerge {
|
|
250
|
+
startCol: number;
|
|
251
|
+
startRow: number;
|
|
252
|
+
endCol: number;
|
|
253
|
+
endRow: number;
|
|
254
|
+
}
|
|
255
|
+
/** A Pine `table.new(...)` — a DOM-overlay grid anchored to a chart corner. */
|
|
256
|
+
interface DrawingTable {
|
|
257
|
+
id: string;
|
|
258
|
+
paneId: string;
|
|
259
|
+
position: TablePosition;
|
|
260
|
+
columns: number;
|
|
261
|
+
rows: number;
|
|
262
|
+
bgColor?: string;
|
|
263
|
+
frameColor?: string;
|
|
264
|
+
frameWidth: number;
|
|
265
|
+
borderColor?: string;
|
|
266
|
+
borderWidth: number;
|
|
267
|
+
/** Row-major: `cells[row][col]`; entries may be null (empty cell). */
|
|
268
|
+
cells: Array<Array<TableCell | null>>;
|
|
269
|
+
/** Merged-cell regions (`table.merge_cells`); origin spans, others are dropped. */
|
|
270
|
+
merges: TableMerge[];
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
type PaneKind = 'price' | 'study';
|
|
274
|
+
interface Pane {
|
|
275
|
+
id: string;
|
|
276
|
+
kind: PaneKind;
|
|
277
|
+
/** Display order, top-to-bottom; the price pane is conventionally order 0. */
|
|
278
|
+
order: number;
|
|
279
|
+
/** Relative height weight among panes (the renderer normalizes). */
|
|
280
|
+
heightWeight?: number;
|
|
281
|
+
title?: string;
|
|
282
|
+
}
|
|
283
|
+
/** One bar's vertical gradient stop for a gradient `fill()` (color@price). */
|
|
284
|
+
interface FillGradientStop {
|
|
285
|
+
topValue: number;
|
|
286
|
+
bottomValue: number;
|
|
287
|
+
topColor: string;
|
|
288
|
+
bottomColor: string;
|
|
289
|
+
}
|
|
290
|
+
/** A band fill between two value series (Pine `fill(plot1, plot2, ...)`). */
|
|
291
|
+
interface Fill {
|
|
292
|
+
id: string;
|
|
293
|
+
paneId: string;
|
|
294
|
+
/** RESOLVED series ids (the orchestrator resolves Pine plot refs to ids). */
|
|
295
|
+
fromSeriesId: string;
|
|
296
|
+
toSeriesId: string;
|
|
297
|
+
/** Flat band color (no per-bar variation). */
|
|
298
|
+
color?: string;
|
|
299
|
+
/** Per-bar solid color (conditional fills), aligned to the anchor points by index. */
|
|
300
|
+
colors?: Array<string | null>;
|
|
301
|
+
/** Per-bar vertical gradient (gradient-fill overload), aligned by index. */
|
|
302
|
+
gradient?: Array<FillGradientStop | null>;
|
|
303
|
+
}
|
|
304
|
+
/** A vertical background tint over a time span (Pine `bgcolor()` / session bands). */
|
|
305
|
+
interface Background {
|
|
306
|
+
id: string;
|
|
307
|
+
paneId: string;
|
|
308
|
+
/** Inclusive start, epoch ms. */
|
|
309
|
+
from: Millis;
|
|
310
|
+
/** Exclusive end, epoch ms. */
|
|
311
|
+
to: Millis;
|
|
312
|
+
color: string;
|
|
313
|
+
}
|
|
314
|
+
/** A horizontal price line (Pine `hline()`). */
|
|
315
|
+
interface PriceLine {
|
|
316
|
+
id: string;
|
|
317
|
+
paneId: string;
|
|
318
|
+
price: number;
|
|
319
|
+
color?: string;
|
|
320
|
+
lineStyle?: LineStyle;
|
|
321
|
+
width?: number;
|
|
322
|
+
title?: string;
|
|
323
|
+
}
|
|
324
|
+
/**
|
|
325
|
+
* The renderer-neutral, full description of what to draw. In the engine-owned
|
|
326
|
+
* design the orchestrator usually drives the renderer per-indicator
|
|
327
|
+
* (`mountIndicator`), but `Scene` is the conceptual aggregate the reconciler
|
|
328
|
+
* diffs against.
|
|
329
|
+
*/
|
|
330
|
+
interface Scene {
|
|
331
|
+
bars: OHLCV[];
|
|
332
|
+
panes: Pane[];
|
|
333
|
+
series: SeriesSpec[];
|
|
334
|
+
fills: Fill[];
|
|
335
|
+
backgrounds: Background[];
|
|
336
|
+
priceLines: PriceLine[];
|
|
337
|
+
lines?: DrawingLine[];
|
|
338
|
+
boxes?: DrawingBox[];
|
|
339
|
+
labels?: DrawingLabel[];
|
|
340
|
+
polylines?: DrawingPolyline[];
|
|
341
|
+
linefills?: DrawingLinefill[];
|
|
342
|
+
tables?: DrawingTable[];
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
/**
|
|
346
|
+
* One order execution of a strategy indicator — the unit painted on the chart as a
|
|
347
|
+
* trade marker (direction arrow + optional label/quantity text + a tick at the exact
|
|
348
|
+
* fill price). Executions anchor to their FILL bar and always render on the PRICE
|
|
349
|
+
* pane, whatever pane the indicator's plots landed on: a fill price only means
|
|
350
|
+
* something on the price scale.
|
|
351
|
+
*/
|
|
352
|
+
interface TradeExecution {
|
|
353
|
+
/** Fill bar (bar open time, epoch ms) — the bar the marker unit anchors to. */
|
|
354
|
+
time: Millis;
|
|
355
|
+
/** Exact fill price — anchors the price tick on the bar's edge. */
|
|
356
|
+
price: number;
|
|
357
|
+
/** A buy paints an up arrow below the bar; a sell a down arrow above it. */
|
|
358
|
+
side: 'buy' | 'sell';
|
|
359
|
+
/**
|
|
360
|
+
* Entries paint a plain arrow in the position side's entry color; exits paint a
|
|
361
|
+
* capped arrow (a bar between tip and price bar) in the shared exit color.
|
|
362
|
+
*/
|
|
363
|
+
kind: 'entry' | 'exit';
|
|
364
|
+
/** Text line next to the arrow — the order id, or its comment when one was given. */
|
|
365
|
+
label?: string;
|
|
366
|
+
/** Filled quantity (magnitude); painted signed (`+` for buys, `-` for sells). */
|
|
367
|
+
qty?: number;
|
|
368
|
+
/** Shared by the executions of one round-trip (an entry and its exits). */
|
|
369
|
+
tradeId?: string;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
/**
|
|
373
|
+
* Renderer-neutral indicator input schema — Vela's own shape, owned here so no
|
|
374
|
+
* scripting language's own input model leaks into core (each engine maps its
|
|
375
|
+
* declarations onto this at its boundary). Drives the renderer's settings dialog
|
|
376
|
+
* (the gear settings UI).
|
|
377
|
+
*/
|
|
378
|
+
type InputType = 'int' | 'float' | 'bool' | 'string' | 'source' | 'color' | 'price' | 'time' | 'session' | 'timeframe' | 'symbol' | 'text_area';
|
|
379
|
+
type InputValue = number | string | boolean;
|
|
380
|
+
/**
|
|
381
|
+
* Host-provided symbol picker for the settings dialog's `input.symbol` control. Called when the
|
|
382
|
+
* user activates the field: the host opens its own symbol-selection UI (e.g. the app's ticker
|
|
383
|
+
* menu) seeded with the `current` symbol, and reports the chosen one back through `onPick`. When
|
|
384
|
+
* no picker is wired, `input.symbol` falls back to a plain text field.
|
|
385
|
+
*/
|
|
386
|
+
type SymbolPickerFn = (current: string, onPick: (symbol: string) => void) => void;
|
|
387
|
+
interface InputSchema {
|
|
388
|
+
/** Stable key used by `setInput()` — the engine's own variable id, falling back to `title`. */
|
|
389
|
+
key: string;
|
|
390
|
+
/** Display label shown in the settings dialog. */
|
|
391
|
+
title: string;
|
|
392
|
+
type: InputType;
|
|
393
|
+
defval: InputValue;
|
|
394
|
+
min?: number;
|
|
395
|
+
max?: number;
|
|
396
|
+
step?: number;
|
|
397
|
+
/** Choices for a dropdown (`input.string(..., options=[...])`). */
|
|
398
|
+
options?: readonly string[];
|
|
399
|
+
/** Grouping label for the dialog layout. */
|
|
400
|
+
group?: string;
|
|
401
|
+
/** Inline grouping label (controls placed on one row). */
|
|
402
|
+
inline?: string;
|
|
403
|
+
tooltip?: string;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
/** Declaration metadata from the Pine `indicator()` / `strategy()` call. */
|
|
407
|
+
interface IndicatorMeta {
|
|
408
|
+
title: string;
|
|
409
|
+
shorttitle?: string;
|
|
410
|
+
overlay: boolean;
|
|
411
|
+
precision?: number;
|
|
412
|
+
format?: string;
|
|
413
|
+
}
|
|
414
|
+
/** Where an indicator's plots are placed. */
|
|
415
|
+
type PaneHint = 'price' | 'new';
|
|
416
|
+
/**
|
|
417
|
+
* Everything one `addIndicator()` produces — the unit the orchestrator mounts
|
|
418
|
+
* on the renderer. Renderer-neutral.
|
|
419
|
+
*/
|
|
420
|
+
interface IndicatorModel {
|
|
421
|
+
/** Per-instance id (stable). */
|
|
422
|
+
id: string;
|
|
423
|
+
title: string;
|
|
424
|
+
overlay: boolean;
|
|
425
|
+
paneHint: PaneHint;
|
|
426
|
+
/**
|
|
427
|
+
* Marks a NATIVE indicator (core-computed, no Pine engine) and its type (e.g. `'volume'`,
|
|
428
|
+
* `'volume'`). Absent ⇒ an ordinary Pine indicator. Drives native-only legend styling
|
|
429
|
+
* (distinct title color) + list ordering (native indicators pin to the top).
|
|
430
|
+
*/
|
|
431
|
+
native?: {
|
|
432
|
+
type: string;
|
|
433
|
+
};
|
|
434
|
+
/** Resolved pane id, filled in by the orchestrator after routing. */
|
|
435
|
+
paneId?: string;
|
|
436
|
+
/**
|
|
437
|
+
* When true, this indicator renders on its OWN price scale within its pane (a
|
|
438
|
+
* dedicated axis column to the right of the pane's scale), independent of the
|
|
439
|
+
* pane's master scale — set when the indicator is merged into a pane it does not
|
|
440
|
+
* own. Absent/false ⇒ it shares the pane's scale (the norm; script overlays like
|
|
441
|
+
* a moving average keep sharing the price scale).
|
|
442
|
+
*/
|
|
443
|
+
ownScale?: boolean;
|
|
444
|
+
/**
|
|
445
|
+
* Chart time (epoch ms) of the execution's FIRST bar. Index-aligned payloads —
|
|
446
|
+
* dense series point/bar arrays and `bar_index` drawing coordinates — count from
|
|
447
|
+
* this bar, so a renderer aligns them to the chart via the offset of this time in
|
|
448
|
+
* its bar array. Absent ⇒ the model spans the whole chart (offset 0, the norm);
|
|
449
|
+
* set by engines that ran over a SUFFIX of the bars (e.g. mid-backfill).
|
|
450
|
+
*/
|
|
451
|
+
anchorTime?: Millis;
|
|
452
|
+
series: SeriesSpec[];
|
|
453
|
+
fills: Fill[];
|
|
454
|
+
backgrounds: Background[];
|
|
455
|
+
priceLines: PriceLine[];
|
|
456
|
+
/** Pine `line.new(...)` drawings (optional; absent ≡ none). */
|
|
457
|
+
lines?: DrawingLine[];
|
|
458
|
+
/** Pine `box.new(...)` drawings (optional; absent ≡ none). */
|
|
459
|
+
boxes?: DrawingBox[];
|
|
460
|
+
/** Pine `label.new(...)` drawings (optional; absent ≡ none). */
|
|
461
|
+
labels?: DrawingLabel[];
|
|
462
|
+
/** Pine `polyline.new(...)` drawings (optional; absent ≡ none). */
|
|
463
|
+
polylines?: DrawingPolyline[];
|
|
464
|
+
/** Pine `linefill.new(...)` fills (optional; absent ≡ none). */
|
|
465
|
+
linefills?: DrawingLinefill[];
|
|
466
|
+
/** Pine `table.new(...)` DOM overlays (optional; absent ≡ none). */
|
|
467
|
+
tables?: DrawingTable[];
|
|
468
|
+
/** Pine `barcolor(...)` per-bar candle recolor (time→color; absent/empty ≡ none). */
|
|
469
|
+
barColors?: Array<{
|
|
470
|
+
time: Millis;
|
|
471
|
+
color: string;
|
|
472
|
+
}>;
|
|
473
|
+
/** Strategy order executions, painted as trade markers on the PRICE pane (optional; absent ≡ none). */
|
|
474
|
+
trades?: TradeExecution[];
|
|
475
|
+
/** Input schema parsed from the Pine source (drives the renderer's settings dialog). */
|
|
476
|
+
inputs: InputSchema[];
|
|
477
|
+
/** Current input values (defaults merged with any user/add-time overrides). */
|
|
478
|
+
inputValues: Record<string, InputValue>;
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
interface DirtyRange {
|
|
482
|
+
from: Millis;
|
|
483
|
+
to: Millis;
|
|
484
|
+
}
|
|
485
|
+
/** Per-series changed tail in a value patch. */
|
|
486
|
+
type SeriesValueDelta = {
|
|
487
|
+
seriesId: string;
|
|
488
|
+
kind: 'points';
|
|
489
|
+
points: SeriesPoint[];
|
|
490
|
+
} | {
|
|
491
|
+
seriesId: string;
|
|
492
|
+
kind: 'bars';
|
|
493
|
+
bars: OHLCV[];
|
|
494
|
+
} | {
|
|
495
|
+
seriesId: string;
|
|
496
|
+
kind: 'markers';
|
|
497
|
+
markers: MarkerPoint[];
|
|
498
|
+
};
|
|
499
|
+
/**
|
|
500
|
+
* Value-only update to existing series — legal as an in-place renderer update
|
|
501
|
+
* (the renderer chooses `update()` vs `setData(tail)` by time comparison).
|
|
502
|
+
*/
|
|
503
|
+
interface ValuePatch {
|
|
504
|
+
kind: 'value';
|
|
505
|
+
indicatorId: string;
|
|
506
|
+
dirty: DirtyRange;
|
|
507
|
+
/**
|
|
508
|
+
* The emitting run's anchor (see `IndicatorModel.anchorTime`): a re-run over a
|
|
509
|
+
* DIFFERENT bar window arrives as a value patch, so the anchor must travel with
|
|
510
|
+
* it for index-aligned rendering to re-derive its offset. `null` states the run
|
|
511
|
+
* spanned the WHOLE chart and clears any previous anchor — an omitted key cannot,
|
|
512
|
+
* so a model that once had an anchor would otherwise keep that stale offset.
|
|
513
|
+
*/
|
|
514
|
+
anchorTime?: Millis | null;
|
|
515
|
+
series: SeriesValueDelta[];
|
|
516
|
+
/**
|
|
517
|
+
* Full drawing snapshots for this tick. Pine drawing containers are emitted
|
|
518
|
+
* as a small, capped, already-final set each run, so live updates replace
|
|
519
|
+
* the whole set rather than diffing. Absent ≡ unchanged/none.
|
|
520
|
+
*/
|
|
521
|
+
lines?: DrawingLine[];
|
|
522
|
+
boxes?: DrawingBox[];
|
|
523
|
+
labels?: DrawingLabel[];
|
|
524
|
+
polylines?: DrawingPolyline[];
|
|
525
|
+
linefills?: DrawingLinefill[];
|
|
526
|
+
tables?: DrawingTable[];
|
|
527
|
+
/** Trade executions follow the same full-snapshot-per-tick pattern as the drawings. */
|
|
528
|
+
trades?: TradeExecution[];
|
|
529
|
+
}
|
|
530
|
+
/**
|
|
531
|
+
* Structural change — series added/removed/kind-changed, or panes changed.
|
|
532
|
+
* Forces a remount of the affected series (a series' kind is fixed at creation
|
|
533
|
+
* in most backends).
|
|
534
|
+
*/
|
|
535
|
+
interface SchemaPatch {
|
|
536
|
+
kind: 'schema';
|
|
537
|
+
indicatorId: string;
|
|
538
|
+
added: SeriesSpec[];
|
|
539
|
+
removed: string[];
|
|
540
|
+
changed: Array<{
|
|
541
|
+
seriesId: string;
|
|
542
|
+
reason: 'kind' | 'pane';
|
|
543
|
+
}>;
|
|
544
|
+
}
|
|
545
|
+
type ScenePatch = ValuePatch | SchemaPatch;
|
|
546
|
+
|
|
547
|
+
/** A function that detaches a previously-registered subscription. */
|
|
548
|
+
type Unsubscribe = () => void;
|
|
549
|
+
|
|
550
|
+
/**
|
|
551
|
+
* Geometry seam for user drawings. A drawing stores its anchors in DATA space
|
|
552
|
+
* ({@link DrawingPoint}); every pixel it needs is resolved on demand through a
|
|
553
|
+
* {@link Projector} the renderer supplies. The model never stores pixels, so a
|
|
554
|
+
* drawing survives reload, pan/zoom, bar-prepend, and timezone changes — the
|
|
555
|
+
* same invariant Pine drawings get from `xloc:'bar_time'`.
|
|
556
|
+
*/
|
|
557
|
+
/** A drawing anchor in DATA space (epoch-ms time + data-space price). */
|
|
558
|
+
interface DrawingPoint {
|
|
559
|
+
/** Epoch ms — resolved to a fractional logical bar index by the time scale. */
|
|
560
|
+
time: number;
|
|
561
|
+
/** Data-space price (not normalized, not pane-relative). */
|
|
562
|
+
price: number;
|
|
563
|
+
}
|
|
564
|
+
/** Axes a handle is free to move along — drives drag constraints + handle generation. */
|
|
565
|
+
type FreeAxis = 'both' | 'x' | 'y' | 'none';
|
|
566
|
+
/**
|
|
567
|
+
* Magnet (snap-to-candle) strength. `off` never snaps; `strong` always snaps the
|
|
568
|
+
* anchor to the nearest bar/OHLC; `weak` snaps only when the candle point is within
|
|
569
|
+
* a small pixel radius of the cursor (so you can place freely between candles).
|
|
570
|
+
* Holding Ctrl/Cmd is a momentary `strong` override regardless of the sticky mode.
|
|
571
|
+
*/
|
|
572
|
+
type SnapMode = 'off' | 'weak' | 'strong';
|
|
573
|
+
/**
|
|
574
|
+
* The renderer-supplied data→pixel transform. The native renderer builds it from
|
|
575
|
+
* its {@link CoordinateSystem} (`xOf = timeToX`, `yOf = priceToY` against the
|
|
576
|
+
* pane's live scale + bounds); any other renderer can build the same from its own
|
|
577
|
+
* coordinate closures. Defined in core so the model depends only on the interface.
|
|
578
|
+
*/
|
|
579
|
+
interface Projector {
|
|
580
|
+
/** Pixel x for an epoch-ms time (extrapolates past either edge). */
|
|
581
|
+
xOf(time: number): number;
|
|
582
|
+
/** Pixel y for a price on a pane; `null` when the pane is gone. */
|
|
583
|
+
yOf(price: number, paneId: string): number | null;
|
|
584
|
+
/** Inverse — pixel → data point on a pane (used on create/drag commit). */
|
|
585
|
+
pxToPoint(x: number, y: number, paneId: string): DrawingPoint;
|
|
586
|
+
/** Which pane owns a pixel y, or `null` outside every pane. */
|
|
587
|
+
paneIdAtY(y: number): string | null;
|
|
588
|
+
/**
|
|
589
|
+
* A pane's vertical pixel extent, or `null` when the pane is gone. `height` is 0 while
|
|
590
|
+
* the pane is hidden (collapsed to a legend strip, or zeroed by another pane's maximize) —
|
|
591
|
+
* painters clip each drawing to this rect so panes stay visually separated; optional.
|
|
592
|
+
*/
|
|
593
|
+
paneRect?(paneId: string): {
|
|
594
|
+
top: number;
|
|
595
|
+
height: number;
|
|
596
|
+
} | null;
|
|
597
|
+
/** Approximate whole bars between two times (for measurement labels); optional. */
|
|
598
|
+
barsBetween?(t1: number, t2: number): number;
|
|
599
|
+
/**
|
|
600
|
+
* OHLC(V) bars whose time falls within `[from, to]` (inclusive), in ascending time —
|
|
601
|
+
* the data a statistical drawing (e.g. a regression channel or anchored VWAP) fits
|
|
602
|
+
* against. `volume` is optional (some feeds omit it). Optional itself: renderers without
|
|
603
|
+
* series access (or with user-drawings disabled) may omit the method, and such drawings
|
|
604
|
+
* then degrade gracefully to an anchor-only fallback.
|
|
605
|
+
*/
|
|
606
|
+
barsInRange?(from: number, to: number): ReadonlyArray<{
|
|
607
|
+
time: number;
|
|
608
|
+
open: number;
|
|
609
|
+
high: number;
|
|
610
|
+
low: number;
|
|
611
|
+
close: number;
|
|
612
|
+
volume?: number;
|
|
613
|
+
}>;
|
|
614
|
+
/** Plot width in media px (excludes the right price-axis strip). */
|
|
615
|
+
readonly width: number;
|
|
616
|
+
/** Plot height in media px (excludes the bottom time-axis strip). */
|
|
617
|
+
readonly height: number;
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
/**
|
|
621
|
+
* The cosmetic payload shared by every drawing (the "settings" a user edits).
|
|
622
|
+
* Reuses the Pine {@link LineStyle} so dash patterns resolve through the same
|
|
623
|
+
* `dashPattern()` helper the renderer already uses.
|
|
624
|
+
*/
|
|
625
|
+
interface DrawingStyle {
|
|
626
|
+
lineColor: string;
|
|
627
|
+
lineWidth: number;
|
|
628
|
+
lineStyle: LineStyle;
|
|
629
|
+
/** Fill (box / closed path); `undefined` ⇒ no fill. */
|
|
630
|
+
fillColor?: string;
|
|
631
|
+
/** Fill opacity 0..1 (applied over `fillColor`). */
|
|
632
|
+
fillOpacity?: number;
|
|
633
|
+
arrowLeft?: boolean;
|
|
634
|
+
arrowRight?: boolean;
|
|
635
|
+
}
|
|
636
|
+
/** A drawing's editable text/annotation block. */
|
|
637
|
+
interface DrawingText {
|
|
638
|
+
value: string;
|
|
639
|
+
/** `undefined` ⇒ auto-contrast against the fill/background. */
|
|
640
|
+
color?: string;
|
|
641
|
+
size: 'tiny' | 'small' | 'normal' | 'large' | 'huge' | 'auto';
|
|
642
|
+
hAlign: 'left' | 'center' | 'right';
|
|
643
|
+
vAlign: 'top' | 'center' | 'bottom';
|
|
644
|
+
bold?: boolean;
|
|
645
|
+
italic?: boolean;
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
/**
|
|
649
|
+
* A data-driven settings schema. Each {@link SettingsField} names a dot-path into
|
|
650
|
+
* a drawing (`'style.lineColor'`, `'text.value'`) plus a control `kind`, so the
|
|
651
|
+
* renderer's settings popup builds controls generically — adding a new drawing
|
|
652
|
+
* type is a schema entry, not new UI code.
|
|
653
|
+
*/
|
|
654
|
+
type FieldKind = 'color' | 'number' | 'select' | 'lineStyle' | 'boolean' | 'text' | 'opacity';
|
|
655
|
+
interface SettingsField {
|
|
656
|
+
/** Dot-path into the drawing, e.g. `'style.lineColor'`, `'text.value'`, `'locked'`. */
|
|
657
|
+
path: string;
|
|
658
|
+
label: string;
|
|
659
|
+
kind: FieldKind;
|
|
660
|
+
/** number/opacity bounds. */
|
|
661
|
+
min?: number;
|
|
662
|
+
max?: number;
|
|
663
|
+
step?: number;
|
|
664
|
+
/** select options. */
|
|
665
|
+
options?: ReadonlyArray<{
|
|
666
|
+
value: string;
|
|
667
|
+
label: string;
|
|
668
|
+
}>;
|
|
669
|
+
/** Cosmetic grouping in the popup. */
|
|
670
|
+
group?: 'line' | 'fill' | 'text' | 'behavior';
|
|
671
|
+
}
|
|
672
|
+
interface SettingsSchema {
|
|
673
|
+
fields: SettingsField[];
|
|
674
|
+
/**
|
|
675
|
+
* The text **is** the drawing (a text label, a note, a callout) rather than an optional label on
|
|
676
|
+
* a shape. The settings popup then puts the text controls — color, size, bold, italic — on the
|
|
677
|
+
* bar itself instead of tucking them under the text field.
|
|
678
|
+
*/
|
|
679
|
+
textIsContent?: boolean;
|
|
680
|
+
}
|
|
681
|
+
|
|
682
|
+
/**
|
|
683
|
+
* The interactive user-drawing types. The lean-core set ships first; new types
|
|
684
|
+
* (fibs/patterns) extend the union + register a class — no base/port change.
|
|
685
|
+
*/
|
|
686
|
+
type DrawingTypeKey = 'trendline' | 'hline' | 'ray' | 'extendedline' | 'vline' | 'hray' | 'crossline' | 'infoline' | 'trendangle' | 'box' | 'text' | 'note' | 'pricenote' | 'comment' | 'pricelabel' | 'signpost' | 'parallelchannel' | 'disjointchannel' | 'flattopbottom' | 'regressionchannel' | 'anchoredvwap' | 'fixedrangevp' | 'pitchfork' | 'schiffpitchfork' | 'modifiedschiffpitchfork' | 'insidepitchfork' | 'arrow' | 'callout' | 'ellipse' | 'triangle' | 'polyline' | 'freehand' | 'highlighter' | 'circle' | 'rotatedrect' | 'path' | 'arc' | 'curve' | 'arrowmarkup' | 'arrowmarkdown' | 'flagmark' | 'iconstamp' | 'fibretracement' | 'fibextension' | 'fibextensiontrend' | 'fibfan' | 'fibtimezones' | 'fibchannel' | 'fibspeedfan' | 'trendfibtime' | 'fibcircles' | 'fibarcs' | 'fibwedge' | 'fibspiral' | 'gannfan' | 'gannbox' | 'gannsquare' | 'dedekind' | 'sonic' | 'supersonic' | 'goldensonic' | 'goldensupersonic' | 'datepricerange' | 'position' | 'xabcd' | 'abcd' | 'elliottimpulse' | 'elliottcorrection' | 'headshoulders' | 'gartley' | 'bat' | 'butterfly' | 'crab' | 'shark' | 'cypher';
|
|
687
|
+
/** One anchor's role + which axes its handle may move along. */
|
|
688
|
+
interface AnchorSlot {
|
|
689
|
+
role: string;
|
|
690
|
+
free: FreeAxis;
|
|
691
|
+
}
|
|
692
|
+
/**
|
|
693
|
+
* The plain-JSON shape of one drawing — the ONLY representation that crosses the
|
|
694
|
+
* renderer port and the persistence boundary. A {@link Drawing} (rich behavior)
|
|
695
|
+
* serializes to/from this; the renderer never sees a class instance.
|
|
696
|
+
*/
|
|
697
|
+
interface SerializedDrawing {
|
|
698
|
+
id: string;
|
|
699
|
+
type: DrawingTypeKey;
|
|
700
|
+
paneId: string;
|
|
701
|
+
/** time+price anchors — the single source of geometry truth. */
|
|
702
|
+
anchors: DrawingPoint[];
|
|
703
|
+
style: DrawingStyle;
|
|
704
|
+
text?: DrawingText;
|
|
705
|
+
locked: boolean;
|
|
706
|
+
visible: boolean;
|
|
707
|
+
/** Draw-order key. On a renderer with `drawingDepth` it shares ONE space with the pane's
|
|
708
|
+
* series — the candles and each indicator carry z keys of their own — so a drawing can sit
|
|
709
|
+
* anywhere in the stack, under the candles or between two indicators included. */
|
|
710
|
+
zIndex: number;
|
|
711
|
+
createdAt: number;
|
|
712
|
+
/** Per-type extras (e.g. box `extend`) — keeps the base closed. */
|
|
713
|
+
props?: Record<string, unknown>;
|
|
714
|
+
}
|
|
715
|
+
/**
|
|
716
|
+
* The parent of every user drawing. Owns the shared state + settings/serialization
|
|
717
|
+
* (the "everything inherits from a parent object" intent), and declares the
|
|
718
|
+
* geometry behaviors as PURE functions of `(anchors, Projector)` so the whole
|
|
719
|
+
* hierarchy stays renderer-neutral and serializable.
|
|
720
|
+
*/
|
|
721
|
+
declare abstract class Drawing {
|
|
722
|
+
readonly id: string;
|
|
723
|
+
abstract readonly type: DrawingTypeKey;
|
|
724
|
+
paneId: string;
|
|
725
|
+
/** DATA-space anchors (time+price). The only geometry the model stores. */
|
|
726
|
+
anchors: DrawingPoint[];
|
|
727
|
+
style: DrawingStyle;
|
|
728
|
+
text?: DrawingText;
|
|
729
|
+
locked: boolean;
|
|
730
|
+
visible: boolean;
|
|
731
|
+
zIndex: number;
|
|
732
|
+
readonly createdAt: number;
|
|
733
|
+
constructor(init: Partial<SerializedDrawing> & {
|
|
734
|
+
paneId: string;
|
|
735
|
+
});
|
|
736
|
+
/** Fallback id counter — used only when no id is supplied (store assigns real ids). */
|
|
737
|
+
private static seq;
|
|
738
|
+
abstract anchorSchema(): {
|
|
739
|
+
min: number;
|
|
740
|
+
max: number;
|
|
741
|
+
slots: AnchorSlot[];
|
|
742
|
+
};
|
|
743
|
+
/** True once enough anchors exist to be a real shape. */
|
|
744
|
+
isComplete(): boolean;
|
|
745
|
+
/**
|
|
746
|
+
* How the tool is placed: `'click'` (click each anchor; a variable-count tool —
|
|
747
|
+
* `max > min` — keeps adding until a finish gesture), `'drag'` (press at the first
|
|
748
|
+
* corner, drag, release at the second — the press-drag-release idiom for boxes/ranges/positions),
|
|
749
|
+
* or `'freehand'` (press, drag to capture a path, release). Drives the state machine.
|
|
750
|
+
*/
|
|
751
|
+
placementMode(): 'click' | 'drag' | 'freehand';
|
|
752
|
+
/**
|
|
753
|
+
* Hook run once after interactive placement finishes, before the `create` intent —
|
|
754
|
+
* lets a type finalize its anchors against the live projector (e.g. a position deriving
|
|
755
|
+
* its stop/target/width in pixel space so a bare click drops a default-sized box).
|
|
756
|
+
* Default: no-op.
|
|
757
|
+
*/
|
|
758
|
+
onPlaced(_proj: Projector): void;
|
|
759
|
+
/**
|
|
760
|
+
* After a single handle (anchor `index`) is dragged, re-impose any cross-anchor invariant —
|
|
761
|
+
* e.g. a position keeps its stop and target on opposite sides of the entry, flipping the
|
|
762
|
+
* non-dragged side across the entry when a drag would put them on the same side. Default: no-op.
|
|
763
|
+
*/
|
|
764
|
+
constrainHandleDrag(_index: number): void;
|
|
765
|
+
/**
|
|
766
|
+
* Apply a whole-body drag — translate the original anchors by (dt, dp) in data space.
|
|
767
|
+
* Default moves every anchor together; a type can pin some (e.g. a callout keeps its
|
|
768
|
+
* pointer tip fixed and moves only the box).
|
|
769
|
+
*/
|
|
770
|
+
translateBody(dt: number, dp: number, orig: DrawingPoint[]): DrawingPoint[];
|
|
771
|
+
/** Is the pixel (px,py) on this drawing's body, within `tol` px? */
|
|
772
|
+
abstract hitTest(px: number, py: number, proj: Projector, tol: number): boolean;
|
|
773
|
+
/** Index of the grabbed handle, or -1 for the body. */
|
|
774
|
+
abstract hitHandle(px: number, py: number, proj: Projector, tol: number): number;
|
|
775
|
+
/** Pixel positions of the draggable handles (for painting + hit-test). */
|
|
776
|
+
abstract handlePoints(proj: Projector): Array<[number, number]>;
|
|
777
|
+
/** Tight pixel bounds (selection box), or null when unresolvable. */
|
|
778
|
+
abstract bounds(proj: Projector): {
|
|
779
|
+
x: number;
|
|
780
|
+
y: number;
|
|
781
|
+
w: number;
|
|
782
|
+
h: number;
|
|
783
|
+
} | null;
|
|
784
|
+
/** Visible price span on its pane — folded into autoscale. */
|
|
785
|
+
abstract priceRange(): {
|
|
786
|
+
min: number;
|
|
787
|
+
max: number;
|
|
788
|
+
} | null;
|
|
789
|
+
/**
|
|
790
|
+
* Time span (epoch ms) the drawing occupies, for visible-range culling. Default
|
|
791
|
+
* is the anchor extent; a full-width drawing (e.g. a horizontal line) overrides
|
|
792
|
+
* to `null` meaning "all time" so it never culls.
|
|
793
|
+
*/
|
|
794
|
+
timeExtent(): {
|
|
795
|
+
min: number;
|
|
796
|
+
max: number;
|
|
797
|
+
} | null;
|
|
798
|
+
abstract schema(): SettingsSchema;
|
|
799
|
+
/**
|
|
800
|
+
* Editable per-level config for a rich "gear" settings panel (Fibonacci levels):
|
|
801
|
+
* each entry's `color` / `enabled` / `label` is mutated via a `levels.<i>.<field>`
|
|
802
|
+
* settings path. Simple drawings return null (no gear).
|
|
803
|
+
*/
|
|
804
|
+
editableLevels(): Array<{
|
|
805
|
+
ratio: number;
|
|
806
|
+
color: string;
|
|
807
|
+
enabled: boolean;
|
|
808
|
+
label?: string;
|
|
809
|
+
}> | null;
|
|
810
|
+
/** Apply a `{ 'dot.path': value }` patch (the popup emits these). */
|
|
811
|
+
applySettings(patch: Record<string, unknown>): void;
|
|
812
|
+
/** Re-read per-type extras (props) onto this instance — used by the store on an edit. */
|
|
813
|
+
applyProps(props: Record<string, unknown>): void;
|
|
814
|
+
serialize(): SerializedDrawing;
|
|
815
|
+
/** Per-type extras to serialize into `props` (override in subclasses). */
|
|
816
|
+
protected writeProps(): Record<string, unknown> | undefined;
|
|
817
|
+
/** Read per-type extras from a `props` bag (override in subclasses). */
|
|
818
|
+
protected readProps(_props: Record<string, unknown>): void;
|
|
819
|
+
}
|
|
820
|
+
|
|
821
|
+
/**
|
|
822
|
+
* Inert, renderer-neutral toolbar data. The core builds it from the type registry;
|
|
823
|
+
* the renderer paints a vertical bar where each {@link ToolGroup} is one button with
|
|
824
|
+
* a flyout listing its {@link ToolDefinition}s. One tool is armed
|
|
825
|
+
* at a time across all groups.
|
|
826
|
+
*/
|
|
827
|
+
interface ToolDefinition {
|
|
828
|
+
type: DrawingTypeKey;
|
|
829
|
+
label: string;
|
|
830
|
+
/** Inline SVG markup (no DOM). */
|
|
831
|
+
icon: string;
|
|
832
|
+
}
|
|
833
|
+
/** A labelled subsection inside a toolbar group's flyout (e.g. "Fibonacci" within Fibonacci & Gann). */
|
|
834
|
+
interface ToolSection {
|
|
835
|
+
label: string;
|
|
836
|
+
tools: ToolDefinition[];
|
|
837
|
+
}
|
|
838
|
+
interface ToolGroup {
|
|
839
|
+
id: string;
|
|
840
|
+
label: string;
|
|
841
|
+
tools: ToolDefinition[];
|
|
842
|
+
/** When set, the flyout renders non-clickable headers between sections. */
|
|
843
|
+
sections?: ToolSection[];
|
|
844
|
+
}
|
|
845
|
+
interface ToolbarDefinition {
|
|
846
|
+
groups: ToolGroup[];
|
|
847
|
+
}
|
|
848
|
+
/** A developer-supplied explicit group (just type keys; the registry fills the rest). */
|
|
849
|
+
interface ToolbarGroupConfig {
|
|
850
|
+
id: string;
|
|
851
|
+
label: string;
|
|
852
|
+
tools: DrawingTypeKey[];
|
|
853
|
+
}
|
|
854
|
+
/** Public `options.drawings` shape. `true` = default toolbar; object = customize. */
|
|
855
|
+
type DrawingsOption = boolean | {
|
|
856
|
+
toolbar?: boolean;
|
|
857
|
+
tools?: DrawingTypeKey[];
|
|
858
|
+
groups?: ToolbarGroupConfig[];
|
|
859
|
+
};
|
|
860
|
+
/** The default toolbar — every registered type, grouped into the canonical seven-button layout. */
|
|
861
|
+
declare function defaultToolbar(): ToolbarDefinition;
|
|
862
|
+
/**
|
|
863
|
+
* Resolve `options.drawings` into a concrete toolbar definition + initial visibility.
|
|
864
|
+
* Default (undefined) ⇒ toolbar VISIBLE; `false` ⇒ subsystem available but toolbar hidden
|
|
865
|
+
* (headless use still works via `chart.drawings.add(...)`); object ⇒ `toolbar ?? true`.
|
|
866
|
+
*/
|
|
867
|
+
declare function buildToolbar(option: DrawingsOption | undefined): {
|
|
868
|
+
definition: ToolbarDefinition;
|
|
869
|
+
visible: boolean;
|
|
870
|
+
};
|
|
871
|
+
|
|
872
|
+
/**
|
|
873
|
+
* The renderer-local drawing MODES beyond an armed tool: the transient measure ruler,
|
|
874
|
+
* the eraser, or none. Mutually exclusive with each other and with any armed tool —
|
|
875
|
+
* the renderer owns that exclusion; the core mirrors the outcome (see the `mode`
|
|
876
|
+
* intent) so external UIs (a shared workspace toolbar) can reflect and drive it.
|
|
877
|
+
*/
|
|
878
|
+
type DrawingMode = 'measure' | 'eraser' | null;
|
|
879
|
+
/**
|
|
880
|
+
* Renderer→core INTENT. The renderer proposes a change from a user gesture; the
|
|
881
|
+
* core {@link DrawingController} decides, mutates the store (the source of truth),
|
|
882
|
+
* re-syncs, and emits a `drawing:*` event. A single discriminated union (vs one
|
|
883
|
+
* callback per kind) because every arm routes to the same destination.
|
|
884
|
+
*/
|
|
885
|
+
type DrawingIntent = {
|
|
886
|
+
kind: 'arm';
|
|
887
|
+
type: DrawingTypeKey | null;
|
|
888
|
+
} | {
|
|
889
|
+
kind: 'create';
|
|
890
|
+
doc: SerializedDrawing;
|
|
891
|
+
} | {
|
|
892
|
+
kind: 'edit';
|
|
893
|
+
doc: SerializedDrawing;
|
|
894
|
+
} | {
|
|
895
|
+
kind: 'edit-many';
|
|
896
|
+
docs: SerializedDrawing[];
|
|
897
|
+
} | {
|
|
898
|
+
kind: 'select';
|
|
899
|
+
ids: string[];
|
|
900
|
+
additive?: boolean;
|
|
901
|
+
} | {
|
|
902
|
+
kind: 'delete';
|
|
903
|
+
ids: string[];
|
|
904
|
+
} | {
|
|
905
|
+
kind: 'reorder';
|
|
906
|
+
id: string;
|
|
907
|
+
to: 'front' | 'back';
|
|
908
|
+
} | {
|
|
909
|
+
kind: 'settings';
|
|
910
|
+
id: string;
|
|
911
|
+
} | {
|
|
912
|
+
kind: 'tool-finished';
|
|
913
|
+
type: DrawingTypeKey;
|
|
914
|
+
} | {
|
|
915
|
+
kind: 'favorite';
|
|
916
|
+
type: DrawingTypeKey;
|
|
917
|
+
on: boolean;
|
|
918
|
+
} | {
|
|
919
|
+
kind: 'snap-mode';
|
|
920
|
+
mode: SnapMode;
|
|
921
|
+
}
|
|
922
|
+
/** Stay-in-drawing-mode toggled in-chart — when on, finishing a drawing leaves the
|
|
923
|
+
* tool armed instead of reverting to the pointer. */
|
|
924
|
+
| {
|
|
925
|
+
kind: 'stay-mode';
|
|
926
|
+
on: boolean;
|
|
927
|
+
} | {
|
|
928
|
+
kind: 'mode';
|
|
929
|
+
mode: DrawingMode;
|
|
930
|
+
} | {
|
|
931
|
+
kind: 'undo';
|
|
932
|
+
} | {
|
|
933
|
+
kind: 'redo';
|
|
934
|
+
} | {
|
|
935
|
+
kind: 'duplicate';
|
|
936
|
+
ids: string[];
|
|
937
|
+
} | {
|
|
938
|
+
kind: 'copy';
|
|
939
|
+
ids: string[];
|
|
940
|
+
} | {
|
|
941
|
+
kind: 'paste';
|
|
942
|
+
};
|
|
943
|
+
/**
|
|
944
|
+
* The interactive user-drawings surface a renderer optionally implements. Present
|
|
945
|
+
* iff `capabilities.userDrawings`. Commands flow down; one intent channel flows up.
|
|
946
|
+
* Only plain {@link SerializedDrawing}/{@link ToolbarDefinition} data crosses — no
|
|
947
|
+
* backend types, mirroring the rest of {@link IChartRenderer}.
|
|
948
|
+
*/
|
|
949
|
+
interface IDrawingsRendererPort {
|
|
950
|
+
/** Hand the renderer the inert toolbar definition to RENDER (groups/tools/icons). */
|
|
951
|
+
setToolbar(def: ToolbarDefinition): void;
|
|
952
|
+
/** Show or hide the on-chart drawing toolbar. */
|
|
953
|
+
showToolbar(visible: boolean): void;
|
|
954
|
+
/** Push the authoritative snapshot down; the renderer re-projects + repaints. */
|
|
955
|
+
syncDrawings(docs: readonly SerializedDrawing[]): void;
|
|
956
|
+
/** Arm/disarm a tool (`null` = selection/idle, pan resumes). `lastStyle` is the
|
|
957
|
+
* tool's last-used style (if any) so the placement preview matches what will be
|
|
958
|
+
* committed, rather than falling back to the type default. */
|
|
959
|
+
setActiveTool(type: DrawingTypeKey | null, lastStyle?: SerializedDrawing['style']): void;
|
|
960
|
+
/** Reflect which drawings are selected (drives handle painting); `[]` = none. */
|
|
961
|
+
setSelection(ids: readonly string[]): void;
|
|
962
|
+
/** Push the FAVORITE tool set (flyout stars + any favorites-driven UI). Optional —
|
|
963
|
+
* favorites still work headless without a renderer reflection. */
|
|
964
|
+
setFavorites?(types: readonly DrawingTypeKey[]): void;
|
|
965
|
+
/** Push per-tool shortcut hints — PRE-FORMATTED display strings (e.g. `'Alt+T'`)
|
|
966
|
+
* shown beside the tools in the toolbar flyouts. The host owns the keymap and the
|
|
967
|
+
* platform formatting; the renderer only displays. Optional. */
|
|
968
|
+
setToolShortcuts?(map: Readonly<Partial<Record<DrawingTypeKey, string>>>): void;
|
|
969
|
+
/** Set the sticky magnet snap mode (off/weak/strong). Optional — a renderer without
|
|
970
|
+
* a magnet omits it; the in-chart toolbar reflects the pushed value. */
|
|
971
|
+
setSnapMode?(mode: SnapMode): void;
|
|
972
|
+
/** Set stay-in-drawing-mode (tools remain armed after each placement). Optional —
|
|
973
|
+
* the in-chart toolbar reflects the pushed value. */
|
|
974
|
+
setStayMode?(on: boolean): void;
|
|
975
|
+
/** Enter/exit a renderer-local mode (measure ruler / eraser; `null` exits). The
|
|
976
|
+
* renderer keeps owning the mutual exclusion (with armed tools too) and reports
|
|
977
|
+
* every actual change back through the `mode` intent. Optional. */
|
|
978
|
+
setMode?(mode: DrawingMode): void;
|
|
979
|
+
/** Open a drawing's settings popup (selecting it too) — the programmatic twin of a click on it. */
|
|
980
|
+
openSettings(id: string): void;
|
|
981
|
+
/**
|
|
982
|
+
* The pane's SERIES stack in z terms, for renderers whose drawings share one draw-order
|
|
983
|
+
* space with the series (`drawingDepth`): the extremes ("bring to front" beats `front`,
|
|
984
|
+
* "send to back" undercuts `back`) and the candles' own key (`price`, absent on a study
|
|
985
|
+
* pane) — a new drawing starts just under it. Optional — without it drawings order only
|
|
986
|
+
* among themselves, on a layer of their own.
|
|
987
|
+
*/
|
|
988
|
+
stackRange?(paneId: string): {
|
|
989
|
+
front: number;
|
|
990
|
+
back: number;
|
|
991
|
+
price?: number;
|
|
992
|
+
};
|
|
993
|
+
/** The one channel up — create/edit/select/delete/settings/tool-finished. */
|
|
994
|
+
onDrawingIntent(cb: (intent: DrawingIntent) => void): Unsubscribe;
|
|
995
|
+
}
|
|
996
|
+
|
|
997
|
+
/** What a rendering backend supports — drives graceful degradation + warnings. */
|
|
998
|
+
interface RendererCapabilities {
|
|
999
|
+
panes: boolean;
|
|
1000
|
+
/**
|
|
1001
|
+
* Full pane management: moving/merging an indicator between panes (with its own
|
|
1002
|
+
* scale column), reordering panes, and pane collapse/maximize. A renderer without
|
|
1003
|
+
* it keeps one-pane-per-indicator behavior; `chart.panes` mutations warn + no-op.
|
|
1004
|
+
*/
|
|
1005
|
+
paneManagement: boolean;
|
|
1006
|
+
fills: 'native' | 'primitive' | 'unsupported';
|
|
1007
|
+
bgcolor: 'native' | 'primitive' | 'unsupported';
|
|
1008
|
+
hline: 'native' | 'primitive' | 'unsupported';
|
|
1009
|
+
markers: boolean;
|
|
1010
|
+
barcolor: 'native' | 'approximated' | 'unsupported';
|
|
1011
|
+
perPointColor: boolean;
|
|
1012
|
+
/** Pine drawing objects (line/box/label/polyline/linefill) via custom primitives. */
|
|
1013
|
+
drawings: boolean;
|
|
1014
|
+
/** Interactive USER drawing tools (toolbar + hit-test + handles). Distinct from `drawings`. */
|
|
1015
|
+
userDrawings: boolean;
|
|
1016
|
+
/** Whether user drawings share ONE draw-order space with the pane's series — a drawing's
|
|
1017
|
+
* `zIndex` then places it anywhere in the stack: over everything, under the candles, or
|
|
1018
|
+
* between two indicators. Absent/false: every drawing paints in front, `zIndex` orders
|
|
1019
|
+
* only the drawings among themselves, and a host UI should not offer depth slots. */
|
|
1020
|
+
drawingDepth?: boolean;
|
|
1021
|
+
/** Pine `table.new` dashboards via a DOM overlay. */
|
|
1022
|
+
tables: boolean;
|
|
1023
|
+
/** Strategy trade markers (`IndicatorModel.trades`): order-fill arrows + labels + price
|
|
1024
|
+
* ticks on the price pane, plus the `tradeMarkers` display feature. Absent/false ⇒ the
|
|
1025
|
+
* channel is carried through mounts/patches but never painted. */
|
|
1026
|
+
trades?: boolean;
|
|
1027
|
+
/** Whether the renderer provides the in-chart inputs/settings UI. */
|
|
1028
|
+
inputsUI: boolean;
|
|
1029
|
+
}
|
|
1030
|
+
/** Opaque handle to a mounted indicator, returned by `mountIndicator()`. */
|
|
1031
|
+
interface IndicatorRenderHandle {
|
|
1032
|
+
readonly id: string;
|
|
1033
|
+
}
|
|
1034
|
+
/** An indicator's live status, shown in its legend row. */
|
|
1035
|
+
type IndicatorStatus = 'idle' | 'loading' | 'live';
|
|
1036
|
+
/**
|
|
1037
|
+
* One host-contributed legend-row action, as the renderer consumes it: pure data plus a
|
|
1038
|
+
* thunk. The shell resolves the plugin descriptor (its `when` gate, the context, the
|
|
1039
|
+
* indicator info) BEFORE it reaches the renderer, so the renderer stays ignorant of the
|
|
1040
|
+
* plugin layer — it just paints an icon button and calls `run` on click.
|
|
1041
|
+
*/
|
|
1042
|
+
interface LegendActionView {
|
|
1043
|
+
id: string;
|
|
1044
|
+
/** Icon id in the core icon registry (`registerIcon`). */
|
|
1045
|
+
icon: string;
|
|
1046
|
+
tooltip: string;
|
|
1047
|
+
run(): void;
|
|
1048
|
+
}
|
|
1049
|
+
/** OHLCV of the price bar under the crosshair (the "data window" source). */
|
|
1050
|
+
interface CrosshairOHLC {
|
|
1051
|
+
time: Millis;
|
|
1052
|
+
open: number;
|
|
1053
|
+
high: number;
|
|
1054
|
+
low: number;
|
|
1055
|
+
close: number;
|
|
1056
|
+
volume?: number;
|
|
1057
|
+
}
|
|
1058
|
+
interface CrosshairEvent {
|
|
1059
|
+
time: Millis | null;
|
|
1060
|
+
price: number | null;
|
|
1061
|
+
/** Value at the crosshair per series, keyed by stable series id. */
|
|
1062
|
+
values: ReadonlyMap<string, number>;
|
|
1063
|
+
/** The hovered price bar's OHLCV (null when the cursor is off any bar). */
|
|
1064
|
+
ohlc: CrosshairOHLC | null;
|
|
1065
|
+
}
|
|
1066
|
+
interface ClickEvent {
|
|
1067
|
+
time: Millis | null;
|
|
1068
|
+
price: number | null;
|
|
1069
|
+
}
|
|
1070
|
+
/** One indicator plot's readout line in the data window. */
|
|
1071
|
+
interface DataWindowRow {
|
|
1072
|
+
label: string;
|
|
1073
|
+
value: string;
|
|
1074
|
+
color: string;
|
|
1075
|
+
}
|
|
1076
|
+
/** The OHLCV block of a data-window readout, formatted on the price pane's scale. */
|
|
1077
|
+
interface DataWindowOHLC {
|
|
1078
|
+
o: string;
|
|
1079
|
+
h: string;
|
|
1080
|
+
l: string;
|
|
1081
|
+
c: string;
|
|
1082
|
+
vol?: string;
|
|
1083
|
+
/** Close ≥ open → tint the values with the up color, else the down color. */
|
|
1084
|
+
up: boolean;
|
|
1085
|
+
}
|
|
1086
|
+
/** One indicator's readout: its title plus a row per plot. */
|
|
1087
|
+
interface DataWindowGroup {
|
|
1088
|
+
name: string;
|
|
1089
|
+
rows: DataWindowRow[];
|
|
1090
|
+
}
|
|
1091
|
+
/**
|
|
1092
|
+
* A data-window snapshot — the bar's timestamp split into date + time, its OHLCV, and one
|
|
1093
|
+
* group per indicator. Every value arrives pre-formatted on the scale of the pane it belongs
|
|
1094
|
+
* to, so a host panel lays the readout out without doing any numeric formatting itself.
|
|
1095
|
+
*/
|
|
1096
|
+
interface DataWindowReadout {
|
|
1097
|
+
/** Bar date, pre-formatted (e.g. `2026-07-03`); empty when there is no bar. */
|
|
1098
|
+
date: string;
|
|
1099
|
+
/** Bar time of day, pre-formatted `HH:MM`; empty when there is no bar. */
|
|
1100
|
+
time: string;
|
|
1101
|
+
ohlc: DataWindowOHLC | null;
|
|
1102
|
+
groups: DataWindowGroup[];
|
|
1103
|
+
}
|
|
1104
|
+
/** Raised by the renderer when the user edits an input in the settings dialog. */
|
|
1105
|
+
interface InputChangeEvent {
|
|
1106
|
+
indicatorId: string;
|
|
1107
|
+
key: string;
|
|
1108
|
+
value: InputValue;
|
|
1109
|
+
}
|
|
1110
|
+
interface VisibleRange {
|
|
1111
|
+
from: Millis;
|
|
1112
|
+
to: Millis;
|
|
1113
|
+
}
|
|
1114
|
+
/** A user-initiated pane action reported by the renderer (hover buttons / double-clicks). */
|
|
1115
|
+
type PaneAction = {
|
|
1116
|
+
type: 'move';
|
|
1117
|
+
paneId: string;
|
|
1118
|
+
dir: 'up' | 'down';
|
|
1119
|
+
} | {
|
|
1120
|
+
type: 'remove';
|
|
1121
|
+
paneId: string;
|
|
1122
|
+
} | {
|
|
1123
|
+
type: 'collapse';
|
|
1124
|
+
paneId: string;
|
|
1125
|
+
collapsed: boolean;
|
|
1126
|
+
} | {
|
|
1127
|
+
type: 'maximize';
|
|
1128
|
+
paneId: string;
|
|
1129
|
+
maximized: boolean;
|
|
1130
|
+
};
|
|
1131
|
+
/**
|
|
1132
|
+
* The rendering backend abstraction. No backend (e.g. lightweight-charts) types
|
|
1133
|
+
* cross this boundary — that is what makes the renderer swappable. The only MVP
|
|
1134
|
+
* implementation is `src/renderers/lightweight-charts/LwcRenderer.ts`.
|
|
1135
|
+
*/
|
|
1136
|
+
interface IChartRenderer {
|
|
1137
|
+
readonly capabilities: RendererCapabilities;
|
|
1138
|
+
/** Stable identity of this renderer (e.g. `'native'`, `'lwc'`) — the warn label and `chart.renderer.name`. */
|
|
1139
|
+
readonly name: string;
|
|
1140
|
+
/** Feature keys this renderer can get/set at runtime via `chart.renderer.set` / `.get`. */
|
|
1141
|
+
readonly features: readonly string[];
|
|
1142
|
+
/** Apply a supported feature live (the caller has already checked `features`); repaints as needed. */
|
|
1143
|
+
applyFeature(key: string, value: unknown): void;
|
|
1144
|
+
/** Read a feature's current value (`undefined` if unsupported). */
|
|
1145
|
+
readFeature(key: string): unknown;
|
|
1146
|
+
mount(container: HTMLElement, theme: VelaTheme): void;
|
|
1147
|
+
setTheme(theme: VelaTheme): void;
|
|
1148
|
+
resize(): void;
|
|
1149
|
+
destroy(): void;
|
|
1150
|
+
/**
|
|
1151
|
+
* Replace all price bars. By default re-frames the view (a fresh series). Pass
|
|
1152
|
+
* `{ preserveView: true }` to keep the current viewport — used when extending the
|
|
1153
|
+
* same series in place (e.g. swapping a quick preview for the full history) so
|
|
1154
|
+
* candles don't jump.
|
|
1155
|
+
*/
|
|
1156
|
+
setBars(bars: OHLCV[], opts?: {
|
|
1157
|
+
preserveView?: boolean;
|
|
1158
|
+
}): void;
|
|
1159
|
+
/** Append a new bar or replace the forming (last) bar, decided by time. */
|
|
1160
|
+
updateBar(bar: OHLCV): void;
|
|
1161
|
+
/**
|
|
1162
|
+
* Set the active symbol's tick size (e.g. `0.01`) so the price axis renders the
|
|
1163
|
+
* instrument's true precision. Passed as soon as symbol metadata resolves; `undefined`
|
|
1164
|
+
* (or absent) ⇒ the renderer falls back to its zoom-derived decimals. Optional.
|
|
1165
|
+
*/
|
|
1166
|
+
setPricePrecision?(mintick: number | undefined): void;
|
|
1167
|
+
/**
|
|
1168
|
+
* Push a bespoke NATIVE-LAYER render payload, keyed by layer `type`. Visuals that aren't
|
|
1169
|
+
* ordinary series/fills draw through a dedicated renderer layer instead of the model; this is
|
|
1170
|
+
* the channel. Producers are native indicators (`'volume'`, `'vpvr'` — layer config) and core
|
|
1171
|
+
* data engines behind a price style (a plugin chart type pushing per-bar secondary data
|
|
1172
|
+
* through its own channel). Optional: a renderer without the
|
|
1173
|
+
* layers omits it.
|
|
1174
|
+
*/
|
|
1175
|
+
setNativeData?(type: string, data: unknown): void;
|
|
1176
|
+
/**
|
|
1177
|
+
* Reflect an indicator's live status in its legend row: `'loading'` (a fetch is in flight —
|
|
1178
|
+
* spinner), `'live'` (live-updating — a distinct pulse), or `'idle'` (nothing). Optional.
|
|
1179
|
+
*/
|
|
1180
|
+
setIndicatorStatus?(handle: IndicatorRenderHandle, status: IndicatorStatus): void;
|
|
1181
|
+
/**
|
|
1182
|
+
* A market load is in flight with NO bars painted yet — the first load, or a
|
|
1183
|
+
* symbol/timeframe switch (the host clears the old series first). Renderers may show a
|
|
1184
|
+
* subtle loading affordance, and must hide any content that does NOT ride the bar series
|
|
1185
|
+
* (corner-anchored tables); bar-mapped content vanishes with the cleared series on its
|
|
1186
|
+
* own. The host turns the flag off with the first series it hands over (or when a load
|
|
1187
|
+
* fails or parks) — the core also mirrors this state to plugins as `load:start`/`load:end`.
|
|
1188
|
+
* Optional.
|
|
1189
|
+
*/
|
|
1190
|
+
setLoading?(loading: boolean): void;
|
|
1191
|
+
ensurePane(pane: Pane): void;
|
|
1192
|
+
removePane(id: string): void;
|
|
1193
|
+
/**
|
|
1194
|
+
* Move a mounted indicator to another pane (merge/unmerge). `ownScale` gives the
|
|
1195
|
+
* indicator its own scale column within the target pane, rescaled so its visible
|
|
1196
|
+
* extent lines up with the pane's; omitted/false shares the pane scale. Present iff
|
|
1197
|
+
* `capabilities.paneManagement`.
|
|
1198
|
+
*/
|
|
1199
|
+
setIndicatorPane?(handle: IndicatorRenderHandle, paneId: string, opts?: {
|
|
1200
|
+
ownScale?: boolean;
|
|
1201
|
+
}): void;
|
|
1202
|
+
/** Set the top-to-bottom pane display order (an array of pane ids). */
|
|
1203
|
+
orderPanes?(orderedIds: string[]): void;
|
|
1204
|
+
/** Collapse a pane to a thin strip (legend + expand button) or restore it. */
|
|
1205
|
+
setPaneCollapsed?(paneId: string, collapsed: boolean): void;
|
|
1206
|
+
/** Maximize one pane to fill the plot, or restore the previous split (`null`). */
|
|
1207
|
+
setPaneMaximized?(paneId: string | null): void;
|
|
1208
|
+
/**
|
|
1209
|
+
* The renderer reports a user-initiated pane action (from a pane hover button or a
|
|
1210
|
+
* double-click). The host/core reflects it: `'remove'` tears down the pane's
|
|
1211
|
+
* indicators; the rest are already applied by the renderer and just keep core's
|
|
1212
|
+
* `chart.panes` view in sync. Present iff `capabilities.paneManagement`.
|
|
1213
|
+
*/
|
|
1214
|
+
onPaneAction?(cb: (action: PaneAction) => void): Unsubscribe;
|
|
1215
|
+
/**
|
|
1216
|
+
* The renderer reports a user request to move/merge an indicator to another pane, made
|
|
1217
|
+
* from its own in-chart UI (the legend "Move to" menu or a legend-row drag). Core routes
|
|
1218
|
+
* it through `moveIndicator`. Present iff `capabilities.paneManagement`.
|
|
1219
|
+
*/
|
|
1220
|
+
onMoveIndicator?(cb: (id: string, target: MoveTarget) => void): Unsubscribe;
|
|
1221
|
+
/** Mount an indicator's series + its in-chart legend/settings UI. */
|
|
1222
|
+
mountIndicator(model: IndicatorModel): IndicatorRenderHandle;
|
|
1223
|
+
updateIndicator(handle: IndicatorRenderHandle, patch: ScenePatch): void;
|
|
1224
|
+
removeIndicator(handle: IndicatorRenderHandle): void;
|
|
1225
|
+
/** Reflect a programmatic input change in the renderer's settings UI. */
|
|
1226
|
+
setIndicatorInputs(handle: IndicatorRenderHandle, values: Record<string, InputValue>): void;
|
|
1227
|
+
/**
|
|
1228
|
+
* Supply a symbol picker so the settings dialog's `input.symbol` control opens the host's own
|
|
1229
|
+
* ticker-selection UI (the host wires this). Optional — without it, `input.symbol` is a plain
|
|
1230
|
+
* text field. Pass `null` to detach.
|
|
1231
|
+
*/
|
|
1232
|
+
setSymbolPicker?(picker: SymbolPickerFn | null): void;
|
|
1233
|
+
/**
|
|
1234
|
+
* Supply the HOST-CONTRIBUTED actions of each legend row (the shells wire the plugin
|
|
1235
|
+
* registry through this — see `registerLegendAction`). The provider is called per row,
|
|
1236
|
+
* lazily, so `when()` gates and late registrations resolve at render time; calling this
|
|
1237
|
+
* again replaces the provider AND re-projects the rows already on screen. Optional — a
|
|
1238
|
+
* renderer without it simply never shows contributed legend actions.
|
|
1239
|
+
*/
|
|
1240
|
+
setLegendActions?(provider: ((indicatorId: string) => LegendActionView[]) | null): void;
|
|
1241
|
+
/**
|
|
1242
|
+
* Hide (`false`) or show (`true`) a mounted indicator's visuals while keeping its legend row
|
|
1243
|
+
* (marked hidden). Optional — a renderer that can't suppress an indicator omits it (and the
|
|
1244
|
+
* core's hide still works for resource suspension; only the in-chart legend eye is unavailable).
|
|
1245
|
+
* On show the core re-mounts the indicator, so this need only drop the visuals + flag the row.
|
|
1246
|
+
*/
|
|
1247
|
+
setIndicatorVisible?(handle: IndicatorRenderHandle, visible: boolean): void;
|
|
1248
|
+
/**
|
|
1249
|
+
* The renderer tells core when the base price style changes — from ANY source (the
|
|
1250
|
+
* `priceStyle` feature, the in-chart settings dialog, an applied config template).
|
|
1251
|
+
* Display state stays renderer-owned; the core listens because some styles carry a
|
|
1252
|
+
* DATA requirement (a plugin style may need its data engine running). Optional —
|
|
1253
|
+
* a renderer without runtime style switching omits it.
|
|
1254
|
+
*/
|
|
1255
|
+
onPriceStyleChange?(cb: (style: PriceStyle) => void): Unsubscribe;
|
|
1256
|
+
/** The renderer tells core when the user edits an input in-chart. */
|
|
1257
|
+
onInputChange(cb: (e: InputChangeEvent) => void): Unsubscribe;
|
|
1258
|
+
/** The renderer tells core when the user removes an indicator in-chart (the legend ✕). */
|
|
1259
|
+
onRemoveIndicator(cb: (id: string) => void): Unsubscribe;
|
|
1260
|
+
/** The renderer tells core when the user toggles an indicator's visibility in-chart (the legend eye). */
|
|
1261
|
+
onToggleIndicatorVisible?(cb: (id: string, visible: boolean) => void): Unsubscribe;
|
|
1262
|
+
onCrosshairMove(cb: (e: CrosshairEvent) => void): Unsubscribe;
|
|
1263
|
+
onClick(cb: (e: ClickEvent) => void): Unsubscribe;
|
|
1264
|
+
/**
|
|
1265
|
+
* Display an EXTERNAL crosshair at a data-space position — a ghost marker driven by
|
|
1266
|
+
* another chart (multi-chart crosshair sync), not by this chart's own pointer.
|
|
1267
|
+
* `time` is epoch-ms (`null` clears); `price` optionally adds the horizontal line
|
|
1268
|
+
* when the caller knows the scales are comparable (same-symbol groups). The ghost
|
|
1269
|
+
* must NEVER re-emit `onCrosshairMove` — that one-way rule is what makes the sync
|
|
1270
|
+
* loop-free. OPTIONAL — detect by presence (`RendererControl.supportsExternalCrosshair`);
|
|
1271
|
+
* a renderer without the seam simply never shows foreign crosshairs.
|
|
1272
|
+
*/
|
|
1273
|
+
setExternalCrosshair?(time: Millis | null, price?: number | null): void;
|
|
1274
|
+
/**
|
|
1275
|
+
* A pre-formatted readout of the bar under the crosshair — or of the latest bar when the
|
|
1276
|
+
* cursor is off the plot, so the snapshot is always useful. Pull it on crosshair movement
|
|
1277
|
+
* to drive a host data-window panel. Optional: a renderer that tracks no hovered bar omits
|
|
1278
|
+
* it (`RendererControl.dataWindowReadout()` then returns null).
|
|
1279
|
+
*/
|
|
1280
|
+
getDataWindowReadout?(): DataWindowReadout;
|
|
1281
|
+
getVisibleRange(): VisibleRange | null;
|
|
1282
|
+
setVisibleRange(range: VisibleRange): void;
|
|
1283
|
+
/**
|
|
1284
|
+
* Pan by a fraction of the visible width at constant zoom (positive ⇒ toward the
|
|
1285
|
+
* latest bars), behaving exactly like a pointer drag: same pan limits (including the
|
|
1286
|
+
* bounded whitespace past the newest bar), eased if the renderer animates pans.
|
|
1287
|
+
* OPTIONAL — without it the core falls back to an instant `setVisibleRange` shift.
|
|
1288
|
+
*/
|
|
1289
|
+
panBy?(fraction: number): void;
|
|
1290
|
+
onViewportChange(cb: (range: VisibleRange) => void): Unsubscribe;
|
|
1291
|
+
/**
|
|
1292
|
+
* Export the current chart as a PNG data URL (optional — a renderer that can't
|
|
1293
|
+
* rasterize its surface omits it). DOM overlays may not be included.
|
|
1294
|
+
*/
|
|
1295
|
+
screenshot?(): string | null;
|
|
1296
|
+
/**
|
|
1297
|
+
* Snapshot the renderer's full cosmetic configuration as a serializable,
|
|
1298
|
+
* versioned document — for persistence (templates, saved user settings).
|
|
1299
|
+
* Optional: a renderer without a rich config omits it. The returned value is
|
|
1300
|
+
* plain JSON; its concrete shape is renderer-defined.
|
|
1301
|
+
*/
|
|
1302
|
+
getConfig?(): unknown;
|
|
1303
|
+
/**
|
|
1304
|
+
* Apply a (possibly partial) config document produced by `getConfig()`.
|
|
1305
|
+
* Implementations validate untrusted input and ignore unknown/malformed fields,
|
|
1306
|
+
* repainting with no indicator re-run.
|
|
1307
|
+
*/
|
|
1308
|
+
applyConfig?(config: unknown): void;
|
|
1309
|
+
/**
|
|
1310
|
+
* The renderer's cosmetic config changed via {@link applyConfig} — the in-chart
|
|
1311
|
+
* settings dialog commits through it, so this is how host chrome mirroring a config
|
|
1312
|
+
* value (a bottom-bar timezone, a persisted template) learns about in-chart edits.
|
|
1313
|
+
* Re-pull {@link getConfig} / `readFeature` for the new values. Optional — paired
|
|
1314
|
+
* with `applyConfig`.
|
|
1315
|
+
*/
|
|
1316
|
+
onConfigChanged?(cb: () => void): Unsubscribe;
|
|
1317
|
+
/**
|
|
1318
|
+
* The renderer reports a user request to switch the APP THEME, made from its own
|
|
1319
|
+
* in-chart UI (the settings dialog's Canvas → Theme row). The core owns the
|
|
1320
|
+
* canonical theme: it resolves the name, calls {@link setTheme}, and emits
|
|
1321
|
+
* `theme:changed` so host chrome follows. Optional — a renderer without an
|
|
1322
|
+
* in-chart theme control omits it.
|
|
1323
|
+
*/
|
|
1324
|
+
onThemeSelect?(cb: (theme: ThemeName) => void): Unsubscribe;
|
|
1325
|
+
/**
|
|
1326
|
+
* Move keyboard focus onto the chart's interactive surface (the element its keyboard
|
|
1327
|
+
* shortcuts key off). Optional — a host UI calls it after its own controls steal focus
|
|
1328
|
+
* (e.g. a shared workspace toolbar click) so chart/drawing keys keep working.
|
|
1329
|
+
*/
|
|
1330
|
+
focus?(): void;
|
|
1331
|
+
/**
|
|
1332
|
+
* Close any in-chart dialogs the renderer owns (the indicator settings dialog, the
|
|
1333
|
+
* chart-settings gear dialog). Optional — used by a host to keep its own dialogs mutually
|
|
1334
|
+
* exclusive with the renderer's. A no-op when nothing is open.
|
|
1335
|
+
*/
|
|
1336
|
+
closeDialogs?(): void;
|
|
1337
|
+
/**
|
|
1338
|
+
* Open (or toggle) the renderer's own settings dialog, when it has one. `section` names
|
|
1339
|
+
* the tab to land on (matched against the dialog's section titles, unknown ones ignored);
|
|
1340
|
+
* with a section an already-open dialog switches tab rather than closing.
|
|
1341
|
+
*/
|
|
1342
|
+
openSettingsDialog?(section?: string): void;
|
|
1343
|
+
/** A chart type's SDK settings changed (dialog edit / applyConfig) — the core forwards
|
|
1344
|
+
* them to the type's data engine. */
|
|
1345
|
+
onChartTypeSettingsChange?(cb: (typeId: string, values: Record<string, unknown>) => void): Unsubscribe;
|
|
1346
|
+
/** Host-app settings tabs (callback rows) shown by the renderer's settings dialog. */
|
|
1347
|
+
setSettingsSections?(sections: ReadonlyArray<{
|
|
1348
|
+
title: string;
|
|
1349
|
+
rows: readonly unknown[];
|
|
1350
|
+
}>): void;
|
|
1351
|
+
/**
|
|
1352
|
+
* Interactive user-drawings surface. Present iff `capabilities.userDrawings`.
|
|
1353
|
+
* The core `DrawingController` drives it (commands down) and listens for
|
|
1354
|
+
* intents (up); a renderer without drawing tools simply omits it.
|
|
1355
|
+
*/
|
|
1356
|
+
readonly userDrawingsPort?: IDrawingsRendererPort;
|
|
1357
|
+
}
|
|
1358
|
+
|
|
1359
|
+
/** A named visible-range shortcut, resolved against the loaded bars. */
|
|
1360
|
+
type VisibleRangePreset = '1D' | '1W' | '1M' | '3M' | '6M' | '1Y' | '5Y' | 'YTD' | 'ALL';
|
|
1361
|
+
|
|
1362
|
+
/** A registered data-provider name (any string; matched case-insensitively). */
|
|
1363
|
+
type ProviderName = string;
|
|
1364
|
+
/** How the chart obtains its candles. */
|
|
1365
|
+
interface MarketConfig {
|
|
1366
|
+
/** The market's symbol. A bare ticker (`'BTCUSDT'`) resolves against the registered
|
|
1367
|
+
* providers in DECLARATION order (first one whose index lists it); an
|
|
1368
|
+
* `EXCHANGE:` prefix (`'coinbase:BTC-USD'`, case-insensitive) pins the venue. */
|
|
1369
|
+
symbol?: string;
|
|
1370
|
+
timeframe?: string;
|
|
1371
|
+
bars?: number;
|
|
1372
|
+
/**
|
|
1373
|
+
* The window to frame on the FIRST paint — a preset name (`'1D'`, `'YTD'`, …) or an
|
|
1374
|
+
* explicit `{from, to}`. Set it when the initial view is known up front (a range
|
|
1375
|
+
* chip, a shared link): the chart then loads the depth in ONE pass and paints the
|
|
1376
|
+
* requested window straight away, instead of flashing its fast recent-bars preview
|
|
1377
|
+
* and re-framing a moment later.
|
|
1378
|
+
*/
|
|
1379
|
+
visibleRange?: VisibleRangePreset | VisibleRange;
|
|
1380
|
+
/** Offline bars instead of a provider; when set, no network fetch happens. */
|
|
1381
|
+
data?: OHLCV[];
|
|
1382
|
+
}
|
|
1383
|
+
/**
|
|
1384
|
+
* One in-place market switch — the argument of `chart.setMarket(next)`. Only the fields
|
|
1385
|
+
* given change; the rest of the market keeps its current value. `data` switches to
|
|
1386
|
+
* offline bars (and giving `symbol`/`provider` WITHOUT `data` drops a previous offline
|
|
1387
|
+
* dataset — back to the provider path). `visibleRange` frames the FIRST paint of the
|
|
1388
|
+
* new market (a range chip switching timeframe + depth + window in one call).
|
|
1389
|
+
*/
|
|
1390
|
+
interface MarketSwitch {
|
|
1391
|
+
/** Bare ticker (provider resolved by declaration order) or `EXCHANGE:`-prefixed. */
|
|
1392
|
+
symbol?: string;
|
|
1393
|
+
timeframe?: string;
|
|
1394
|
+
bars?: number;
|
|
1395
|
+
data?: OHLCV[];
|
|
1396
|
+
visibleRange?: VisibleRangePreset | VisibleRange;
|
|
1397
|
+
}
|
|
1398
|
+
/**
|
|
1399
|
+
* The chart's current market identity — `chart.market`, the read counterpart of
|
|
1400
|
+
* `setMarket`. A SNAPSHOT of the requested market (mutating it changes nothing): it
|
|
1401
|
+
* reflects a switch as soon as `setMarket` is called, not when the load lands — the
|
|
1402
|
+
* "what is this chart showing/loading right now" answer. `offline` is true when the
|
|
1403
|
+
* chart runs on an inline `data` array instead of a provider.
|
|
1404
|
+
*/
|
|
1405
|
+
interface MarketSnapshot {
|
|
1406
|
+
symbol?: string;
|
|
1407
|
+
/** The venue the symbol PINS (its `EXCHANGE:` prefix, lower-cased) — undefined for a
|
|
1408
|
+
* bare symbol. The venue that actually served it: `chart.data.resolve(symbol)`. */
|
|
1409
|
+
provider?: ProviderName;
|
|
1410
|
+
timeframe?: string;
|
|
1411
|
+
bars?: number;
|
|
1412
|
+
offline: boolean;
|
|
1413
|
+
}
|
|
1414
|
+
interface VelaTheme {
|
|
1415
|
+
background: string;
|
|
1416
|
+
textColor: string;
|
|
1417
|
+
gridColor: string;
|
|
1418
|
+
borderColor: string;
|
|
1419
|
+
upColor: string;
|
|
1420
|
+
downColor: string;
|
|
1421
|
+
fontFamily: string;
|
|
1422
|
+
}
|
|
1423
|
+
type ThemeName = 'dark' | 'light';
|
|
1424
|
+
/** A renderer **class** — Vela instantiates it with the resolved display options.
|
|
1425
|
+
* Built-in default: `NativeRenderer`.
|
|
1426
|
+
* from `'vela/renderers/lwc'` and pass it as `options.renderer`. */
|
|
1427
|
+
type RendererConstructor = new (opts?: RendererDisplayOptions) => IChartRenderer;
|
|
1428
|
+
interface VelaOptions extends MarketConfig {
|
|
1429
|
+
/** false = static history; true = history + live forming candle. */
|
|
1430
|
+
live?: boolean;
|
|
1431
|
+
theme?: ThemeName | VelaTheme;
|
|
1432
|
+
height?: number | string;
|
|
1433
|
+
/** Rendering backend as a renderer **class** that Vela instantiates (with the
|
|
1434
|
+
* resolved display options). Omit for the built-in native renderer (default); for
|
|
1435
|
+
**/
|
|
1436
|
+
renderer?: RendererConstructor;
|
|
1437
|
+
/** Scripting language used when `addIndicator` doesn't specify one. Default `'pine'`
|
|
1438
|
+
* (or the first injected engine's language). */
|
|
1439
|
+
defaultLanguage?: string;
|
|
1440
|
+
/** Show the dashed line + axis label at the latest price (default true). */
|
|
1441
|
+
currentPriceLine?: boolean;
|
|
1442
|
+
/** Use a logarithmic price scale on the price pane (default false). */
|
|
1443
|
+
logScale?: boolean;
|
|
1444
|
+
/** Native geometry backend: `'auto'` (WebGL2 if available, else canvas2d),
|
|
1445
|
+
* or force `'canvas2d'` / `'webgl2'`. Native renderer only. */
|
|
1446
|
+
nativeBackend?: NativeBackend;
|
|
1447
|
+
/** Native-renderer animations. `true`/`false` toggles all; an object configures
|
|
1448
|
+
* each independently. Default: eased **zoom on**, inertial **pan on but snappy**
|
|
1449
|
+
* (short glide). Set `{ pan: false }` for an instant pan with no momentum. */
|
|
1450
|
+
animations?: boolean | AnimationConfig;
|
|
1451
|
+
/** Neon glow/bloom intensity for line series (0 = off, ~0.6 = strong). WebGL2 only
|
|
1452
|
+
* — the canvas2d backend ignores it. Default 0. */
|
|
1453
|
+
glow?: number;
|
|
1454
|
+
/** Bullish candle body/wick color (native renderer). Defaults to the palette's bullish green. */
|
|
1455
|
+
upColor?: string;
|
|
1456
|
+
/** Bearish candle body/wick color (native renderer). Defaults to the palette's bearish red. */
|
|
1457
|
+
downColor?: string;
|
|
1458
|
+
/** How the base price series is drawn (native renderer): candlestick / OHLC bars /
|
|
1459
|
+
* line / area / baseline. Default `'candles'`. */
|
|
1460
|
+
priceStyle?: PriceStyle;
|
|
1461
|
+
/** Interactive user drawings (native renderer). Default: toolbar VISIBLE with the
|
|
1462
|
+
* default tool set. `false` hides the toolbar (the `chart.drawings` API still works
|
|
1463
|
+
* headlessly); an object picks tools (`{ tools: [...] }`) or defines groups
|
|
1464
|
+
* (`{ groups: [...] }`) and toggles the toolbar (`{ toolbar: false }`). */
|
|
1465
|
+
drawings?: DrawingsOption;
|
|
1466
|
+
/** The built-in volume indicator: per-bar volume columns anchored to the bottom of the
|
|
1467
|
+
* price pane, on their own scale (they never affect the price autoscale). Added
|
|
1468
|
+
* automatically on chart creation (native renderer) — pass `false` to opt out. */
|
|
1469
|
+
volume?: boolean;
|
|
1470
|
+
}
|
|
1471
|
+
/** Per-feature native-renderer animation toggles. */
|
|
1472
|
+
interface AnimationConfig {
|
|
1473
|
+
/** Eased cursor-anchored wheel-zoom (+ gliding autoscale while zooming). Default true. */
|
|
1474
|
+
zoom?: boolean;
|
|
1475
|
+
/** Inertial/kinetic pan — a short snappy glide after a drag-release. Default true. */
|
|
1476
|
+
pan?: boolean;
|
|
1477
|
+
}
|
|
1478
|
+
/** Native geometry-layer backend selection. */
|
|
1479
|
+
type NativeBackend = 'auto' | 'canvas2d' | 'webgl2';
|
|
1480
|
+
/** How the base price series is drawn on the price pane (native renderer).
|
|
1481
|
+
* A plugin chart type (registered via `vela/plugin`) adds its own id to this union
|
|
1482
|
+
* volume-at-price (plus a right-edge visible-range profile); it needs the
|
|
1483
|
+
* provider+symbol to expose trade data — without it, plain candles render.
|
|
1484
|
+
* `'heikinashi'` draws Heikin Ashi candles: a 1:1 display transform of the raw
|
|
1485
|
+
* bars applied at the core's bar seam, so indicators compute on the same
|
|
1486
|
+
* smoothed values the chart shows (raw data stays untouched underneath). */
|
|
1487
|
+
/** Built-in styles plus any id registered through the chart-type SDK (`registerChartType`). */
|
|
1488
|
+
type PriceStyle = 'candles' | 'bars' | 'line' | 'area' | 'baseline' | 'heikinashi' | (string & {});
|
|
1489
|
+
/** Display options passed to a renderer at construction. */
|
|
1490
|
+
interface RendererDisplayOptions {
|
|
1491
|
+
currentPriceLine: boolean;
|
|
1492
|
+
logScale: boolean;
|
|
1493
|
+
nativeBackend: NativeBackend;
|
|
1494
|
+
animZoom: boolean;
|
|
1495
|
+
animPan: boolean;
|
|
1496
|
+
glow: number;
|
|
1497
|
+
upColor: string;
|
|
1498
|
+
downColor: string;
|
|
1499
|
+
priceStyle: PriceStyle;
|
|
1500
|
+
}
|
|
1501
|
+
/**
|
|
1502
|
+
* Where to move an indicator (via `handle.moveTo(...)`):
|
|
1503
|
+
* - `'price'` — merge into the main price pane (on its own scale unless it's a
|
|
1504
|
+
* price-unit overlay).
|
|
1505
|
+
* - `{ pane: id }` — merge into an existing pane (identified by `Pane.id`).
|
|
1506
|
+
* - `{ newPane: {...} }` — create a fresh pane, optionally placed relative to an
|
|
1507
|
+
* existing one (`before`/`after` its pane id); default is a new pane at the bottom.
|
|
1508
|
+
*/
|
|
1509
|
+
type MoveTarget = 'price' | {
|
|
1510
|
+
pane: string;
|
|
1511
|
+
} | {
|
|
1512
|
+
newPane: {
|
|
1513
|
+
before?: string;
|
|
1514
|
+
after?: string;
|
|
1515
|
+
} | true;
|
|
1516
|
+
};
|
|
1517
|
+
/** A pane and the indicators it holds — a `chart.panes.list()` entry. */
|
|
1518
|
+
interface PaneInfo {
|
|
1519
|
+
id: string;
|
|
1520
|
+
kind: 'price' | 'study';
|
|
1521
|
+
/** Display order, top-to-bottom (0 = topmost, the price pane). */
|
|
1522
|
+
order: number;
|
|
1523
|
+
collapsed: boolean;
|
|
1524
|
+
maximized: boolean;
|
|
1525
|
+
indicators: Array<{
|
|
1526
|
+
id: string;
|
|
1527
|
+
title: string;
|
|
1528
|
+
ownScale: boolean;
|
|
1529
|
+
}>;
|
|
1530
|
+
}
|
|
1531
|
+
/** Options for `chart.addIndicator(source, options?)`. */
|
|
1532
|
+
interface AddIndicatorOptions {
|
|
1533
|
+
/** Which registered engine runs this script (by language id). Default: the chart's `defaultLanguage`. */
|
|
1534
|
+
language?: string;
|
|
1535
|
+
/** Input overrides, keyed by input title or varId. */
|
|
1536
|
+
inputs?: Record<string, InputValue>;
|
|
1537
|
+
/** Force overlay-vs-pane placement (default: read from `indicator(overlay=…)`). */
|
|
1538
|
+
overlay?: boolean;
|
|
1539
|
+
/** Explicit pane placement. */
|
|
1540
|
+
pane?: 'price' | 'new';
|
|
1541
|
+
/** Display title override. */
|
|
1542
|
+
title?: string;
|
|
1543
|
+
}
|
|
1544
|
+
|
|
1545
|
+
export { type DrawingLinefill as $, type AddIndicatorOptions as A, type Background as B, type CrosshairEvent as C, Drawing as D, type CandleBarColor as E, type CandleSeries as F, type CandleStyle as G, type DataWindowGroup as H, type IChartRenderer as I, type DataWindowOHLC as J, type DataWindowRow as K, type LineStyle as L, type MarketConfig as M, type NativeBackend as N, type OHLCV as O, type PriceStyle as P, type DirtyRange as Q, type RendererCapabilities as R, type SerializedDrawing as S, type ThemeName as T, type Unsubscribe as U, type VisibleRangePreset as V, type DrawingBox as W, type DrawingExtend as X, type DrawingIntent as Y, type DrawingLabel as Z, type DrawingLine as _, type VisibleRange as a, type DrawingMode as a0, type DrawingPoint as a1, type DrawingPolyline as a2, type DrawingStyle as a3, type DrawingTable as a4, type DrawingText as a5, type DrawingXLoc as a6, type DrawingsOption as a7, type Fill as a8, type FillGradientStop as a9, type SettingsSchema as aA, type TableCell as aB, type TableMerge as aC, type TablePosition as aD, type ToolbarGroupConfig as aE, type TradeExecution as aF, type ValuePatch as aG, buildToolbar as aH, defaultToolbar as aI, type PaneInfo as aJ, type IndicatorMeta as aa, type InputSchema as ab, type InputType as ac, type LabelStyle as ad, type LabelYLoc as ae, type LineLikeKind as af, type LineLikeSeries as ag, type LineLikeStyle as ah, type MarkerPoint as ai, type MarkerSeries as aj, type MarketSnapshot as ak, type MarketSwitch as al, type PaneHint as am, type PaneKind as an, type PolylinePoint as ao, type PriceLine as ap, type Projector as aq, type ProviderName as ar, type RendererConstructor as as, type Scene as at, type SchemaPatch as au, type SeriesKind as av, type SeriesPoint as aw, type SeriesSpec as ax, type SeriesValueDelta as ay, type SettingsField as az, type VelaOptions as b, type VelaTheme as c, type RendererDisplayOptions as d, type IndicatorRenderHandle as e, type IndicatorStatus as f, type Pane as g, type PaneAction as h, type MoveTarget as i, type IndicatorModel as j, type ScenePatch as k, type InputValue as l, type SymbolPickerFn as m, type LegendActionView as n, type InputChangeEvent as o, type ClickEvent as p, type DataWindowReadout as q, type IDrawingsRendererPort as r, type Millis as s, type SnapMode as t, type DrawingTypeKey as u, type ToolbarDefinition as v, type BoxFontFamily as w, type BoxHAlign as x, type BoxTextSize as y, type BoxVAlign as z };
|