@tony01/astroneum 0.4.1-beta.2

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.
Files changed (59) hide show
  1. package/CHANGELOG.md +237 -0
  2. package/LICENSE +21 -0
  3. package/README.md +198 -0
  4. package/dist/Indicator-BBI3L_lx.d.ts +1181 -0
  5. package/dist/ar-SA-AEPUSRMF.js +2 -0
  6. package/dist/astroneum.css +1 -0
  7. package/dist/chunk-2SN3RH42.js +2 -0
  8. package/dist/chunk-2YYGUSVX.js +3 -0
  9. package/dist/chunk-3GJSZFLM.js +2 -0
  10. package/dist/chunk-4YOLQ5DC.js +2 -0
  11. package/dist/chunk-I4YQBP2M.js +3 -0
  12. package/dist/chunk-OOMZRONH.js +35 -0
  13. package/dist/chunk-PV2GAINM.js +2 -0
  14. package/dist/chunk-SDXH2WAI.js +3 -0
  15. package/dist/chunk-YFPXTHZX.js +2 -0
  16. package/dist/chunk-YW3STIPY.js +653 -0
  17. package/dist/de-DE-4PR3NRQ7.js +2 -0
  18. package/dist/entries/alerts.d.ts +93 -0
  19. package/dist/entries/alerts.js +2 -0
  20. package/dist/entries/datafeeds/crypto.d.ts +65 -0
  21. package/dist/entries/datafeeds/crypto.js +2 -0
  22. package/dist/entries/datafeeds/polygon.d.ts +113 -0
  23. package/dist/entries/datafeeds/polygon.js +2 -0
  24. package/dist/entries/multichart.d.ts +96 -0
  25. package/dist/entries/multichart.js +2 -0
  26. package/dist/entries/portfolio.d.ts +55 -0
  27. package/dist/entries/portfolio.js +2 -0
  28. package/dist/entries/replay.d.ts +141 -0
  29. package/dist/entries/replay.js +2 -0
  30. package/dist/entries/script.d.ts +68 -0
  31. package/dist/entries/script.js +2 -0
  32. package/dist/entries/watchlist.d.ts +43 -0
  33. package/dist/entries/watchlist.js +2 -0
  34. package/dist/es-ES-HNDVPSLW.js +2 -0
  35. package/dist/fr-FR-Y7XWRGF2.js +2 -0
  36. package/dist/hi-IN-KEGIKIMV.js +2 -0
  37. package/dist/id-ID-QXDIUQUZ.js +2 -0
  38. package/dist/index.d.ts +1434 -0
  39. package/dist/index.js +2 -0
  40. package/dist/it-IT-UDTDFSRB.js +2 -0
  41. package/dist/ja-JP-NIODTBW3.js +2 -0
  42. package/dist/ko-KR-DQHPXKBA.js +2 -0
  43. package/dist/nl-NL-BB3ZHCXS.js +2 -0
  44. package/dist/pl-PL-I5MZDLFD.js +2 -0
  45. package/dist/pt-BR-MAMRTOYR.js +2 -0
  46. package/dist/ru-RU-F43D6B7G.js +2 -0
  47. package/dist/th-TH-KTFIUAD6.js +2 -0
  48. package/dist/tr-TR-WFTKJ22Y.js +2 -0
  49. package/dist/vi-VN-CD3WI2FQ.js +2 -0
  50. package/dist/zh-CN-Y2C6RSOI.js +3 -0
  51. package/docs/STRUCTURE.md +231 -0
  52. package/docs/TODO-DESIGN.md +261 -0
  53. package/docs/TODO.md +222 -0
  54. package/docs/api.md +528 -0
  55. package/docs/datafeed-guide.md +311 -0
  56. package/docs/design-astroneum.md +479 -0
  57. package/docs/plugin-development.md +565 -0
  58. package/docs/tv-functions-skill.md +706 -0
  59. package/package.json +147 -0
@@ -0,0 +1,1434 @@
1
+ import { I as IndicatorTemplate, O as OverlayTemplate, X as XAxisTemplate, Y as YAxisTemplate, A as AstroneumOptions, a as AstroneumHandle, C as CandleData, b as IndicatorPlugin, P as Price, T as Timestamp, V as Volume, c as Chart, S as SerializedChartState, d as Period, e as SymbolInfo, D as Datafeed } from './Indicator-BBI3L_lx.js';
2
+ export { f as ChartEventMap, g as ChartPlugin, h as ChartPluginContext, i as DatafeedSubscribeCallback, j as Viewport } from './Indicator-BBI3L_lx.js';
3
+ export { DefaultDatafeed, WebSocketDatafeed, WebSocketDatafeedOptions } from './entries/datafeeds/polygon.js';
4
+ export { BinanceAdapter, BitgetAdapter, CryptoSymbolInfo, DATAFEED_ERROR_EVENT, DatafeedErrorDetail, DatafeedErrorType, ExchangeAdapter, OkxAdapter, STANDARD_CRYPTO_SYMBOLS, StandardCryptoDatafeed, StandardCryptoDatafeedOptions, createStandardCryptoDatafeed } from './entries/datafeeds/crypto.js';
5
+ import * as react from 'react';
6
+ export { MultiChartCount, MultiChartLayout, MultiChartLayoutOptions, MultiChartSlot } from './entries/multichart.js';
7
+ export { BarReplay, BarReplayOptions, BarReplayState } from './entries/replay.js';
8
+ export { Alert, AlertCheckInput, AlertCondition, AlertCreate, AlertFrequency, AlertManager, AlertStatus, AlertTriggeredCallback, NotificationSchedule, SoundDuration, SoundTitle } from './entries/alerts.js';
9
+ export { CompiledIndicator, InputOptions, PlotOptions, ScriptEngine, StudyOptions } from './entries/script.js';
10
+ export { WatchSymbol, Watchlist, WatchlistManager } from './entries/watchlist.js';
11
+ import { Position } from './entries/portfolio.js';
12
+ export { PnLResult, PortfolioTracker, PositionSide } from './entries/portfolio.js';
13
+
14
+ declare function registerIndicator<D = unknown, C = unknown, E = unknown>(indicator: IndicatorTemplate<D, C, E>): void;
15
+ declare function getSupportedIndicators(): string[];
16
+
17
+ declare function registerOverlay<E = unknown>(template: OverlayTemplate<E>): void;
18
+ declare function getSupportedOverlays(): string[];
19
+
20
+ declare function registerXAxis(axis: XAxisTemplate): void;
21
+
22
+ declare function registerYAxis(axis: YAxisTemplate): void;
23
+
24
+ declare const AstroneumChart: react.ForwardRefExoticComponent<AstroneumOptions & react.RefAttributes<AstroneumHandle>>;
25
+
26
+ /**
27
+ * Drawing Style Templates & Presets
28
+ *
29
+ * Provides named overlay style presets that users can apply to drawing tools,
30
+ * plus save/load of custom templates to localStorage.
31
+ */
32
+ interface OverlayStylePreset {
33
+ /** Unique identifier for this preset. */
34
+ id: string;
35
+ /** Human-readable display name. */
36
+ name: string;
37
+ /** Partial overlay style object compatible with the engine's overlay styles. */
38
+ styles: DrawingStyleTemplate;
39
+ }
40
+ interface DrawingStyleTemplate {
41
+ line?: {
42
+ color?: string;
43
+ size?: number;
44
+ style?: 'solid' | 'dashed' | 'dotted';
45
+ };
46
+ polygon?: {
47
+ color?: string;
48
+ };
49
+ text?: {
50
+ color?: string;
51
+ size?: number;
52
+ family?: string;
53
+ weight?: string;
54
+ };
55
+ rectText?: {
56
+ color?: string;
57
+ size?: number;
58
+ family?: string;
59
+ weight?: string;
60
+ paddingLeft?: number;
61
+ paddingRight?: number;
62
+ paddingTop?: number;
63
+ paddingBottom?: number;
64
+ borderRadius?: number;
65
+ borderSize?: number;
66
+ borderColor?: string;
67
+ backgroundColor?: string;
68
+ };
69
+ point?: {
70
+ color?: string;
71
+ radius?: number;
72
+ borderColor?: string;
73
+ borderSize?: number;
74
+ };
75
+ }
76
+ /**
77
+ * Manager for drawing style presets.
78
+ * Provides access to built-in presets and allows saving/loading custom ones.
79
+ *
80
+ * @example
81
+ * ```ts
82
+ * const templates = DrawingTemplates.getInstance()
83
+ * const preset = templates.getPreset('bullish')
84
+ * // Apply preset.styles to an overlay via chart.overrideOverlay(...)
85
+ * ```
86
+ */
87
+ declare class DrawingTemplates {
88
+ private static _instance;
89
+ private _custom;
90
+ private constructor();
91
+ static getInstance(): DrawingTemplates;
92
+ private _loadCustom;
93
+ private _saveCustom;
94
+ /** Return all presets (built-in first, then custom). */
95
+ getAll(): OverlayStylePreset[];
96
+ /** Return built-in presets only. */
97
+ getBuiltIn(): OverlayStylePreset[];
98
+ /** Return user-saved custom presets. */
99
+ getCustom(): OverlayStylePreset[];
100
+ /** Find a preset by id (searches built-ins then custom). */
101
+ getPreset(id: string): OverlayStylePreset | undefined;
102
+ /**
103
+ * Save a new custom preset (or overwrite an existing custom one with the same id).
104
+ * Note: built-in preset ids cannot be overwritten.
105
+ */
106
+ saveCustomPreset(preset: OverlayStylePreset): void;
107
+ /** Delete a custom preset by id. Built-in presets cannot be deleted. */
108
+ deleteCustomPreset(id: string): boolean;
109
+ /**
110
+ * Apply a preset to an engine overlay via overrideOverlay.
111
+ * Returns the styles object ready to pass to `chart.overrideOverlay({ groupId, styles })`.
112
+ */
113
+ toOverlayStyles(presetId: string): DrawingStyleTemplate | undefined;
114
+ /**
115
+ * Preview a preset on an overlay without saving it. The styles are applied
116
+ * temporarily via overrideOverlay. Combine with the revert function to
117
+ * restore the original styles after preview ends.
118
+ *
119
+ * @returns A revert function that restores the original styles.
120
+ */
121
+ preview(presetId: string, overlayId: string, chart: {
122
+ overrideOverlay: (o: {
123
+ id?: string;
124
+ styles?: unknown;
125
+ }) => void;
126
+ getOverlays: () => Array<{
127
+ id: string;
128
+ styles: unknown;
129
+ }>;
130
+ }): (() => void) | null;
131
+ /**
132
+ * Apply a specific color to an individual drawing overlay by ID.
133
+ * Changes are persisted with the overlay (stored in overlay styles).
134
+ */
135
+ static applyColor(chart: {
136
+ overrideOverlay: (o: {
137
+ id?: string;
138
+ styles?: unknown;
139
+ }) => void;
140
+ }, overlayId: string, color: string): void;
141
+ }
142
+
143
+ /**
144
+ * PerformanceMode — data decimation and virtualization utilities.
145
+ *
146
+ * Use these when dealing with very large datasets to keep renders fast:
147
+ * - `decimate(data, maxBars)` — LTTB downsampling
148
+ * - `virtualizeWindow(data, start, end, buffer)` — windowed slice
149
+ * - `shouldDecimate(length, threshold?)` — quick heuristic
150
+ */
151
+
152
+ /**
153
+ * Transform standard OHLCV bars into Heikin-Ashi candles.
154
+ *
155
+ * Heikin-Ashi candles use averaged values to filter out market noise:
156
+ * ha_close = (open + high + low + close) / 4
157
+ * ha_open = (prev_ha_open + prev_ha_close) / 2
158
+ * ha_high = max(high, ha_open, ha_close)
159
+ * ha_low = min(low, ha_open, ha_close)
160
+ *
161
+ * @param data Source candlestick data
162
+ * @returns New array of Heikin-Ashi candles (same timestamps, volume, turnover)
163
+ */
164
+ declare function heikinAshi(data: CandleData[]): CandleData[];
165
+ interface Bar {
166
+ timestamp: number;
167
+ open: number;
168
+ high: number;
169
+ low: number;
170
+ close: number;
171
+ volume?: number;
172
+ [key: string]: unknown;
173
+ }
174
+ /**
175
+ * Downsample `data` to `targetCount` points using the LTTB algorithm.
176
+ * Always preserves the first and last bar. Returns a new array.
177
+ */
178
+ declare function decimate<T extends Bar>(data: T[], targetCount: number): T[];
179
+ /**
180
+ * Return only the bars within [visibleStart, visibleEnd] timestamps,
181
+ * extended by `buffer` bars on each side to support look-back indicators.
182
+ */
183
+ declare function virtualizeWindow<T extends Bar>(data: T[], visibleStart: number, visibleEnd: number, buffer?: number): T[];
184
+ /**
185
+ * Returns true when the dataset is large enough that decimation makes sense.
186
+ * @param dataLength - Total number of bars in the dataset
187
+ * @param threshold - Bar count threshold, default 5000
188
+ */
189
+ declare function shouldDecimate(dataLength: number, threshold?: number): boolean;
190
+ declare class PerformanceMode {
191
+ static decimate: typeof decimate;
192
+ static virtualizeWindow: typeof virtualizeWindow;
193
+ static shouldDecimate: typeof shouldDecimate;
194
+ static heikinAshi: typeof heikinAshi;
195
+ }
196
+
197
+ var indicator = "Indicator";
198
+ var main_indicator = "Main Indicator";
199
+ var sub_indicator = "Sub Indicator";
200
+ var setting = "Setting";
201
+ var timezone = "Timezone";
202
+ var screenshot = "Screenshot";
203
+ var full_screen = "Full Screen";
204
+ var exit_full_screen = "Exit";
205
+ var save = "Save";
206
+ var confirm = "Confirm";
207
+ var color = "Color";
208
+ var show = "Show";
209
+ var cancel = "Cancel";
210
+ var ma = "MA(Moving Average)";
211
+ var ema = "EMA(Exponential Moving Average)";
212
+ var sma = "SMA";
213
+ var boll = "BOLL(Bolinger Bands)";
214
+ var bbi = "BBI(Bull And Bearlndex)";
215
+ var sar = "SAR(Stop and Reverse)";
216
+ var vol = "VOL(Volume)";
217
+ var macd = "MACD(Moving Average Convergence / Divergence)";
218
+ var kdj = "KDJ(KDJ Index)";
219
+ var rsi = "RSI(Relative Strength Index)";
220
+ var bias = "BIAS(Bias Ratio)";
221
+ var brar = "BRAR(Bull and Bear Sentiment)";
222
+ var cci = "CCI(Commodity Channel Index)";
223
+ var dmi = "DMI(Directional Movement Index)";
224
+ var cr = "CR(Energy Index)";
225
+ var psy = "PSY(Psychological Line)";
226
+ var dma = "DMA(Different of Moving Average)";
227
+ var trix = "TRIX(Triple Exponentially Smoothed Moving Average)";
228
+ var obv = "OBV(On Balance Volume)";
229
+ var vr = "VR(Volatility Volume Ratio)";
230
+ var wr = "WR(Williams %R)";
231
+ var mtm = "MTM(Momentum Index)";
232
+ var emv = "EMV(Ease of Movement Value)";
233
+ var roc = "ROC(Price Rate of Change)";
234
+ var pvt = "PVT(Price and Volume Trend)";
235
+ var ao = "AO(Awesome Oscillator)";
236
+ var utc = "UTC";
237
+ var honolulu = "(UTC-10) Honolulu";
238
+ var juneau = "(UTC-8) Juneau";
239
+ var los_angeles = "(UTC-7) Los Angeles";
240
+ var chicago = "(UTC-5) Chicago";
241
+ var toronto = "(UTC-4) Toronto";
242
+ var sao_paulo = "(UTC-3) Sao Paulo";
243
+ var london = "(UTC+1) London";
244
+ var berlin = "(UTC+2) Berlin";
245
+ var bahrain = "(UTC+3) Bahrain";
246
+ var dubai = "(UTC+4) Dubai";
247
+ var ashkhabad = "(UTC+5) Ashkhabad";
248
+ var almaty = "(UTC+6) Almaty";
249
+ var bangkok = "(UTC+7) Bangkok";
250
+ var shanghai = "(UTC+8) Shanghai";
251
+ var tokyo = "(UTC+9) Tokyo";
252
+ var sydney = "(UTC+10) Sydney";
253
+ var norfolk = "(UTC+12) Norfolk";
254
+ var horizontal_straight_line = "Horizontal Line";
255
+ var horizontal_ray_line = "Horizontal Ray";
256
+ var horizontal_segment = "Horizontal Segment";
257
+ var vertical_straight_line = "Vertical Line";
258
+ var vertical_ray_line = "Vertical Ray";
259
+ var vertical_segment = "Vertical Segment";
260
+ var straight_line = "Trend Line";
261
+ var ray_line = "Ray";
262
+ var segment = "Segment";
263
+ var arrow = "Arrow";
264
+ var price_line = "Price Line";
265
+ var price_channel_line = "Price Channel Line";
266
+ var parallel_straight_line = "Parallel Line";
267
+ var fibonacci_line = "Fibonacci Line";
268
+ var fibonacci_segment = "Fibonacci Segment";
269
+ var fibonacci_circle = "Fibonacci Circle";
270
+ var fibonacci_spiral = "Fibonacci Spiral";
271
+ var fibonacci_speed_resistance_fan = "Fibonacci Sector";
272
+ var fibonacci_extension = "Fibonacci Extension";
273
+ var gann_box = "Gann Box";
274
+ var gann_fan = "Gann Fan";
275
+ var pitchfork = "Andrews Pitchfork";
276
+ var rect = "Rect";
277
+ var parallelogram = "Parallelogram";
278
+ var circle = "Circle";
279
+ var triangle = "Triangle";
280
+ var three_waves = "Three Waves";
281
+ var five_waves = "Five Waves";
282
+ var eight_waves = "Eight Waves";
283
+ var any_waves = "Any Waves";
284
+ var abcd = "ABCD Pattern";
285
+ var xabcd = "XABCD Pattern";
286
+ var weak_magnet = "Weak Magnet";
287
+ var strong_magnet = "Strong Magnet";
288
+ var symbol_search = "Symbol Search";
289
+ var symbol_code = "Symbol Code";
290
+ var params_1 = "Parameter 1";
291
+ var params_2 = "Parameter 2";
292
+ var params_3 = "Parameter 3";
293
+ var params_4 = "Parameter 4";
294
+ var params_5 = "Parameter 5";
295
+ var line_1 = "Line 1";
296
+ var line_2 = "Line 2";
297
+ var line_3 = "Line 3";
298
+ var line_4 = "Line 4";
299
+ var line_5 = "Line 5";
300
+ var period = "Period";
301
+ var standard_deviation = "Standard Deviation";
302
+ var candle_type = "Candle Type";
303
+ var candle_solid = "Candle Solid";
304
+ var candle_stroke = "Candle Stroke";
305
+ var candle_up_stroke = "Candle Up Stroke";
306
+ var candle_down_stroke = "Candle Down Stroke";
307
+ var ohlc = "OHLC";
308
+ var area = "Area";
309
+ var last_price_show = "Show Last Price";
310
+ var high_price_show = "Show Highest Price";
311
+ var low_price_show = "Show Lowest Price";
312
+ var indicator_last_value_show = "Show indicator's last value";
313
+ var price_axis_type = "Price Axis Type";
314
+ var normal = "Normal";
315
+ var percentage = "Percentage";
316
+ var log = "Log";
317
+ var reverse_coordinate = "Reverse Coordinate";
318
+ var grid_show = "Show Grids";
319
+ var restore_default = "Restore Defaults";
320
+ var alerts = "Alerts";
321
+ var alert_create = "Create";
322
+ var alert_history = "History";
323
+ var alert_condition = "Condition";
324
+ var alert_price = "Price";
325
+ var alert_note = "Note";
326
+ var alert_note_placeholder = "Optional label…";
327
+ var alert_add = "Add Alert";
328
+ var alert_active = "Active";
329
+ var alert_no_history = "No triggered alerts yet";
330
+ var alert_reactivate = "Re-activate";
331
+ var alert_above = "Above";
332
+ var alert_below = "Below";
333
+ var alert_crosses_above = "Crosses ↑";
334
+ var alert_crosses_below = "Crosses ↓";
335
+ var alert_trigger = "Trigger";
336
+ var alert_trigger_once = "Once only";
337
+ var alert_trigger_every_bar = "Every bar";
338
+ var alert_trigger_bar_close = "Once per bar close";
339
+ var alert_expiration = "Expiration";
340
+ var alert_expiration_open = "Open-ended";
341
+ var alert_expiration_1d = "In 1 day";
342
+ var alert_expiration_1w = "In 1 week";
343
+ var alert_expiration_1m = "In 1 month";
344
+ var alert_expiration_2m = "In 2 months";
345
+ var alert_message = "Message";
346
+ var alert_message_hint = "Sent as the webhook body when a webhook URL is set.";
347
+ var alert_webhook_body = "Webhook body";
348
+ var alert_notifications = "Notifications";
349
+ var alert_back = "Back";
350
+ var alert_apply = "Apply";
351
+ var alert_notif_app = "Notify in app";
352
+ var alert_notif_app_desc = "Provides a push notification in the mobile app.";
353
+ var alert_notif_toast = "Show toast notification";
354
+ var alert_notif_toast_desc = "Displays an onsite notification in the page corner.";
355
+ var alert_notif_email = "Send email";
356
+ var alert_notif_email_desc = "Sends an email to the address in your account settings.";
357
+ var alert_notif_webhook = "Webhook URL";
358
+ var alert_notif_webhook_desc = "Sends a POST request to your URL when the alert triggers.";
359
+ var alert_notif_sound = "Play sound";
360
+ var alert_notif_sound_desc = "Plays an audio cue when your alert triggers.";
361
+ var alert_notif_plaintext = "Send plain text";
362
+ var alert_notif_plaintext_desc = "Sends plain text to an alternative email.";
363
+ var alert_notif_none = "None";
364
+ var alert_webhook_valid = "Valid target URL";
365
+ var alert_webhook_invalid = "Invalid URL — use http(s)://, no private or localhost hosts";
366
+ var alert_sound_once = "Once";
367
+ var alert_sound_repeating = "Repeating";
368
+ var alert_schedule = "Notification schedule";
369
+ var alert_schedule_desc = "Notifications are muted outside this schedule.";
370
+ var alert_schedule_weekdays = "Weekdays";
371
+ var alert_schedule_working_hours = "Working hours (Mon–Fri 09:00–18:00)";
372
+ var alert_schedule_custom = "Custom";
373
+ var alert_webhook_delivered = "Delivered";
374
+ var alert_webhook_failed = "Failed";
375
+ var alert_webhook_sending = "Sending";
376
+ var alert_log = "Log";
377
+ var alert_clear_log = "Clear log";
378
+ var alert_actions = "Actions";
379
+ var alert_no_log = "No alerts triggered yet";
380
+ var alert_webhook_success = "Webhook successfully delivered";
381
+ var alert_webhook_failed_prefix = "Webhook delivery failed";
382
+ var alert_webhook_timeout = "request took too long and timed out";
383
+ var alert_webhook_learn_more = "Learn more";
384
+ var snap_levels = "Snap to price levels";
385
+ var no_magnet = "No snap";
386
+ var script_editor = "Script Editor";
387
+ var script_editor_hint = "Write JavaScript — uses Pine Script–inspired API with ta.* helpers";
388
+ var script_compile = "Compile";
389
+ var script_apply = "Add to Chart";
390
+ var script_compiled = "Compiled";
391
+ var script_api_ref = "API Reference";
392
+ var watchlist = "Watchlist";
393
+ var watchlist_new = "New Watchlist";
394
+ var watchlist_add_list = "Add watchlist";
395
+ var watchlist_delete_list = "Delete watchlist";
396
+ var watchlist_add_symbol = "Add";
397
+ var watchlist_remove_symbol = "Remove symbol";
398
+ var watchlist_enter_symbol = "Enter ticker…";
399
+ var enUS = {
400
+ indicator: indicator,
401
+ main_indicator: main_indicator,
402
+ sub_indicator: sub_indicator,
403
+ setting: setting,
404
+ timezone: timezone,
405
+ screenshot: screenshot,
406
+ full_screen: full_screen,
407
+ exit_full_screen: exit_full_screen,
408
+ save: save,
409
+ confirm: confirm,
410
+ color: color,
411
+ show: show,
412
+ cancel: cancel,
413
+ ma: ma,
414
+ ema: ema,
415
+ sma: sma,
416
+ boll: boll,
417
+ bbi: bbi,
418
+ sar: sar,
419
+ vol: vol,
420
+ macd: macd,
421
+ kdj: kdj,
422
+ rsi: rsi,
423
+ bias: bias,
424
+ brar: brar,
425
+ cci: cci,
426
+ dmi: dmi,
427
+ cr: cr,
428
+ psy: psy,
429
+ dma: dma,
430
+ trix: trix,
431
+ obv: obv,
432
+ vr: vr,
433
+ wr: wr,
434
+ mtm: mtm,
435
+ emv: emv,
436
+ roc: roc,
437
+ pvt: pvt,
438
+ ao: ao,
439
+ utc: utc,
440
+ honolulu: honolulu,
441
+ juneau: juneau,
442
+ los_angeles: los_angeles,
443
+ chicago: chicago,
444
+ toronto: toronto,
445
+ sao_paulo: sao_paulo,
446
+ london: london,
447
+ berlin: berlin,
448
+ bahrain: bahrain,
449
+ dubai: dubai,
450
+ ashkhabad: ashkhabad,
451
+ almaty: almaty,
452
+ bangkok: bangkok,
453
+ shanghai: shanghai,
454
+ tokyo: tokyo,
455
+ sydney: sydney,
456
+ norfolk: norfolk,
457
+ horizontal_straight_line: horizontal_straight_line,
458
+ horizontal_ray_line: horizontal_ray_line,
459
+ horizontal_segment: horizontal_segment,
460
+ vertical_straight_line: vertical_straight_line,
461
+ vertical_ray_line: vertical_ray_line,
462
+ vertical_segment: vertical_segment,
463
+ straight_line: straight_line,
464
+ ray_line: ray_line,
465
+ segment: segment,
466
+ arrow: arrow,
467
+ price_line: price_line,
468
+ price_channel_line: price_channel_line,
469
+ parallel_straight_line: parallel_straight_line,
470
+ fibonacci_line: fibonacci_line,
471
+ fibonacci_segment: fibonacci_segment,
472
+ fibonacci_circle: fibonacci_circle,
473
+ fibonacci_spiral: fibonacci_spiral,
474
+ fibonacci_speed_resistance_fan: fibonacci_speed_resistance_fan,
475
+ fibonacci_extension: fibonacci_extension,
476
+ gann_box: gann_box,
477
+ gann_fan: gann_fan,
478
+ pitchfork: pitchfork,
479
+ rect: rect,
480
+ parallelogram: parallelogram,
481
+ circle: circle,
482
+ triangle: triangle,
483
+ three_waves: three_waves,
484
+ five_waves: five_waves,
485
+ eight_waves: eight_waves,
486
+ any_waves: any_waves,
487
+ abcd: abcd,
488
+ xabcd: xabcd,
489
+ weak_magnet: weak_magnet,
490
+ strong_magnet: strong_magnet,
491
+ symbol_search: symbol_search,
492
+ symbol_code: symbol_code,
493
+ params_1: params_1,
494
+ params_2: params_2,
495
+ params_3: params_3,
496
+ params_4: params_4,
497
+ params_5: params_5,
498
+ line_1: line_1,
499
+ line_2: line_2,
500
+ line_3: line_3,
501
+ line_4: line_4,
502
+ line_5: line_5,
503
+ period: period,
504
+ standard_deviation: standard_deviation,
505
+ candle_type: candle_type,
506
+ candle_solid: candle_solid,
507
+ candle_stroke: candle_stroke,
508
+ candle_up_stroke: candle_up_stroke,
509
+ candle_down_stroke: candle_down_stroke,
510
+ ohlc: ohlc,
511
+ area: area,
512
+ last_price_show: last_price_show,
513
+ high_price_show: high_price_show,
514
+ low_price_show: low_price_show,
515
+ indicator_last_value_show: indicator_last_value_show,
516
+ price_axis_type: price_axis_type,
517
+ normal: normal,
518
+ percentage: percentage,
519
+ log: log,
520
+ reverse_coordinate: reverse_coordinate,
521
+ grid_show: grid_show,
522
+ restore_default: restore_default,
523
+ alerts: alerts,
524
+ alert_create: alert_create,
525
+ alert_history: alert_history,
526
+ alert_condition: alert_condition,
527
+ alert_price: alert_price,
528
+ alert_note: alert_note,
529
+ alert_note_placeholder: alert_note_placeholder,
530
+ alert_add: alert_add,
531
+ alert_active: alert_active,
532
+ alert_no_history: alert_no_history,
533
+ alert_reactivate: alert_reactivate,
534
+ alert_above: alert_above,
535
+ alert_below: alert_below,
536
+ alert_crosses_above: alert_crosses_above,
537
+ alert_crosses_below: alert_crosses_below,
538
+ alert_trigger: alert_trigger,
539
+ alert_trigger_once: alert_trigger_once,
540
+ alert_trigger_every_bar: alert_trigger_every_bar,
541
+ alert_trigger_bar_close: alert_trigger_bar_close,
542
+ alert_expiration: alert_expiration,
543
+ alert_expiration_open: alert_expiration_open,
544
+ alert_expiration_1d: alert_expiration_1d,
545
+ alert_expiration_1w: alert_expiration_1w,
546
+ alert_expiration_1m: alert_expiration_1m,
547
+ alert_expiration_2m: alert_expiration_2m,
548
+ alert_message: alert_message,
549
+ alert_message_hint: alert_message_hint,
550
+ alert_webhook_body: alert_webhook_body,
551
+ alert_notifications: alert_notifications,
552
+ alert_back: alert_back,
553
+ alert_apply: alert_apply,
554
+ alert_notif_app: alert_notif_app,
555
+ alert_notif_app_desc: alert_notif_app_desc,
556
+ alert_notif_toast: alert_notif_toast,
557
+ alert_notif_toast_desc: alert_notif_toast_desc,
558
+ alert_notif_email: alert_notif_email,
559
+ alert_notif_email_desc: alert_notif_email_desc,
560
+ alert_notif_webhook: alert_notif_webhook,
561
+ alert_notif_webhook_desc: alert_notif_webhook_desc,
562
+ alert_notif_sound: alert_notif_sound,
563
+ alert_notif_sound_desc: alert_notif_sound_desc,
564
+ alert_notif_plaintext: alert_notif_plaintext,
565
+ alert_notif_plaintext_desc: alert_notif_plaintext_desc,
566
+ alert_notif_none: alert_notif_none,
567
+ alert_webhook_valid: alert_webhook_valid,
568
+ alert_webhook_invalid: alert_webhook_invalid,
569
+ alert_sound_once: alert_sound_once,
570
+ alert_sound_repeating: alert_sound_repeating,
571
+ alert_schedule: alert_schedule,
572
+ alert_schedule_desc: alert_schedule_desc,
573
+ "alert_schedule_24/7": "24/7",
574
+ alert_schedule_weekdays: alert_schedule_weekdays,
575
+ alert_schedule_working_hours: alert_schedule_working_hours,
576
+ alert_schedule_custom: alert_schedule_custom,
577
+ alert_webhook_delivered: alert_webhook_delivered,
578
+ alert_webhook_failed: alert_webhook_failed,
579
+ alert_webhook_sending: alert_webhook_sending,
580
+ alert_log: alert_log,
581
+ alert_clear_log: alert_clear_log,
582
+ alert_actions: alert_actions,
583
+ alert_no_log: alert_no_log,
584
+ alert_webhook_success: alert_webhook_success,
585
+ alert_webhook_failed_prefix: alert_webhook_failed_prefix,
586
+ alert_webhook_timeout: alert_webhook_timeout,
587
+ alert_webhook_learn_more: alert_webhook_learn_more,
588
+ snap_levels: snap_levels,
589
+ no_magnet: no_magnet,
590
+ script_editor: script_editor,
591
+ script_editor_hint: script_editor_hint,
592
+ script_compile: script_compile,
593
+ script_apply: script_apply,
594
+ script_compiled: script_compiled,
595
+ script_api_ref: script_api_ref,
596
+ watchlist: watchlist,
597
+ watchlist_new: watchlist_new,
598
+ watchlist_add_list: watchlist_add_list,
599
+ watchlist_delete_list: watchlist_delete_list,
600
+ watchlist_add_symbol: watchlist_add_symbol,
601
+ watchlist_remove_symbol: watchlist_remove_symbol,
602
+ watchlist_enter_symbol: watchlist_enter_symbol
603
+ };
604
+
605
+ type LocaleKey = keyof typeof enUS;
606
+ type LocaleMap = Partial<Record<LocaleKey, string>>;
607
+ /**
608
+ * Register a locale dictionary explicitly. Use this to ship your own
609
+ * translations or to override a built-in locale at runtime.
610
+ */
611
+ declare function load(key: string, ls: LocaleMap): void;
612
+ /**
613
+ * Asynchronously load one of the built-in locales. Resolves with the
614
+ * dictionary, or `null` when the locale is not a built-in (already
615
+ * loaded locales return the cached map). Subsequent lookups for that
616
+ * locale will return its translations.
617
+ *
618
+ * ```ts
619
+ * await loadLocale('ja-JP')
620
+ * chartRef.current?.setLocale('ja-JP')
621
+ * ```
622
+ */
623
+ declare function loadLocale(key: string): Promise<LocaleMap | null>;
624
+ /** Names of all built-in locales that can be passed to `loadLocale`. */
625
+ declare const BUILTIN_LOCALES: ReadonlyArray<string>;
626
+
627
+ /**
628
+ * Locale-aware number and date formatting utilities.
629
+ * Uses the native Intl API — no extra dependencies.
630
+ */
631
+ interface FormatPriceOptions {
632
+ /** Number of decimal places. Defaults to 2. */
633
+ precision?: number;
634
+ /** Whether to show compact notation (1.2K, 3.4M). Defaults to false. */
635
+ compact?: boolean;
636
+ /** Currency code, e.g. "USD". When provided, formats as currency. */
637
+ currency?: string;
638
+ }
639
+ /**
640
+ * Format a price / numeric value for display.
641
+ *
642
+ * @example
643
+ * formatPrice(1234567.891, 'en-US', { precision: 2 }) // "1,234,567.89"
644
+ * formatPrice(1234567.891, 'de-DE', { precision: 2 }) // "1.234.567,89"
645
+ * formatPrice(1234567, 'en-US', { compact: true }) // "1.2M"
646
+ * formatPrice(1234.5, 'en-US', { currency: 'USD' }) // "$1,234.50"
647
+ */
648
+ declare function formatPrice(value: number, locale: string, options?: FormatPriceOptions): string;
649
+ /**
650
+ * Format a volume number compactly.
651
+ *
652
+ * @example
653
+ * formatVolume(1234567, 'en-US') // "1.2M"
654
+ * formatVolume(54321, 'zh-CN') // "5.4万"
655
+ */
656
+ declare function formatVolume(value: number, locale: string): string;
657
+ /**
658
+ * Format a percentage value.
659
+ *
660
+ * @example
661
+ * formatPercent(0.0523, 'en-US') // "5.23%"
662
+ * formatPercent(-0.012, 'fr-FR') // "-1,20 %"
663
+ */
664
+ declare function formatPercent(value: number, locale: string, precision?: number): string;
665
+ type DateFormatStyle = 'short' | 'medium' | 'long' | 'full';
666
+ type TimeFormatStyle = 'short' | 'medium';
667
+ /**
668
+ * Format a UNIX timestamp (ms or s) as a locale-aware date string.
669
+ *
670
+ * @param timestamp UNIX timestamp in milliseconds (or seconds — auto-detected)
671
+ * @param locale BCP-47 locale string, e.g. "en-US"
672
+ * @param style Intl DateTimeFormat date style
673
+ */
674
+ declare function formatDate(timestamp: number, locale: string, style?: DateFormatStyle): string;
675
+ /**
676
+ * Format a UNIX timestamp as a locale-aware time string.
677
+ */
678
+ declare function formatTime(timestamp: number, locale: string, style?: TimeFormatStyle): string;
679
+ /**
680
+ * Format a UNIX timestamp as a combined date+time string.
681
+ */
682
+ declare function formatDateTime(timestamp: number, locale: string, dateStyle?: DateFormatStyle, timeStyle?: TimeFormatStyle): string;
683
+ /**
684
+ * Format a duration in milliseconds as a human-readable string.
685
+ * Uses RelativeTimeFormat for relative phrases when |ms| < threshold.
686
+ *
687
+ * @example
688
+ * formatDuration(60_000, 'en-US') // "1 minute"
689
+ * formatDuration(3_600_000, 'de-DE') // "1 Stunde"
690
+ */
691
+ declare function formatDuration(ms: number, locale: string): string;
692
+ /**
693
+ * Format a Period as a short locale-aware timeframe label.
694
+ *
695
+ * @example
696
+ * formatPeriod({ multiplier: 1, timespan: 'minute' }, 'en-US') // "1m"
697
+ * formatPeriod({ multiplier: 4, timespan: 'hour' }, 'zh-CN') // "4时"
698
+ * formatPeriod({ multiplier: 1, timespan: 'day' }, 'en-US') // "1D"
699
+ */
700
+ declare function formatPeriod(period: {
701
+ multiplier: number;
702
+ timespan: string;
703
+ }, locale: string): string;
704
+ /**
705
+ * Detect an appropriate number of decimal places for a given price.
706
+ * Useful when `pricePrecision` is not specified on a SymbolInfo.
707
+ *
708
+ * @example
709
+ * detectPricePrecision(0.00001234) // 8
710
+ * detectPricePrecision(1234.56) // 2
711
+ * detectPricePrecision(50000) // 0
712
+ */
713
+ declare function detectPricePrecision(price: number): number;
714
+
715
+ type NormalizedIndicatorRow = Record<string, number | null>;
716
+ declare function createIndicatorTemplateFromPlugin<TOutput>(plugin: IndicatorPlugin<TOutput>): IndicatorTemplate<NormalizedIndicatorRow, number>;
717
+ declare function registerIndicatorPlugin<TOutput>(plugin: IndicatorPlugin<TOutput>): void;
718
+ declare function registerIndicatorPlugins(plugins: ReadonlyArray<IndicatorPlugin<unknown>>): void;
719
+
720
+ /** Cast a raw number to the Price brand. Use only when the number is known to be a price. */
721
+ declare function asPrice(n: number): Price;
722
+ /** Cast a raw number to the Volume brand. Use only when the number is known to be a volume. */
723
+ declare function asVolume(n: number): Volume;
724
+ /** Cast a raw number to the Timestamp brand (milliseconds). Use only at data ingress. */
725
+ declare function asTimestamp(n: number): Timestamp;
726
+ /**
727
+ * Returns a dispatcher that schedules `fn` on the next animation frame,
728
+ * coalescing rapid calls so only the last value is delivered.
729
+ *
730
+ * @example
731
+ * const dispatch = rafCoalesce((tick: CandleData) => chart.update(tick))
732
+ * ws.onmessage = e => dispatch(parse(e.data)) // safe to call 100×/s
733
+ */
734
+ declare function rafCoalesce<T>(fn: (value: T) => void): (value: T) => void;
735
+ /**
736
+ * OHLCV-aware frame-coalescing scheduler for financial tick streams.
737
+ *
738
+ * Unlike `rafCoalesce` (which drops intermediate values), `rafMergeTick`
739
+ * merges multiple ticks that arrive within a single animation frame into
740
+ * one financially accurate OHLCV bar:
741
+ *
742
+ * open = first tick's open (bar opening price)
743
+ * high = max across all ticks (price extreme)
744
+ * low = min across all ticks (price extreme)
745
+ * close = last tick's close (current price)
746
+ * volume = sum of all volumes (accurate volume)
747
+ *
748
+ * This is the correct coalescer for financial charting:
749
+ * - Never loses high/low extremes (important for candle accuracy)
750
+ * - Never loses volume (critical for volume indicators)
751
+ * - Delivers one merged tick per rAF frame — O(1) render cost
752
+ *
753
+ * @example
754
+ * const dispatch = rafMergeTick((merged) => chart.updateData(merged))
755
+ * ws.onmessage = e => dispatch(parseTick(e.data)) // safe to call 500×/s
756
+ */
757
+ declare function rafMergeTick(fn: (tick: CandleData) => void): (tick: CandleData) => void;
758
+ declare function deepSet(obj: object, path: string, value: unknown): void;
759
+ declare function deepClone<T>(obj: T): T;
760
+
761
+ /**
762
+ * EventBus — type-safe, zero-dependency synchronous event bus.
763
+ *
764
+ * Usage:
765
+ * const bus = new EventBus<ChartEventMap>()
766
+ * const off = bus.on('tick', candle => chart.update(candle))
767
+ * bus.emit('tick', newCandle)
768
+ * off() // unsubscribe
769
+ *
770
+ * Performance characteristics:
771
+ * - O(n_listeners) per emit — keep listener count low in hot paths
772
+ * - All events are synchronous and ordered (FIFO within an event key)
773
+ * - No allocations on emit when there are no listeners for the key
774
+ */
775
+ type ListenerOf<TMap, K extends keyof TMap> = (payload: TMap[K]) => void;
776
+ declare class EventBus<TMap extends Record<string, unknown>> {
777
+ private readonly _listeners;
778
+ /**
779
+ * Subscribe to an event. Returns an unsubscribe function.
780
+ * The returned function is idempotent — safe to call multiple times.
781
+ */
782
+ on<K extends keyof TMap>(event: K, listener: ListenerOf<TMap, K>): () => void;
783
+ /** Unsubscribe a specific listener. No-op if not currently subscribed. */
784
+ off<K extends keyof TMap>(event: K, listener: ListenerOf<TMap, K>): void;
785
+ /** Emit an event, invoking all registered listeners synchronously. */
786
+ emit<K extends keyof TMap>(event: K, payload: TMap[K]): void;
787
+ /**
788
+ * Clear all listeners for a specific event, or all listeners when called
789
+ * with no argument (useful for component teardown).
790
+ */
791
+ clear(event?: keyof TMap): void;
792
+ }
793
+
794
+ /**
795
+ * TickAnimator — smoothly interpolates the last candlestick bar as live ticks arrive.
796
+ *
797
+ * Problem it solves:
798
+ * Raw WebSocket ticks arrive at irregular bursts (10–500 ms apart). Without
799
+ * animation, the last bar jumps discretely on every tick — jarring at high
800
+ * update rates. TickAnimator interpolates close/high/low between the previous
801
+ * and next confirmed values over a configurable `duration` (default 120 ms),
802
+ * targeting 60–120 fps via requestAnimationFrame.
803
+ *
804
+ * Design rules (per SKILL.md):
805
+ * - Zero allocations inside the rAF loop — all state is pre-allocated
806
+ * - Uses `performance.now()` for sub-millisecond frame timing
807
+ * - Single rAF handle — never stacks multiple loops
808
+ * - Price fields use the branded Price type (compatible with engine CandleData)
809
+ *
810
+ * Usage:
811
+ * const animator = new TickAnimator((interpolated) => chart.updateData(interpolated))
812
+ * ws.onmessage = e => animator.feed(parsedTick)
813
+ * // On symbol change / cleanup:
814
+ * animator.cancel()
815
+ */
816
+
817
+ interface TickAnimatorOptions {
818
+ /**
819
+ * Duration of the interpolation animation in milliseconds.
820
+ * Lower = more responsive but less smooth.
821
+ * Higher = smoother but introduces lag.
822
+ * Default: 120ms (≈7 frames at 60fps, ≈12 frames at 100fps).
823
+ */
824
+ duration?: number;
825
+ /**
826
+ * Interpolation easing profile.
827
+ * - 'easeOut' (default): snappy response that settles smoothly.
828
+ * - 'linear': constant-speed interpolation, better for video-like motion.
829
+ */
830
+ easing?: 'easeOut' | 'linear';
831
+ }
832
+ declare class TickAnimator {
833
+ private readonly _onFrame;
834
+ private readonly _duration;
835
+ private readonly _easing;
836
+ /** Snapshot of the bar at the moment the last tick arrived (animation start). */
837
+ private _fromClose;
838
+ private _fromHigh;
839
+ private _fromLow;
840
+ /** Target values (the actual received tick). */
841
+ private _toClose;
842
+ private _toHigh;
843
+ private _toLow;
844
+ /** Stable fields that don't animate. */
845
+ private _timestamp;
846
+ private _open;
847
+ private _volume;
848
+ private _turnover;
849
+ /** Reused output object — written in-place every rAF frame. No allocation.
850
+ * @warning Consumers MUST NOT retain or mutate this object. It is reused
851
+ * across frames — storing a reference will see stale/corrupted data. */
852
+ private readonly _frame;
853
+ private _startTime;
854
+ private _rafId;
855
+ private _running;
856
+ constructor(onFrame: (tick: CandleData) => void, options?: TickAnimatorOptions);
857
+ /**
858
+ * Feed a new confirmed tick.
859
+ * Starts (or restarts) the interpolation from the last rendered state to `next`.
860
+ * Safe to call at any rate — will coalesce intermediate ticks automatically
861
+ * by updating the target (`_to*`) without resetting the start time.
862
+ */
863
+ feed(next: CandleData): void;
864
+ /**
865
+ * Cancel the running animation (e.g., on symbol change, unmount).
866
+ * Safe to call at any time, including when not animating.
867
+ */
868
+ cancel(): void;
869
+ private _elapsed;
870
+ private _tick;
871
+ }
872
+
873
+ /**
874
+ * RingBuffer<T> — fixed-capacity circular buffer with O(1) append, prepend, and index access.
875
+ *
876
+ * Purpose: streaming time-series data (candles, ticks) that grows at the tail
877
+ * and drops the oldest bar at the head when capacity is exceeded.
878
+ * Avoids the O(n) cost of Array.splice() during live streaming.
879
+ *
880
+ * Capacity design: set to your desired visible bar count × 2–4× for history.
881
+ * At 1 tick/second and 4h of data: 14_400 bars → use capacity = 32_768.
882
+ *
883
+ * @example
884
+ * const bars = new RingBuffer<CandleData>(8192)
885
+ * bars.push(tick) // O(1) — auto-drops oldest when full
886
+ * const last = bars.last() // O(1)
887
+ * const bar = bars.at(-1) // O(1) — negative index from tail
888
+ * bars.updateLast(merged) // O(1) — in-place last bar update
889
+ */
890
+ declare class RingBuffer<T> {
891
+ private readonly _buf;
892
+ private readonly _capacity;
893
+ /** Index of the oldest item (logical position 0). */
894
+ private _head;
895
+ /** Total items ever written — from this we derive the current fill and tail. */
896
+ private _size;
897
+ constructor(capacity: number);
898
+ get length(): number;
899
+ get capacity(): number;
900
+ get isFull(): boolean;
901
+ /**
902
+ * Append an item to the tail.
903
+ * When full, silently overwrites (and advances) the oldest item.
904
+ */
905
+ push(item: T): void;
906
+ /**
907
+ * Replace the last item in-place.
908
+ * Used to update the current live bar with a new tick merge result.
909
+ * O(1) — no allocation.
910
+ */
911
+ updateLast(item: T): void;
912
+ /**
913
+ * Access item at logical index.
914
+ * Positive: 0 = oldest, `length - 1` = newest.
915
+ * Negative: -1 = newest, -length = oldest.
916
+ * Returns `undefined` when out of bounds.
917
+ */
918
+ at(index: number): T | undefined;
919
+ /** Most recently pushed item. O(1). */
920
+ last(): T | undefined;
921
+ /** Oldest item still in the buffer. O(1). */
922
+ first(): T | undefined;
923
+ /**
924
+ * Iterate from oldest to newest without allocating a copy.
925
+ * Uses a standard iterator protocol so it works with `for…of`.
926
+ */
927
+ [Symbol.iterator](): Iterator<T>;
928
+ /**
929
+ * Return a dense snapshot copy as a plain array, oldest → newest.
930
+ * O(n). Use sparingly — this allocates. Prefer `at()` / iteration.
931
+ */
932
+ toArray(): T[];
933
+ clear(): void;
934
+ }
935
+
936
+ /**
937
+ * UndoManager — tracks chart overlay mutations for Ctrl+Z / Ctrl+Y support.
938
+ *
939
+ * Every createOverlay / removeOverlay / overrideOverlay is recorded as a
940
+ * snapshot of the full overlay list. Undo pops the stack and restores.
941
+ *
942
+ * Usage:
943
+ * const undo = new UndoManager(chart)
944
+ * chart.createOverlay(...)
945
+ * undo.record() // call after every mutation
946
+ * undo.undo() // Ctrl+Z
947
+ * undo.redo() // Ctrl+Y
948
+ */
949
+ declare class UndoManager {
950
+ private readonly _chart;
951
+ private _stack;
952
+ private _redoStack;
953
+ private _maxDepth;
954
+ private _lastSnapshot;
955
+ constructor(chart: AstroneumHandle, maxDepth?: number);
956
+ /** Record current overlay state. Call after every overlay mutation. */
957
+ record(): void;
958
+ /** Undo last mutation. Returns true if an undo was performed. */
959
+ undo(): boolean;
960
+ /** Redo last undone mutation. Returns true if a redo was performed. */
961
+ redo(): boolean;
962
+ /** Clear all undo/redo history. */
963
+ clear(): void;
964
+ get canUndo(): boolean;
965
+ get canRedo(): boolean;
966
+ }
967
+
968
+ /**
969
+ * SessionVisualizer — renders session breaks, extended-hours shading, and
970
+ * session extremes (high/low/open/close) as persistent chart overlays.
971
+ *
972
+ * Usage:
973
+ * const sv = new SessionVisualizer(chart, { timezone: 'America/New_York' })
974
+ * sv.enable()
975
+ * // session breaks and extremes auto-update when the chart scrolls/zooms
976
+ * sv.disable()
977
+ */
978
+
979
+ interface SessionConfig {
980
+ /** IANA timezone, e.g. 'America/New_York'. Default: 'America/New_York' */
981
+ timezone?: string;
982
+ /** Regular market open hour (0-23) in the configured timezone. Default: 9 (9:30 AM ET) */
983
+ openHour?: number;
984
+ /** Regular market open minute. Default: 30 */
985
+ openMinute?: number;
986
+ /** Regular market close hour. Default: 16 (4:00 PM ET) */
987
+ closeHour?: number;
988
+ /** Regular market close minute. Default: 0 */
989
+ closeMinute?: number;
990
+ /** Whether to show extended-hours shading. Default: true */
991
+ showExtendedHours?: boolean;
992
+ /** Whether to show session high/low/open/close lines. Default: true */
993
+ showSessionLevels?: boolean;
994
+ }
995
+ declare class SessionVisualizer {
996
+ private _chart;
997
+ private _config;
998
+ private _enabled;
999
+ private _animFrame;
1000
+ constructor(chart: Chart, config?: SessionConfig);
1001
+ get enabled(): boolean;
1002
+ enable(): void;
1003
+ disable(): void;
1004
+ toggle(): void;
1005
+ /** Call when the chart scrolls/zooms. Debounced via rAF. */
1006
+ refresh(): void;
1007
+ private _refresh;
1008
+ private _removeGuides;
1009
+ }
1010
+
1011
+ /**
1012
+ * Volume Profile indicator — horizontal histogram of volume at each price level.
1013
+ *
1014
+ * Usage:
1015
+ * import { volumeProfilePlugin } from '@tony01/astroneum'
1016
+ * registerIndicatorPlugin(volumeProfilePlugin)
1017
+ * chart.createIndicator({ name: 'volume_profile' })
1018
+ *
1019
+ * Or set it as a sub-indicator:
1020
+ * <AstroneumChart subIndicators={['VOL', 'volume_profile']} />
1021
+ */
1022
+ interface VolumeProfileRow {
1023
+ price: number;
1024
+ volume: number;
1025
+ /** Cumulative volume from top → this level */
1026
+ cumulative: number;
1027
+ }
1028
+ declare const volumeProfilePlugin: IndicatorPlugin<VolumeProfileRow>;
1029
+
1030
+ interface ChartTemplate {
1031
+ id: string;
1032
+ name: string;
1033
+ state: SerializedChartState;
1034
+ createdAt: string;
1035
+ }
1036
+ /**
1037
+ * ChartTemplateManager — save/load named chart configurations.
1038
+ *
1039
+ * Templates persist to localStorage and include theme, locale, timezone,
1040
+ * styles, indicators, and overlay state. Symbols and periods are intentionally
1041
+ * NOT included — templates apply chart settings to any symbol.
1042
+ *
1043
+ * Usage:
1044
+ * const templates = ChartTemplateManager.getInstance()
1045
+ * templates.save('My Setup', chart.serializeState())
1046
+ * templates.load('My Setup', chart) // applies to current chart
1047
+ */
1048
+ declare class ChartTemplateManager {
1049
+ private static _instance;
1050
+ private _templates;
1051
+ private constructor();
1052
+ static getInstance(): ChartTemplateManager;
1053
+ /** Save current chart state as a named template. Overwrites if name exists. */
1054
+ save(name: string, state: SerializedChartState): ChartTemplate;
1055
+ /** Load a template onto a chart. Returns false if template not found. */
1056
+ load(name: string, chart: AstroneumHandle): boolean;
1057
+ /** Delete a template by name. Returns false if not found. */
1058
+ delete(name: string): boolean;
1059
+ /** List all saved template names. */
1060
+ list(): string[];
1061
+ /** Get a template by name. */
1062
+ get(name: string): ChartTemplate | undefined;
1063
+ /** Get all templates. */
1064
+ getAll(): ChartTemplate[];
1065
+ private _persist;
1066
+ private _load;
1067
+ }
1068
+
1069
+ /**
1070
+ * Build a higher-timeframe bar array from lower-TF data using OHLCV resampling.
1071
+ *
1072
+ * This is a client-side resampler — it aggregates lower-TF bars into higher-TF
1073
+ * bars without requiring a second datafeed subscription. The output can be fed
1074
+ * to any indicator calc function that expects CandleData[].
1075
+ *
1076
+ * @example
1077
+ * ```ts
1078
+ * // Resample 15m bars to 4H bars
1079
+ * const h4Bars = resampleBars(bars15m, { multiplier: 4, timespan: 'hour', text: '4H' })
1080
+ * const ema4h = sma(h4Bars.map(b => b.close), 21)
1081
+ *
1082
+ * // Forward-fill to align with lower-TF bars
1083
+ * const aligned = forwardFill(h4Bars, bars15m)
1084
+ * ```
1085
+ *
1086
+ * @param data Source lower-timeframe bars (must be sorted ascending by timestamp)
1087
+ * @param period Target higher timeframe
1088
+ * @returns Resampled bars
1089
+ */
1090
+ declare function resampleBars(data: CandleData[], period: Period): CandleData[];
1091
+ /**
1092
+ * Forward-fill higher-TF indicator values to align with lower-TF bar array.
1093
+ * Each lower-TF bar gets the indicator value from the most recent higher-TF bar.
1094
+ *
1095
+ * @param htValues Higher-TF indicator values (one per higher-TF bar)
1096
+ * @param htBars Higher-TF bars (same length as htValues)
1097
+ * @param ltBars Lower-TF bars to align to
1098
+ * @returns Array of length ltBars.length, with forward-filled values
1099
+ */
1100
+ declare function forwardFill(htValues: number[], htBars: Pick<CandleData, 'timestamp'>[], ltBars: Pick<CandleData, 'timestamp'>[]): number[];
1101
+ /**
1102
+ * Convenience: create a higher-TF indicator factory.
1103
+ * Call `calc` on the full lower-TF dataset, then `getValue(i)` for each bar.
1104
+ *
1105
+ * @example
1106
+ * ```ts
1107
+ * const h4Sma = mtfIndicator(bars15m, { multiplier: 4, timespan: 'hour', text: '4H' }, (data) => sma(data, 21))
1108
+ * const h4SmaValues = bars15m.map((_, i) => h4Sma.getValue(i))
1109
+ * ```
1110
+ */
1111
+ declare function mtfIndicator<T>(data: CandleData[], higherPeriod: Period, indicatorFn: (data: CandleData[]) => T[]): {
1112
+ getValue: (index: number) => T | null;
1113
+ result: T[];
1114
+ };
1115
+
1116
+ /**
1117
+ * PositionVisualizer — renders entry, stop-loss, and take-profit levels
1118
+ * directly on the chart as colored horizontal lines with labels.
1119
+ *
1120
+ * Usage:
1121
+ * const pv = new PositionVisualizer(chart)
1122
+ * pv.show(position)
1123
+ * // When position updates:
1124
+ * pv.update(position)
1125
+ * pv.hide()
1126
+ */
1127
+
1128
+ interface PositionVisual {
1129
+ position: Position;
1130
+ stopPrice?: number;
1131
+ targetPrice?: number;
1132
+ }
1133
+ declare class PositionVisualizer {
1134
+ private _chart;
1135
+ private _active;
1136
+ constructor(chart: Chart);
1137
+ /** Show position lines on the chart. */
1138
+ show(visual: PositionVisual): void;
1139
+ /** Hide all position lines. */
1140
+ hide(): void;
1141
+ /** Update position lines (calls show internally). */
1142
+ update(visual: PositionVisual): void;
1143
+ get active(): boolean;
1144
+ private _createLine;
1145
+ private _createLabel;
1146
+ }
1147
+
1148
+ /**
1149
+ * ZigZag indicator — detects swing highs and lows using price deviation.
1150
+ *
1151
+ * A swing high occurs when price is the highest within a `deviation`-bar
1152
+ * window on both sides. The resulting array contains the pivot prices at
1153
+ * swing points, with NaN for non-pivot bars.
1154
+ *
1155
+ * @param data Source candle data
1156
+ * @param deviation Number of bars to confirm a swing (default 5)
1157
+ * @returns Array of pivot values (NaN = no pivot at that bar)
1158
+ */
1159
+ declare function zigzag(data: CandleData[], deviation?: number): number[];
1160
+ /**
1161
+ * Detect support and resistance zones from clustered pivot points.
1162
+ * Returns price levels where swings cluster within `tolerance` percentage.
1163
+ */
1164
+ declare function detectSupportResistance(data: CandleData[], zigzagDeviation?: number, clusterTolerance?: number): Array<{
1165
+ price: number;
1166
+ count: number;
1167
+ type: 'support' | 'resistance';
1168
+ }>;
1169
+ /**
1170
+ * ZigZag IndicatorPlugin — can be registered as a chart indicator and will
1171
+ * render swing lines between pivot points on the chart.
1172
+ */
1173
+ declare const zigzagPlugin: IndicatorPlugin<number>;
1174
+
1175
+ /**
1176
+ * Candlestick pattern recognition plugin.
1177
+ *
1178
+ * Scans OHLC data for common candlestick patterns and marks them on the chart.
1179
+ * Patterns are grouped: single-bar, two-bar, three-bar.
1180
+ *
1181
+ * Usage:
1182
+ * import { patternRecognitionPlugin, registerIndicatorPlugin } from '@tony01/astroneum'
1183
+ * registerIndicatorPlugin(patternRecognitionPlugin)
1184
+ * chart.createIndicator({ name: 'patterns', calcParams: [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1] })
1185
+ */
1186
+ interface PatternMatch {
1187
+ index: number;
1188
+ pattern: string;
1189
+ type: 'bullish' | 'bearish' | 'neutral';
1190
+ timestamp: number;
1191
+ high: number;
1192
+ low: number;
1193
+ }
1194
+ interface PatternDef {
1195
+ id: string;
1196
+ name: string;
1197
+ category: 'single' | 'two' | 'three';
1198
+ type: 'bullish' | 'bearish' | 'neutral';
1199
+ fn: (data: CandleData[], i: number) => PatternMatch | null;
1200
+ }
1201
+ declare const PATTERN_CATALOGUE: PatternDef[];
1202
+ declare const patternRecognitionPlugin: IndicatorPlugin<PatternMatch>;
1203
+
1204
+ /**
1205
+ * MultiPeriodLayout — renders multiple charts of the same symbol at
1206
+ * different timeframes stacked vertically. Crosshair syncs across all
1207
+ * panes at the same timestamp.
1208
+ *
1209
+ * Usage:
1210
+ * const layout = new MultiPeriodLayout({
1211
+ * container: 'chart-root',
1212
+ * symbol: { ticker: 'BTCUSDT', ... },
1213
+ * periods: [
1214
+ * { multiplier: 4, timespan: 'hour', text: '4H' },
1215
+ * { multiplier: 1, timespan: 'hour', text: '1H' },
1216
+ * { multiplier: 15, timespan: 'minute', text: '15m' },
1217
+ * ],
1218
+ * datafeed: myDatafeed,
1219
+ * })
1220
+ */
1221
+
1222
+ interface MultiPeriodLayoutOptions extends Omit<AstroneumOptions, 'symbol' | 'period'> {
1223
+ container: string | HTMLElement;
1224
+ symbol: SymbolInfo;
1225
+ /** Periods for each pane (top to bottom). Default: [4H, 1H, 15m] */
1226
+ periods?: Period[];
1227
+ /** localStorage key for persistence. Pass null to disable. */
1228
+ storageKey?: string | null;
1229
+ }
1230
+ declare class MultiPeriodLayout {
1231
+ private _container;
1232
+ private _periods;
1233
+ private _charts;
1234
+ private _options;
1235
+ private _storageKey;
1236
+ private _wrapperEl;
1237
+ constructor(options: MultiPeriodLayoutOptions);
1238
+ private _render;
1239
+ private _destroy;
1240
+ setTheme(theme: string): void;
1241
+ setLocale(locale: string): void;
1242
+ getCharts(): AstroneumHandle[];
1243
+ destroy(): void;
1244
+ }
1245
+
1246
+ /**
1247
+ * CompareOverlay — overlays a second symbol's price as a colored line on the
1248
+ * main chart pane. Uses registerIndicatorPlugin infrastructure for rendering.
1249
+ *
1250
+ * Unlike TradingView's compare feature (which supports dual Y-axis), this
1251
+ * implementation normalizes both symbols to percentage change from the first
1252
+ * visible bar, making them visually comparable on a single Y-axis.
1253
+ *
1254
+ * Usage:
1255
+ * const compare = createCompareIndicator('AAPL', myDatafeed)
1256
+ * registerIndicatorPlugin(compare)
1257
+ * chart.createIndicator({ name: 'compare_AAPL' })
1258
+ */
1259
+ interface CompareIndicatorOptions {
1260
+ /** Display name shown in legend */
1261
+ name: string;
1262
+ /** Color of the compare line */
1263
+ color?: string;
1264
+ }
1265
+ /**
1266
+ * Create an indicator plugin that overlays a comparison symbol's price data
1267
+ * normalized to percentage change.
1268
+ */
1269
+ declare function createCompareIndicator(compareSymbol: SymbolInfo, datafeed: Datafeed, period: Period, color?: string): IndicatorPlugin<number>;
1270
+
1271
+ /**
1272
+ * Depth of Market (DOM) / Order Book indicator plugin.
1273
+ *
1274
+ * Renders a ladder-style order book on the right side of the chart showing
1275
+ * cumulative bid/ask volume at each price level.
1276
+ *
1277
+ * This is a client-side approximation — a real DOM requires Level 2 market
1278
+ * data from the exchange. This implementation uses the visible candle data
1279
+ * to visualize historical volume distribution at price levels, which is
1280
+ * useful for identifying support/resistance and liquidity zones.
1281
+ *
1282
+ * Usage:
1283
+ * import { domPlugin } from '@tony01/astroneum'
1284
+ * registerIndicatorPlugin(domPlugin)
1285
+ * chart.createIndicator({ name: 'dom', calcParams: [20] }) // 20 price levels
1286
+ */
1287
+ interface DOMLevel {
1288
+ price: number;
1289
+ bidVolume: number;
1290
+ askVolume: number;
1291
+ totalVolume: number;
1292
+ }
1293
+ declare const domPlugin: IndicatorPlugin<DOMLevel>;
1294
+
1295
+ /**
1296
+ * PriceScaleTransform — log, percentage, and indexed-to-100 price axis
1297
+ * scaling implemented as data-level transformations.
1298
+ *
1299
+ * These transforms work by converting candle OHLC data before it reaches
1300
+ * the chart engine, and converting axis tick values back for display.
1301
+ * This avoids modifying the engine core Y-axis renderer.
1302
+ */
1303
+
1304
+ type PriceScaleMode = 'linear' | 'log' | 'percent' | 'indexed';
1305
+ /**
1306
+ * Transform OHLC data from linear to the target scale mode.
1307
+ * Returns a new array — does not mutate input.
1308
+ */
1309
+ declare function transformCandles(data: CandleData[], mode: PriceScaleMode, basePrice?: number): CandleData[];
1310
+ /**
1311
+ * Convert a display price from the transformed scale back to linear.
1312
+ */
1313
+ declare function untransformPrice(value: number, mode: PriceScaleMode, basePrice: number): number;
1314
+ /**
1315
+ * Format a tick label for the given scale mode.
1316
+ */
1317
+ declare function formatScaleTick(value: number, mode: PriceScaleMode, basePrice: number, precision?: number): string;
1318
+
1319
+ /**
1320
+ * Non-time-based bar generators: Renko, Kagi, Line Break, Tick, Range, Volume.
1321
+ *
1322
+ * Each function takes standard time-based OHLC data and produces a new array
1323
+ * of synthetic bars where timestamps are artificially spaced for equal-width
1324
+ * rendering on a time-based X-axis. This workaround avoids modifying the
1325
+ * engine core BarSpace/VisibleRange.
1326
+ *
1327
+ * Usage:
1328
+ * const renko = generateRenko(bars, 10) // $10 brick size
1329
+ * chart.setData(renko) // feed to chart as candles
1330
+ */
1331
+
1332
+ /**
1333
+ * Generate Renko bricks from OHLC data.
1334
+ * Each brick has a fixed price size. A new brick forms when price moves
1335
+ * beyond the brick size in either direction.
1336
+ *
1337
+ * @param data Source OHLC bars (sorted ascending)
1338
+ * @param brickSize Price size of each Renko brick
1339
+ * @returns Array of synthetic bricks with artificial timestamps
1340
+ */
1341
+ declare function generateRenko(data: CandleData[], brickSize: number): CandleData[];
1342
+ /**
1343
+ * Generate Kagi line segments from OHLC data.
1344
+ * Kagi draws vertical lines (yang = rising, yin = falling) that reverse
1345
+ * when price moves beyond a threshold.
1346
+ *
1347
+ * @param data Source OHLC bars (sorted ascending)
1348
+ * @param reversalPct Reversal threshold as percentage (e.g., 3 = 3%)
1349
+ * @returns Array of synthetic bars representing line segments
1350
+ */
1351
+ declare function generateKagi(data: CandleData[], reversalPct?: number): CandleData[];
1352
+ /**
1353
+ * Generate tick bars from raw OHLC data by simulating tick aggregation.
1354
+ * Groups bars into buckets of N "ticks" (where each source bar = 1 tick).
1355
+ *
1356
+ * @param data Source OHLC bars
1357
+ * @param ticksPerBar Number of ticks per synthetic bar
1358
+ * @returns Aggregated tick bars
1359
+ */
1360
+ declare function generateTickBars(data: CandleData[], ticksPerBar: number): CandleData[];
1361
+ /**
1362
+ * Generate range bars from OHLC data.
1363
+ * Each bar covers a fixed price range. New bar forms when price moves beyond
1364
+ * the range boundary.
1365
+ *
1366
+ * @param data Source OHLC bars
1367
+ * @param rangeSize Price range per bar
1368
+ * @returns Range bars with artificial timestamps
1369
+ */
1370
+ declare function generateRangeBars(data: CandleData[], rangeSize: number): CandleData[];
1371
+
1372
+ /**
1373
+ * Point & Figure chart generator.
1374
+ *
1375
+ * P&F charts use X and O columns on a grid instead of time-based candles.
1376
+ * X = rising price column, O = falling price column.
1377
+ * Box size = minimum price move to add a mark. Reversal = number of boxes
1378
+ * required to reverse the current column direction.
1379
+ *
1380
+ * Since the engine requires CandleData[] (time-based), we convert P&F
1381
+ * bricks into synthetic candles with artificial 1-minute timestamps
1382
+ * and uniform spacing. Each brick = one candle bar rendered as a solid
1383
+ * block (open=low, close=high for X, open=high, close=low for O).
1384
+ *
1385
+ * Usage:
1386
+ * import { generatePointAndFigure } from '@tony01/astroneum'
1387
+ * const pfBars = generatePointAndFigure(bars, 10, 3) // $10 box, 3-box reversal
1388
+ * // Feed to chart as regular candles
1389
+ *
1390
+ * Also exports a standalone renderer for true P&F grid visualization
1391
+ * via canvas (used with IndicatorPlugin infrastructure).
1392
+ */
1393
+
1394
+ interface PFConfig {
1395
+ /** Box size in price units. Default: derived from data (1% of average price) */
1396
+ boxSize?: number;
1397
+ /** Number of boxes to reverse direction. Default: 3 */
1398
+ reversal?: number;
1399
+ /** Chart type: 'pf' = X/O columns, 'hilo' = high/low based */
1400
+ method?: 'close' | 'hilo';
1401
+ }
1402
+ interface PFColumn {
1403
+ /** X (rising) or O (falling) */
1404
+ type: 'X' | 'O';
1405
+ /** Price at the top of this column */
1406
+ top: number;
1407
+ /** Price at the bottom of this column */
1408
+ bottom: number;
1409
+ /** Number of boxes in this column */
1410
+ boxes: number;
1411
+ /** Column index (0-based from left) */
1412
+ columnIndex: number;
1413
+ }
1414
+ /**
1415
+ * Generate Point & Figure columns from price data.
1416
+ * Returns the raw columns for custom rendering.
1417
+ */
1418
+ declare function computePFColumns(data: CandleData[], config?: PFConfig): PFColumn[];
1419
+ /**
1420
+ * Convert P&F columns to CandleData for rendering in the standard chart engine.
1421
+ * Each X box = green candle (open < close), each O box = red candle (open > close).
1422
+ */
1423
+ declare function pfColumnsToBars(columns: PFColumn[]): CandleData[];
1424
+ /**
1425
+ * One-shot: generate P&F bars from OHLC data.
1426
+ */
1427
+ declare function generatePointAndFigure(data: CandleData[], boxSize?: number, reversal?: number): CandleData[];
1428
+ /**
1429
+ * Point & Figure IndicatorPlugin — renders true X/O grid on the chart
1430
+ * via Canvas2D custom render path.
1431
+ */
1432
+ declare const pointAndFigurePlugin: IndicatorPlugin<number>;
1433
+
1434
+ export { AstroneumChart, AstroneumHandle, AstroneumOptions, BUILTIN_LOCALES, CandleData, type ChartTemplate, ChartTemplateManager, type CompareIndicatorOptions, type DOMLevel, Datafeed, type DateFormatStyle, type DrawingStyleTemplate, DrawingTemplates, EventBus, type FormatPriceOptions, IndicatorPlugin, MultiPeriodLayout, type MultiPeriodLayoutOptions, type OverlayStylePreset, PATTERN_CATALOGUE, type PFColumn, type PFConfig, type PatternDef, type PatternMatch, type Bar as PerformanceBar, PerformanceMode, Period, Position, type PositionVisual, PositionVisualizer, Price, type PriceScaleMode, RingBuffer, SerializedChartState, type SessionConfig, SessionVisualizer, SymbolInfo, TickAnimator, type TickAnimatorOptions, type TimeFormatStyle, Timestamp, UndoManager, Volume, type VolumeProfileRow, asPrice, asTimestamp, asVolume, computePFColumns, createCompareIndicator, createIndicatorTemplateFromPlugin, deepClone, deepSet, detectPricePrecision, detectSupportResistance, domPlugin, formatDate, formatDateTime, formatDuration, formatPercent, formatPeriod, formatPrice, formatScaleTick, formatTime, formatVolume, forwardFill, generateKagi, generatePointAndFigure, generateRangeBars, generateRenko, generateTickBars, getSupportedIndicators, getSupportedOverlays, heikinAshi, loadLocale, load as loadLocales, mtfIndicator, patternRecognitionPlugin, pfColumnsToBars, pointAndFigurePlugin, rafCoalesce, rafMergeTick, registerIndicator, registerIndicatorPlugin, registerIndicatorPlugins, registerOverlay, registerXAxis, registerYAxis, resampleBars, transformCandles, untransformPrice, volumeProfilePlugin, zigzag, zigzagPlugin };