@tradecanvas/chart 0.14.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
  import { DARK_THEME as e, DEFAULT_PANEL_HEIGHT as t, LIGHT_THEME as n, LayerType as r, MIN_PANEL_HEIGHT as i, PRICE_AXIS_WIDTH as a, TIME_AXIS_HEIGHT as o, computePriceLimits as s, mergeBar as c, setLocale as l, timeframeToMs as u } from "@tradecanvas/commons";
2
- import { AlertDragHandler as d, AlertManager as f, Animator as p, AreaRenderer as m, AxisDragHandler as ee, BarCountdown as te, BarRenderer as h, BaselineRenderer as ne, CandlestickRenderer as g, ChartLegend as re, ChartStateManager as _, CompareRenderer as ie, CrosshairHandler as ae, CrosshairTooltip as oe, CurrentPriceLine as se, DataExporter as v, DepthHeatmapRenderer as ce, DrawingManager as le, DrawingRenderer as ue, EquivolumeRenderer as de, EventBus as fe, GridRenderer as pe, HLCAreaRenderer as me, HollowCandleRenderer as he, IndicatorEngine as y, InteractionManager as ge, KagiRenderer as _e, KeyboardHandler as ve, LineRenderer as ye, LineWithMarkersRenderer as be, MarketProfileRenderer as xe, MeasureOverlay as Se, PanHandler as Ce, PeriodLevelsRenderer as we, PinnedTooltip as Te, PivotMarkersRenderer as b, PointAndFigureRenderer as x, PriceAxis as S, RenderEngine as C, RenkoRenderer as w, ReplayManager as T, Screenshot as E, SessionBreaks as D, SessionShading as O, SignalMarkerManager as Ee, StepLineRenderer as De, StreamManager as Oe, TimeAxis as ke, TradeZoneManager as Ae, TradingManager as je, TradingRenderer as Me, UndoRedoManager as Ne, Viewport as Pe, VolumeCandleRenderer as Fe, VolumeProfileRenderer as Ie, VolumeRenderer as Le, Watermark as Re, ZoomHandler as ze, findDominantSwing as Be, registerBuiltInDrawingTools as Ve, registerBuiltInIndicators as k, toHeikinAshi as A, toKagi as He, toLineBreak as Ue, toPointAndFigure as We, toRangeBars as Ge, toRenko as Ke, xToBarIndex as qe } from "@tradecanvas/core";
2
+ import { AlertDragHandler as d, AlertManager as f, Animator as p, AreaRenderer as m, AxisDragHandler as ee, BarCountdown as te, BarRenderer as h, BaselineRenderer as ne, CandlestickRenderer as g, ChartLegend as re, ChartStateManager as _, CompareRenderer as ie, CrosshairHandler as ae, CrosshairTooltip as oe, CurrentPriceLine as se, DataExporter as v, DepthHeatmapRenderer as ce, DrawingManager as le, DrawingRenderer as ue, EquivolumeRenderer as de, EventBus as fe, GridRenderer as pe, HLCAreaRenderer as me, HollowCandleRenderer as he, IndicatorEngine as y, InteractionManager as ge, KagiRenderer as _e, KeyboardHandler as ve, LineRenderer as ye, LineWithMarkersRenderer as be, MarketProfileRenderer as xe, MeasureOverlay as Se, PanHandler as Ce, PaneResizeHandler as we, PeriodLevelsRenderer as Te, PinnedTooltip as Ee, PivotMarkersRenderer as De, PointAndFigureRenderer as Oe, PriceAxis as ke, RenderEngine as Ae, RenkoRenderer as b, ReplayManager as x, Screenshot as S, SessionBreaks as C, SessionShading as je, SignalMarkerManager as Me, StepLineRenderer as Ne, StreamManager as Pe, TimeAxis as Fe, TradeZoneManager as Ie, TradingManager as Le, TradingRenderer as Re, UndoRedoManager as ze, Viewport as Be, VolumeCandleRenderer as Ve, VolumeProfileRenderer as He, VolumeRenderer as Ue, Watermark as We, ZoomHandler as Ge, findDominantSwing as Ke, registerBuiltInDrawingTools as qe, registerBuiltInIndicators as w, toHeikinAshi as Je, toKagi as Ye, toLineBreak as Xe, toPointAndFigure as Ze, toRangeBars as Qe, toRenko as T, xToBarIndex as $e } from "@tradecanvas/core";
3
3
  //#region src/charts/ChartTypeStrategy.ts
4
- function Je(e) {
4
+ function et(e) {
5
5
  switch (e) {
6
6
  case "candlestick":
7
7
  case "heikinAshi":
@@ -12,46 +12,55 @@ function Je(e) {
12
12
  case "bar": return new h();
13
13
  case "hollowCandle": return new he();
14
14
  case "baseline": return new ne();
15
- case "renko": return new w();
15
+ case "renko": return new b();
16
16
  case "kagi": return new _e();
17
- case "pointAndFigure": return new x();
18
- case "volumeCandles": return new Fe();
17
+ case "pointAndFigure": return new Oe();
18
+ case "volumeCandles": return new Ve();
19
19
  case "equivolume": return new de();
20
20
  case "hlcArea": return new me();
21
- case "stepLine": return new De();
21
+ case "stepLine": return new Ne();
22
22
  case "lineWithMarkers": return new be();
23
23
  default: return new g();
24
24
  }
25
25
  }
26
- function Ye(e, t) {
26
+ function tt(e, t) {
27
27
  if (t.length === 0) return t;
28
28
  switch (e) {
29
- case "heikinAshi": return A(t);
30
- case "renko": return Ke(t, {
29
+ case "heikinAshi": return Je(t);
30
+ case "renko": return T(t, {
31
31
  brickSize: 0,
32
32
  useATR: !0,
33
33
  atrPeriod: 14
34
34
  });
35
- case "lineBreak": return Ue(t, 3);
36
- case "kagi": return He(t, 4);
37
- case "pointAndFigure": return We(t, j(t) * .01, 3);
38
- case "rangeBars": return Ge(t, { rangeSize: j(t) * .005 });
35
+ case "lineBreak": return Xe(t, 3);
36
+ case "kagi": return Ye(t, 4);
37
+ case "pointAndFigure": return Ze(t, E(t) * .01, 3);
38
+ case "rangeBars": return Qe(t, { rangeSize: E(t) * .005 });
39
39
  default: return t;
40
40
  }
41
41
  }
42
- function j(e) {
42
+ function E(e) {
43
43
  let t = 0;
44
44
  for (let n of e) t += n.close;
45
45
  return t / e.length;
46
46
  }
47
+ function nt(e, t) {
48
+ let n = t?.(e);
49
+ return n ? n.createRenderer() : et(e);
50
+ }
51
+ function rt(e, t, n) {
52
+ if (t.length === 0) return t;
53
+ let r = n?.(e);
54
+ return r?.transform ? r.transform(t) : tt(e, t);
55
+ }
47
56
  //#endregion
48
57
  //#region src/charts/IndicatorPriceRange.ts
49
- var M = {
58
+ var D = {
50
59
  min: 0,
51
60
  max: 100
52
- }, N = .1;
53
- function Xe(e, t, n) {
54
- if (!e) return { ...M };
61
+ }, O = .1;
62
+ function it(e, t, n) {
63
+ if (!e) return { ...D };
55
64
  let r = Infinity, i = -Infinity, a = 0;
56
65
  for (let [, o] of e.values) {
57
66
  if (a >= t && a <= n) for (let e in o) {
@@ -60,16 +69,16 @@ function Xe(e, t, n) {
60
69
  }
61
70
  a++;
62
71
  }
63
- if (r === Infinity) return { ...M };
72
+ if (r === Infinity) return { ...D };
64
73
  let o = i - r || 1;
65
74
  return {
66
- min: r - o * N,
67
- max: i + o * N
75
+ min: r - o * O,
76
+ max: i + o * O
68
77
  };
69
78
  }
70
79
  //#endregion
71
80
  //#region src/state/AutoSaveScheduler.ts
72
- var Ze = class {
81
+ var at = class {
73
82
  timer = null;
74
83
  delayMs = 0;
75
84
  key = null;
@@ -99,12 +108,12 @@ var Ze = class {
99
108
  };
100
109
  //#endregion
101
110
  //#region src/DataManager.ts
102
- function P(e) {
111
+ function k(e) {
103
112
  if (!e || typeof e.time != "number") return !1;
104
113
  let { open: t, high: n, low: r, close: i } = e;
105
114
  return !(!isFinite(t) || !isFinite(n) || !isFinite(r) || !isFinite(i) || t < 0 || n < 0 || r < 0 || i < 0 || n < r || e.volume !== void 0 && (!isFinite(e.volume) || e.volume < 0));
106
115
  }
107
- function F(e) {
116
+ function A(e) {
108
117
  return {
109
118
  ...e,
110
119
  high: Math.max(e.open, e.high, e.low, e.close),
@@ -112,20 +121,20 @@ function F(e) {
112
121
  volume: e.volume === void 0 ? 0 : Math.max(0, e.volume)
113
122
  };
114
123
  }
115
- var I = class {
124
+ var j = class {
116
125
  data = [];
117
126
  getData() {
118
127
  return this.data;
119
128
  }
120
129
  setData(e) {
121
- this.data = e.filter(P).map(F);
130
+ this.data = e.filter(k).map(A);
122
131
  }
123
132
  appendBar(e) {
124
- P(e) && this.data.push(F(e));
133
+ k(e) && this.data.push(A(e));
125
134
  }
126
135
  updateLastBar(e) {
127
- if (!P(e)) return;
128
- let t = F(e);
136
+ if (!k(e)) return;
137
+ let t = A(e);
129
138
  if (this.data.length === 0) {
130
139
  this.data.push(t);
131
140
  return;
@@ -141,7 +150,7 @@ var I = class {
141
150
  clear() {
142
151
  this.data = [];
143
152
  }
144
- }, L = class {
153
+ }, M = class {
145
154
  theme;
146
155
  constructor(t) {
147
156
  !t || t === "dark" ? this.theme = { ...e } : t === "light" ? this.theme = { ...n } : this.theme = { ...t };
@@ -152,7 +161,7 @@ var I = class {
152
161
  setTheme(t) {
153
162
  t === "dark" ? this.theme = { ...e } : t === "light" ? this.theme = { ...n } : this.theme = { ...t };
154
163
  }
155
- }, R = 200, z = 80, B = class {
164
+ }, N = 200, P = 80, F = class {
156
165
  panels = [];
157
166
  containerWidth = 0;
158
167
  containerHeight = 0;
@@ -164,8 +173,8 @@ var I = class {
164
173
  this.panels.push({
165
174
  id: e,
166
175
  position: n,
167
- size: r ?? (a ? R : t),
168
- minSize: a ? z : i,
176
+ size: r ?? (a ? N : t),
177
+ minSize: a ? P : i,
169
178
  content: {
170
179
  type: "indicator",
171
180
  indicatorInstanceId: e
@@ -179,7 +188,7 @@ var I = class {
179
188
  let r = this.panels.find((t) => t.id === e);
180
189
  if (r) {
181
190
  let e = r.position === "left" || r.position === "right", a = n === "left" || n === "right";
182
- r.position = n, e !== a && (r.size = a ? R : t, r.minSize = a ? z : i);
191
+ r.position = n, e !== a && (r.size = a ? N : t, r.minSize = a ? P : i);
183
192
  }
184
193
  }
185
194
  setPanelSize(e, t) {
@@ -280,15 +289,95 @@ var I = class {
280
289
  getMainChartRect() {
281
290
  return this.resolve().mainChartRect;
282
291
  }
283
- }, V = class {
284
- constructor(e) {
285
- this.indicatorEngine = e;
292
+ }, ot = 1;
293
+ function I(e, t) {
294
+ return e.filter((e) => (e.descriptor.layer ?? "overlay") === t);
295
+ }
296
+ function L(e) {
297
+ switch (e.kind) {
298
+ case "indicator": return `indicator:${e.plugin.descriptor.id}`;
299
+ case "drawing": return `drawing:${e.plugin.descriptor.type}`;
300
+ case "chartType": return `chartType:${e.plugin.descriptor.type}`;
301
+ case "overlay": return `overlay:${e.plugin.descriptor.id}`;
302
+ }
303
+ }
304
+ //#endregion
305
+ //#region src/plugins/registry.ts
306
+ var R = /* @__PURE__ */ new Map();
307
+ function st(e) {
308
+ R.set(L(e), e);
309
+ }
310
+ function ct(e) {
311
+ return R.delete(e);
312
+ }
313
+ function z() {
314
+ return [...R.values()];
315
+ }
316
+ function lt() {
317
+ R.clear();
318
+ }
319
+ //#endregion
320
+ //#region src/plugins/PluginManager.ts
321
+ var B = class {
322
+ plugins = /* @__PURE__ */ new Map();
323
+ constructor(e, t = {}) {
324
+ if (this.indicatorEngine = e, t.inheritGlobal !== !1) for (let e of z()) this.add(e);
325
+ for (let e of t.plugins ?? []) this.add(e);
326
+ }
327
+ register(e) {
328
+ this.add(e);
329
+ }
330
+ unregister(e) {
331
+ return this.plugins.delete(e);
332
+ }
333
+ list() {
334
+ return [...this.plugins.values()];
286
335
  }
287
336
  registerIndicator(e) {
288
- this.indicatorEngine.register(e);
337
+ this.add({
338
+ kind: "indicator",
339
+ plugin: e
340
+ });
341
+ }
342
+ getChartType(e) {
343
+ let t = this.plugins.get(`chartType:${e}`);
344
+ return t?.kind === "chartType" ? t.plugin : void 0;
345
+ }
346
+ getOverlays() {
347
+ let e = [];
348
+ for (let t of this.plugins.values()) t.kind === "overlay" && e.push(t.plugin);
349
+ return e;
289
350
  }
290
- }, Qe = class {
291
- static version = "0.7.0";
351
+ add(e) {
352
+ this.plugins.set(L(e), e), e.kind === "indicator" && this.indicatorEngine.register(e.plugin);
353
+ }
354
+ }, V = {
355
+ orderPlace: (e, t) => e.placeOrder(t),
356
+ orderModify: (e, t) => e.modifyOrder(t),
357
+ orderCancel: (e, t) => e.cancelOrder(t),
358
+ positionModify: (e, t) => e.modifyPosition(t),
359
+ positionClose: (e, t) => e.closePosition(t)
360
+ };
361
+ function ut(e, t) {
362
+ let n = [], r = (e) => t.setOrders(e.data ?? []), i = (e) => t.setPositions(e.data ?? []), a = (e) => t.onError(e.data ?? { message: "Execution error" });
363
+ e.on("orders", r), e.on("positions", i), e.on("error", a), n.push(() => e.off("orders", r), () => e.off("positions", i), () => e.off("error", a));
364
+ for (let r of Object.keys(V)) {
365
+ let i = V[r], a = t.onIntent(r, (n) => {
366
+ Promise.resolve(i(e, n)).catch((e) => t.onError({
367
+ message: `Execution command failed: ${r}`,
368
+ cause: e
369
+ }));
370
+ });
371
+ n.push(a);
372
+ }
373
+ return () => {
374
+ for (let e of n) e();
375
+ };
376
+ }
377
+ //#endregion
378
+ //#region src/Chart.ts
379
+ var dt = class {
380
+ static version = "1.0.0";
292
381
  engine;
293
382
  viewport;
294
383
  dataManager;
@@ -302,6 +391,8 @@ var I = class {
302
391
  tradingRenderer;
303
392
  eventBus;
304
393
  streamManager = null;
394
+ executionAdapter = null;
395
+ execTeardown = null;
305
396
  autoScrollOnNewBar = !0;
306
397
  displayDataCache = null;
307
398
  resolvedLayoutCache = null;
@@ -328,7 +419,7 @@ var I = class {
328
419
  measureOverlay;
329
420
  replayManager;
330
421
  undoRedoManager;
331
- autoSaveScheduler = new Ze((e) => this.saveState(e));
422
+ autoSaveScheduler = new at((e) => this.saveState(e));
332
423
  animator;
333
424
  crosshairTooltip;
334
425
  pinnedTooltip;
@@ -380,22 +471,22 @@ var I = class {
380
471
  logScale: n.logScale ?? !0,
381
472
  timeframes: n.timeframes ?? [],
382
473
  defaultTimeframeFavorites: n.defaultTimeframeFavorites ?? []
383
- }, e.style.position = "relative", e.style.overflow = "hidden", e.tabIndex = 0, e.style.outline = "none", this.dataManager = new I(), this.themeManager = new L(t.theme), this.layoutManager = new B(), this.indicatorEngine = new y(), this.pluginManager = new V(this.indicatorEngine), this.eventBus = new fe(), k(this.indicatorEngine), this.drawingManager = new le(), Ve(this.drawingManager), this.drawingRenderer = new ue(this.drawingManager), this.drawingManager.setRequestRender(() => {
474
+ }, e.style.position = "relative", e.style.overflow = "hidden", e.tabIndex = 0, e.style.outline = "none", this.dataManager = new j(), this.themeManager = new M(t.theme), this.layoutManager = new F(), this.indicatorEngine = new y(), this.pluginManager = new B(this.indicatorEngine, { plugins: t.plugins }), this.eventBus = new fe(), w(this.indicatorEngine), this.drawingManager = new le(), qe(this.drawingManager), this.drawingRenderer = new ue(this.drawingManager), this.drawingManager.setRequestRender(() => {
384
475
  this.syncRenderContext(), this.engine.requestRender(r.Overlay), this.scheduleAutoSave();
385
476
  }), this.drawingManager.setEventCallback((e, t) => {
386
477
  this.eventBus.emit(e, t);
387
- }), this.undoRedoManager = new Ne(), this.drawingManager.setUndoRedoManager(this.undoRedoManager), this.drawingManager.setDataGetter(() => this.dataManager.getData()), this.drawingManager.setDisplayDataGetter(() => this.getDisplayData()), t.crosshair?.mode === "magnet" && this.drawingManager.setMagnetMode("magnet"), this.tradingManager = new je({
478
+ }), this.undoRedoManager = new ze(), this.drawingManager.setUndoRedoManager(this.undoRedoManager), this.drawingManager.setDataGetter(() => this.dataManager.getData()), this.drawingManager.setDisplayDataGetter(() => this.getDisplayData()), t.crosshair?.mode === "magnet" && this.drawingManager.setMagnetMode("magnet"), this.tradingManager = new Le({
388
479
  enabled: this.features.trading,
389
480
  contextMenu: { enabled: this.features.tradingContextMenu }
390
- }), this.tradingRenderer = new Me(this.tradingManager), this.tradingManager.setContainer(e), this.tradingManager.setRequestRender(() => this.engine.requestRender(r.Overlay)), this.tradingManager.setEventCallback((e, t) => {
481
+ }), this.tradingRenderer = new Re(this.tradingManager), this.tradingManager.setContainer(e), this.tradingManager.setRequestRender(() => this.engine.requestRender(r.Overlay)), this.tradingManager.setEventCallback((e, t) => {
391
482
  this.eventBus.emit(e, t);
392
- }), this.engine = new C(e);
483
+ }), this.engine = new Ae(e);
393
484
  let i = this.engine.dprManager.getContainerSize();
394
- if (this.viewport = new Pe(i.width, i.height, t.minBarSpacing ?? 2, t.maxBarSpacing ?? 30, t.rightMargin ?? 5), this.layoutManager.resize(i.width, i.height), this.engine.onContainerResize = (e) => {
485
+ if (this.viewport = new Be(i.width, i.height, t.minBarSpacing ?? 2, t.maxBarSpacing ?? 30, t.rightMargin ?? 5), this.layoutManager.resize(i.width, i.height), this.engine.onContainerResize = (e) => {
395
486
  if (e.width <= 0 || e.height <= 0) return;
396
487
  let t = this.viewport.isAtEnd();
397
488
  this.viewport.resize(e.width, e.height), this.layoutManager.resize(e.width, e.height), this.updateViewportAndRender(t);
398
- }, this.chartRenderer = this.createChartRenderer(t.chartType), this.gridRenderer = new pe(), t.grid?.visible === !1 && this.gridRenderer.setVisible(!1), this.priceAxis = new S(), this.priceAxis.setLocale(this.numberLocale), this.timeAxis = new ke(), this.crosshairHandler = new ae(), this.crosshairHandler.setLocale(this.numberLocale), t.crosshair?.mode && this.crosshairHandler.setMode(t.crosshair.mode), this.crosshairHandler.setCallback((e, t) => {
489
+ }, this.chartRenderer = this.createChartRenderer(t.chartType), this.gridRenderer = new pe(), t.grid?.visible === !1 && this.gridRenderer.setVisible(!1), this.priceAxis = new ke(), this.priceAxis.setLocale(this.numberLocale), this.timeAxis = new Fe(), this.crosshairHandler = new ae(), this.crosshairHandler.setLocale(this.numberLocale), t.crosshair?.mode && this.crosshairHandler.setMode(t.crosshair.mode), this.crosshairHandler.setCallback((e, t) => {
399
490
  if (e !== null && t) {
400
491
  let n = this.dataManager.getData(), r = e < n.length ? n[e] : void 0;
401
492
  this.chartLegend.setHoverBar(r ?? null), r && this.crosshairTooltip.show(t, r, this.themeManager.getTheme(), this.cachedContainerSize()), this.pinnedTooltip.isPinned() && this.pinnedTooltip.reposition(this.viewport.getState(), r ?? null, e, this.themeManager.getTheme()), this.eventBus.emit("crosshairMove", {
@@ -404,12 +495,12 @@ var I = class {
404
495
  barIndex: e
405
496
  });
406
497
  } else this.crosshairTooltip.hide(), this.chartLegend.setHoverBar(null);
407
- }), this.chartLegend = new re(), this.chartLegend.setChartType(t.chartType), this.watermark = new Re(), t.watermark && this.watermark.setConfig(t.watermark), this.volumeRenderer = new Le(), this.volumeProfile = new Ie(), this.marketProfile = new xe(), this.depthHeatmap = new ce(), this.periodLevels = new we(), this.pivotMarkers = new b(), this.barCountdown = new te(), this.sessionBreaks = new D(), this.sessionShading = new O(), this.compareRenderer = new ie(), t.sessionBreaks ? this.sessionBreaks.setConfig({
498
+ }), this.chartLegend = new re(), this.chartLegend.setChartType(t.chartType), this.watermark = new We(), t.watermark && this.watermark.setConfig(t.watermark), this.volumeRenderer = new Ue(), this.volumeProfile = new He(), this.marketProfile = new xe(), this.depthHeatmap = new ce(), this.periodLevels = new Te(), this.pivotMarkers = new De(), this.barCountdown = new te(), this.sessionBreaks = new C(), this.sessionShading = new je(), this.compareRenderer = new ie(), t.sessionBreaks ? this.sessionBreaks.setConfig({
408
499
  visible: t.sessionBreaks.visible ?? !0,
409
500
  color: t.sessionBreaks.color,
410
501
  lineStyle: t.sessionBreaks.lineStyle,
411
502
  lineWidth: t.sessionBreaks.lineWidth
412
- }) : t.features?.sessionBreaks !== !1 && this.sessionBreaks.setVisible(!0), t.logScale && this.viewport.setLogScale(!0), this.animator = new p(), this.crosshairTooltip = new oe(), this.crosshairTooltip.create(e), this.pinnedTooltip = new Te(), this.pinnedTooltip.create(e), this.keyboardHandler = new ve({
503
+ }) : t.features?.sessionBreaks !== !1 && this.sessionBreaks.setVisible(!0), t.logScale && this.viewport.setLogScale(!0), this.animator = new p(), this.crosshairTooltip = new oe(), this.crosshairTooltip.create(e), this.pinnedTooltip = new Ee(), this.pinnedTooltip.create(e), this.keyboardHandler = new ve({
413
504
  scrollBars: (e) => {
414
505
  let t = this.viewport.getState().barWidth + this.viewport.getState().barSpacing;
415
506
  this.viewport.scrollBy(e * t), this.updateViewportAndRender();
@@ -461,7 +552,7 @@ var I = class {
461
552
  message: e.message,
462
553
  triggered: e.triggered
463
554
  });
464
- }), this.signalMarkerManager = new Ee(), this.signalMarkerManager.setRequestRender(() => this.engine.requestRender(r.Overlay)), this.signalMarkerManager.setDataGetter(() => this.dataManager.getData()), this.signalMarkerManager.on("added", (e) => {
555
+ }), this.signalMarkerManager = new Me(), this.signalMarkerManager.setRequestRender(() => this.engine.requestRender(r.Overlay)), this.signalMarkerManager.setDataGetter(() => this.dataManager.getData()), this.signalMarkerManager.on("added", (e) => {
465
556
  this.eventBus.emit("signalMarkerAdd", {
466
557
  id: e.id,
467
558
  source: e.source,
@@ -469,17 +560,17 @@ var I = class {
469
560
  });
470
561
  }), this.signalMarkerManager.on("removed", (e) => {
471
562
  this.eventBus.emit("signalMarkerRemove", { id: e });
472
- }), this.tradeZoneManager = new Ae(), this.tradeZoneManager.setRequestRender(() => this.engine.requestRender(r.Overlay)), this.tradeZoneManager.setDataGetter(() => this.dataManager.getData()), this.tradeZoneManager.on("added", (e) => {
563
+ }), this.tradeZoneManager = new Ie(), this.tradeZoneManager.setRequestRender(() => this.engine.requestRender(r.Overlay)), this.tradeZoneManager.setDataGetter(() => this.dataManager.getData()), this.tradeZoneManager.on("added", (e) => {
473
564
  this.eventBus.emit("tradeZoneAdd", {
474
565
  id: e.id,
475
566
  direction: e.direction
476
567
  });
477
568
  }), this.tradeZoneManager.on("removed", (e) => {
478
569
  this.eventBus.emit("tradeZoneRemove", { id: e });
479
- }), this.replayManager = new T(), this.measureOverlay = new Se(), this.interactionManager = new ge(e), this.features.panning && this.interactionManager.setPanHandler(new Ce((e) => {
570
+ }), this.replayManager = new x(), this.measureOverlay = new Se(), this.interactionManager = new ge(e), this.features.panning && this.interactionManager.setPanHandler(new Ce((e) => {
480
571
  this.viewport.scrollBy(e), this.updateViewportAndRender();
481
572
  })), this.features.zooming) {
482
- this.interactionManager.setZoomHandler(new ze((e, t) => {
573
+ this.interactionManager.setZoomHandler(new Ge((e, t) => {
483
574
  this.viewport.zoom(e, t), this.updateViewportAndRender();
484
575
  }));
485
576
  let e = new ee((e) => {
@@ -502,7 +593,8 @@ var I = class {
502
593
  let e = new d(this.alertManager, () => this.viewport.getState());
503
594
  this.interactionManager.setAlertDragHandler(e);
504
595
  }
505
- this.interactionManager.setAltClickHandler((e) => {
596
+ let a = new we();
597
+ a.configure(() => this.getResolvedLayout(), (e, t) => this.setPanelSize(e, t)), this.interactionManager.setPaneResizeHandler(a), this.interactionManager.setAltClickHandler((e) => {
506
598
  let t = this.getDisplayData();
507
599
  if (t.length === 0) return;
508
600
  let n = this.viewport.getState(), i = n.barWidth + n.barSpacing, a = Math.round((n.offset + e.x) / i);
@@ -513,7 +605,7 @@ var I = class {
513
605
  x: e.x,
514
606
  y: e.y
515
607
  }), t.length === 0) return;
516
- let n = qe(e.x, this.viewport.getState());
608
+ let n = $e(e.x, this.viewport.getState());
517
609
  n < 0 || n >= t.length || this.eventBus.emit("barClick", {
518
610
  bar: t[n],
519
611
  barIndex: n,
@@ -581,15 +673,18 @@ var I = class {
581
673
  registerIndicator(e) {
582
674
  this.pluginManager.registerIndicator(e);
583
675
  }
676
+ get plugins() {
677
+ return this.pluginManager;
678
+ }
584
679
  static indicators() {
585
680
  let e = new y();
586
- return k(e), e.getAvailableIndicators();
681
+ return w(e), e.getAvailableIndicators();
587
682
  }
588
683
  setPanelPosition(e, t) {
589
684
  this.layoutManager.setPanelPosition(e, t), this.engine.requestRender();
590
685
  }
591
686
  setPanelSize(e, t) {
592
- this.layoutManager.setPanelSize(e, t), this.engine.requestRender();
687
+ this.layoutManager.setPanelSize(e, t), this.updateViewportAndRender();
593
688
  }
594
689
  setDrawingTool(e) {
595
690
  this.features.drawings && (e && this.features.drawingTools.length > 0 && !this.features.drawingTools.includes(e) || this.drawingManager.setActiveTool(e));
@@ -622,7 +717,7 @@ var I = class {
622
717
  }
623
718
  autoFib() {
624
719
  if (!this.features.drawings) return null;
625
- let e = this.getDisplayData(), t = this.viewport.getState(), n = Be(e, t.visibleRange.from, t.visibleRange.to);
720
+ let e = this.getDisplayData(), t = this.viewport.getState(), n = Ke(e, t.visibleRange.from, t.visibleRange.to);
626
721
  return n ? this.addDrawing({
627
722
  type: "fibRetracement",
628
723
  anchors: [n[0], n[1]]
@@ -746,6 +841,20 @@ var I = class {
746
841
  isBracketActive() {
747
842
  return this.features.trading && this.tradingManager.isBracketActive();
748
843
  }
844
+ startOrderDraft(e, t) {
845
+ if (!this.features.trading) return !1;
846
+ let n = this.dataManager.getData(), r = t ?? (n.length > 0 ? n[n.length - 1].close : null);
847
+ return r === null ? !1 : (this.tradingManager.startOrderDraft(e, r), !0);
848
+ }
849
+ cancelOrderDraft() {
850
+ this.features.trading && this.tradingManager.cancelOrderDraft();
851
+ }
852
+ confirmOrderDraft() {
853
+ return this.features.trading ? this.tradingManager.confirmOrderDraft() : !1;
854
+ }
855
+ isOrderDraftActive() {
856
+ return this.features.trading && this.tradingManager.isOrderDraftActive();
857
+ }
749
858
  placeOrderIntent(e) {
750
859
  this.features.trading && this.eventBus.emit("orderPlace", e);
751
860
  }
@@ -775,7 +884,7 @@ var I = class {
775
884
  this.features.trading && this.tradingManager.setConfig(e);
776
885
  }
777
886
  async connect(e) {
778
- this.disconnectStream(), this.streamManager = new Oe(), this.streamManager.on("snapshot", (e) => {
887
+ this.disconnectStream(), this.streamManager = new Pe(), this.streamManager.on("snapshot", (e) => {
779
888
  this.setData(e);
780
889
  }), this.streamManager.on("barClose", (e) => {
781
890
  this.dataManager.appendBar(e), this.crosshairHandler.setData(this.dataManager.getData()), this.autoScrollOnNewBar && this.viewport.scrollToEnd(), this.indicatorEngine.recalculateAll(this.dataManager.getData()), this.updateViewportAndRender();
@@ -803,6 +912,27 @@ var I = class {
803
912
  disconnectStream() {
804
913
  this.streamManager &&= (this.streamManager.dispose(), null);
805
914
  }
915
+ connectExecution(e, t = {}) {
916
+ if (!this.features.trading) throw Error("connectExecution requires features.trading to be enabled");
917
+ this.disconnectExecution(), this.executionAdapter = e, this.execTeardown = ut(e, {
918
+ onIntent: (e, t) => {
919
+ let n = (e) => t(e.payload);
920
+ return this.eventBus.on(e, n), () => this.eventBus.off(e, n);
921
+ },
922
+ setOrders: (e) => this.setOrders(e),
923
+ setPositions: (e) => this.setPositions(e),
924
+ onError: (e) => this.eventBus.emit("executionError", e)
925
+ }), Promise.resolve(e.connect(t)).catch((e) => this.eventBus.emit("executionError", {
926
+ message: "Execution connect failed",
927
+ cause: e
928
+ }));
929
+ }
930
+ disconnectExecution() {
931
+ this.execTeardown &&= (this.execTeardown(), null), this.executionAdapter &&= (this.executionAdapter.disconnect(), null);
932
+ }
933
+ getExecutionAdapter() {
934
+ return this.executionAdapter;
935
+ }
806
936
  setBarCountdownVisible(e) {
807
937
  this.barCountdown.setVisible(e), this.engine.requestRender(r.UI);
808
938
  }
@@ -1028,22 +1158,22 @@ var I = class {
1028
1158
  this.chartLegend.setStatusText(e), this.engine.requestRender(r.UI);
1029
1159
  }
1030
1160
  screenshot(e) {
1031
- this.features.screenshot && E.download(this.container, e, this.themeManager.getTheme().background);
1161
+ this.features.screenshot && S.download(this.container, e, this.themeManager.getTheme().background);
1032
1162
  }
1033
1163
  async copyScreenshot() {
1034
1164
  if (!this.features.screenshot) return !1;
1035
1165
  try {
1036
- let e = await E.toBlob(this.container, this.themeManager.getTheme().background), t = globalThis.ClipboardItem;
1166
+ let e = await S.toBlob(this.container, this.themeManager.getTheme().background), t = globalThis.ClipboardItem;
1037
1167
  return !e || !navigator.clipboard?.write || !t ? !1 : (await navigator.clipboard.write([new t({ "image/png": e })]), !0);
1038
1168
  } catch {
1039
1169
  return !1;
1040
1170
  }
1041
1171
  }
1042
1172
  screenshotDataURL() {
1043
- return this.features.screenshot ? E.toDataURL(this.container, this.themeManager.getTheme().background) : null;
1173
+ return this.features.screenshot ? S.toDataURL(this.container, this.themeManager.getTheme().background) : null;
1044
1174
  }
1045
1175
  async screenshotBlob() {
1046
- return this.features.screenshot ? E.toBlob(this.container, this.themeManager.getTheme().background) : null;
1176
+ return this.features.screenshot ? S.toBlob(this.container, this.themeManager.getTheme().background) : null;
1047
1177
  }
1048
1178
  addAlert(e, t = "crossing", n, r = "price", i) {
1049
1179
  if (!this.features.alerts) return null;
@@ -1104,7 +1234,7 @@ var I = class {
1104
1234
  setTradeZoneStyle(e) {
1105
1235
  this.tradeZoneManager.setStyle(e);
1106
1236
  }
1107
- replay(e) {
1237
+ replayStart(e) {
1108
1238
  if (!this.features.replay) return;
1109
1239
  let t = this.dataManager.getData();
1110
1240
  this.replayManager.load(t), this.replayManager.on("bar", ({ bar: e, index: n }) => {
@@ -1218,16 +1348,16 @@ var I = class {
1218
1348
  this.viewport.resize(e.width, e.height), this.layoutManager.resize(e.width, e.height), this.updateViewportAndRender(n), this.eventBus.emit("resize", e);
1219
1349
  }
1220
1350
  destroy() {
1221
- this.countdownInterval && clearInterval(this.countdownInterval), this.disableAutoSave(), this.disconnectStream(), this.onWindowKeyDown &&= (window.removeEventListener("keydown", this.onWindowKeyDown), null), this.keyboardHandler = null, this.interactionManager.detach(), this.tradingManager.destroy(), this.animator.dispose(), this.crosshairTooltip.destroy(), this.pinnedTooltip.destroy(), this.replayManager.dispose(), this.undoRedoManager.clear(), this.engine.destroy(), this.eventBus.destroy(), this.container.innerHTML = "";
1351
+ this.countdownInterval && clearInterval(this.countdownInterval), this.disableAutoSave(), this.disconnectStream(), this.disconnectExecution(), this.onWindowKeyDown &&= (window.removeEventListener("keydown", this.onWindowKeyDown), null), this.keyboardHandler = null, this.interactionManager.detach(), this.tradingManager.destroy(), this.animator.dispose(), this.crosshairTooltip.destroy(), this.pinnedTooltip.destroy(), this.replayManager.dispose(), this.undoRedoManager.clear(), this.engine.destroy(), this.eventBus.destroy(), this.container.innerHTML = "";
1222
1352
  }
1223
1353
  createChartRenderer(e) {
1224
- return Je(e);
1354
+ return nt(e, (e) => this.pluginManager.getChartType(e));
1225
1355
  }
1226
1356
  getDisplayData() {
1227
1357
  if (this.displayDataCache) return this.displayDataCache;
1228
1358
  let e = this.dataManager.getData();
1229
1359
  if (e.length === 0) return e;
1230
- let t = Ye(this.options.chartType, e);
1360
+ let t = rt(this.options.chartType, e, (e) => this.pluginManager.getChartType(e));
1231
1361
  return this.displayDataCache = t, t;
1232
1362
  }
1233
1363
  scheduleRender() {
@@ -1268,7 +1398,7 @@ var I = class {
1268
1398
  buildPanelRenderInfos() {
1269
1399
  if (this.panelInfoCache) return this.panelInfoCache;
1270
1400
  let e = this.getResolvedLayout(), t = this.viewport.getState(), { from: n, to: r } = t.visibleRange, i = e.panels.map((e) => {
1271
- let i = Xe(this.indicatorEngine.getOutput(e.config.id), n, r), a = {
1401
+ let i = it(this.indicatorEngine.getOutput(e.config.id), n, r), a = {
1272
1402
  x: e.rect.x,
1273
1403
  y: e.rect.y + 20,
1274
1404
  width: e.rect.width,
@@ -1324,9 +1454,20 @@ var I = class {
1324
1454
  },
1325
1455
  theme: this.themeManager.getTheme(),
1326
1456
  data: i,
1327
- numberLocale: this.numberLocale
1457
+ numberLocale: this.numberLocale,
1458
+ renderOverlayPlugins: (e, t) => this.drawOverlayPlugins(e, t)
1328
1459
  });
1329
1460
  }
1461
+ drawOverlayPlugins(e, t) {
1462
+ let n = I(this.pluginManager.getOverlays(), t);
1463
+ if (n.length === 0) return;
1464
+ let r = {
1465
+ viewport: this.viewport.getState(),
1466
+ data: this.getDisplayData(),
1467
+ theme: this.themeManager.getTheme()
1468
+ };
1469
+ for (let t of n) t.render(e, r);
1470
+ }
1330
1471
  buildPriceLimits() {
1331
1472
  if (!this.marketConfig?.priceLimits?.enabled || !this.marketConfig.priceLimits.referencePrice) return null;
1332
1473
  let e = s(this.marketConfig.priceLimits.referencePrice, this.marketConfig);
@@ -1352,13 +1493,13 @@ var I = class {
1352
1493
  ];
1353
1494
  function J(e) {
1354
1495
  let t = e.trim();
1355
- return t ? t[0] === "[" || t[0] === "{" ? $e(t) : et(t) : {
1496
+ return t ? t[0] === "[" || t[0] === "{" ? ft(t) : pt(t) : {
1356
1497
  data: [],
1357
1498
  rowCount: 0,
1358
1499
  skipped: 0
1359
1500
  };
1360
1501
  }
1361
- function $e(e) {
1502
+ function ft(e) {
1362
1503
  let t;
1363
1504
  try {
1364
1505
  t = JSON.parse(e);
@@ -1368,19 +1509,19 @@ function $e(e) {
1368
1509
  if (!Array.isArray(t)) throw Error("Expected a JSON array of OHLCV rows");
1369
1510
  let n = [], r = 0;
1370
1511
  for (let e of t) {
1371
- let t = Array.isArray(e) ? it(e) : rt(e);
1512
+ let t = Array.isArray(e) ? _t(e) : gt(e);
1372
1513
  t ? n.push(t) : r++;
1373
1514
  }
1374
1515
  return Q(n, t.length, r);
1375
1516
  }
1376
- function et(e) {
1517
+ function pt(e) {
1377
1518
  let t = e.split(/\r?\n/).filter((e) => e.trim().length > 0);
1378
1519
  if (t.length === 0) return {
1379
1520
  data: [],
1380
1521
  rowCount: 0,
1381
1522
  skipped: 0
1382
1523
  };
1383
- let n = tt(t[0]), r = Y(t[0], n).map((e) => e.trim().toLowerCase()), i = r.some((e) => isNaN(Number(e)) && e.length > 0), a = i ? nt(r) : {
1524
+ let n = mt(t[0]), r = Y(t[0], n).map((e) => e.trim().toLowerCase()), i = r.some((e) => isNaN(Number(e)) && e.length > 0), a = i ? ht(r) : {
1384
1525
  time: 0,
1385
1526
  open: 1,
1386
1527
  high: 2,
@@ -1412,7 +1553,7 @@ function et(e) {
1412
1553
  }
1413
1554
  return Q(o, t.length - +!!i, s);
1414
1555
  }
1415
- function tt(e) {
1556
+ function mt(e) {
1416
1557
  let t = {
1417
1558
  ",": 0,
1418
1559
  ";": 0,
@@ -1432,7 +1573,7 @@ function Y(e, t) {
1432
1573
  }
1433
1574
  return n.push(r), n;
1434
1575
  }
1435
- function nt(e) {
1576
+ function ht(e) {
1436
1577
  let t = (t) => e.findIndex((e) => t.includes(e));
1437
1578
  return {
1438
1579
  time: t(H),
@@ -1443,7 +1584,7 @@ function nt(e) {
1443
1584
  volume: t(q)
1444
1585
  };
1445
1586
  }
1446
- function rt(e) {
1587
+ function gt(e) {
1447
1588
  let t = (t) => {
1448
1589
  for (let n of t) {
1449
1590
  if (e[n] !== void 0) return e[n];
@@ -1465,7 +1606,7 @@ function rt(e) {
1465
1606
  volume: Number.isFinite(s) ? s : 0
1466
1607
  };
1467
1608
  }
1468
- function it(e) {
1609
+ function _t(e) {
1469
1610
  if (e.length < 5) return null;
1470
1611
  let t = Z(String(e[0])), n = Number(e[1]), r = Number(e[2]), i = Number(e[3]), a = Number(e[4]), o = e.length >= 6 ? Number(e[5]) : 0;
1471
1612
  return t === null || ![
@@ -1505,7 +1646,7 @@ function Q(e, t, n) {
1505
1646
  }
1506
1647
  //#endregion
1507
1648
  //#region src/io/DragDropImporter.ts
1508
- var at = class {
1649
+ var vt = class {
1509
1650
  host;
1510
1651
  overlay = null;
1511
1652
  callbacks;
@@ -1573,6 +1714,6 @@ function $(e) {
1573
1714
  return e.dataTransfer?.types?.includes("Files") ?? !1;
1574
1715
  }
1575
1716
  //#endregion
1576
- export { B as a, V as i, J as n, L as o, Qe as r, I as s, at as t };
1717
+ export { lt as a, ct as c, L as d, F as f, B as i, ot as l, j as m, J as n, z as o, M as p, dt as r, st as s, vt as t, I as u };
1577
1718
 
1578
- //# sourceMappingURL=DragDropImporter-Br2ez5Gz.js.map
1719
+ //# sourceMappingURL=DragDropImporter-C4x09P7e.js.map