@tradecanvas/chart 0.9.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.
Files changed (81) hide show
  1. package/dist/Chart.d.ts +148 -5
  2. package/dist/Chart.d.ts.map +1 -1
  3. package/dist/{DragDropImporter-6QOjnfSj.js → DragDropImporter-C4x09P7e.js} +446 -112
  4. package/dist/DragDropImporter-C4x09P7e.js.map +1 -0
  5. package/dist/DragDropImporter-DeXlngof.cjs +2 -0
  6. package/dist/DragDropImporter-DeXlngof.cjs.map +1 -0
  7. package/dist/charts/ChartTypeStrategy.d.ts +13 -0
  8. package/dist/charts/ChartTypeStrategy.d.ts.map +1 -1
  9. package/dist/finance/PerformanceDashboard.d.ts +43 -0
  10. package/dist/finance/PerformanceDashboard.d.ts.map +1 -0
  11. package/dist/finance/index.d.ts +4 -0
  12. package/dist/finance/index.d.ts.map +1 -1
  13. package/dist/finance/performanceData.d.ts +39 -0
  14. package/dist/finance/performanceData.d.ts.map +1 -0
  15. package/dist/index.cjs +1 -1
  16. package/dist/index.cjs.map +1 -1
  17. package/dist/index.d.ts +8 -4
  18. package/dist/index.d.ts.map +1 -1
  19. package/dist/index.js +293 -36
  20. package/dist/index.js.map +1 -1
  21. package/dist/io/index.d.ts +2 -0
  22. package/dist/io/index.d.ts.map +1 -1
  23. package/dist/io/resampleOHLCV.d.ts +29 -0
  24. package/dist/io/resampleOHLCV.d.ts.map +1 -0
  25. package/dist/plugins/PluginManager.d.ts +27 -1
  26. package/dist/plugins/PluginManager.d.ts.map +1 -1
  27. package/dist/plugins/contracts.d.ts +54 -0
  28. package/dist/plugins/contracts.d.ts.map +1 -0
  29. package/dist/plugins/index.d.ts +4 -0
  30. package/dist/plugins/index.d.ts.map +1 -1
  31. package/dist/plugins/registry.d.ts +10 -0
  32. package/dist/plugins/registry.d.ts.map +1 -0
  33. package/dist/trading/wireExecution.d.ts +26 -0
  34. package/dist/trading/wireExecution.d.ts.map +1 -0
  35. package/dist/widget/AlertNotifier.d.ts +32 -0
  36. package/dist/widget/AlertNotifier.d.ts.map +1 -0
  37. package/dist/widget/ChartWidget.d.ts +54 -1
  38. package/dist/widget/ChartWidget.d.ts.map +1 -1
  39. package/dist/widget/DrawingFavoritesStore.d.ts +22 -0
  40. package/dist/widget/DrawingFavoritesStore.d.ts.map +1 -0
  41. package/dist/widget/DrawingTemplateStore.d.ts +29 -0
  42. package/dist/widget/DrawingTemplateStore.d.ts.map +1 -0
  43. package/dist/widget/WidgetAlertsPanel.d.ts +58 -0
  44. package/dist/widget/WidgetAlertsPanel.d.ts.map +1 -0
  45. package/dist/widget/WidgetBracketBar.d.ts +21 -0
  46. package/dist/widget/WidgetBracketBar.d.ts.map +1 -0
  47. package/dist/widget/WidgetDataWindow.d.ts +41 -0
  48. package/dist/widget/WidgetDataWindow.d.ts.map +1 -0
  49. package/dist/widget/WidgetDepthLadder.d.ts +29 -0
  50. package/dist/widget/WidgetDepthLadder.d.ts.map +1 -0
  51. package/dist/widget/WidgetDrawingSidebar.d.ts +6 -0
  52. package/dist/widget/WidgetDrawingSidebar.d.ts.map +1 -1
  53. package/dist/widget/WidgetDrawingStyle.d.ts +36 -0
  54. package/dist/widget/WidgetDrawingStyle.d.ts.map +1 -0
  55. package/dist/widget/WidgetHotkeySheet.d.ts.map +1 -1
  56. package/dist/widget/WidgetIndicatorSettings.d.ts +42 -0
  57. package/dist/widget/WidgetIndicatorSettings.d.ts.map +1 -0
  58. package/dist/widget/WidgetObjectTree.d.ts +59 -0
  59. package/dist/widget/WidgetObjectTree.d.ts.map +1 -0
  60. package/dist/widget/WidgetReplayBar.d.ts +1 -1
  61. package/dist/widget/WidgetSettings.d.ts +1 -0
  62. package/dist/widget/WidgetSettings.d.ts.map +1 -1
  63. package/dist/widget/WidgetSymbolSearch.d.ts +3 -1
  64. package/dist/widget/WidgetSymbolSearch.d.ts.map +1 -1
  65. package/dist/widget/WidgetToolbar.d.ts.map +1 -1
  66. package/dist/widget/icons.d.ts.map +1 -1
  67. package/dist/widget/index.cjs +947 -15
  68. package/dist/widget/index.cjs.map +1 -1
  69. package/dist/widget/index.js +1826 -159
  70. package/dist/widget/index.js.map +1 -1
  71. package/dist/widget/ladderRows.d.ts +21 -0
  72. package/dist/widget/ladderRows.d.ts.map +1 -0
  73. package/dist/widget/types.d.ts +72 -1
  74. package/dist/widget/types.d.ts.map +1 -1
  75. package/dist/widget/widgetConfig.d.ts.map +1 -1
  76. package/dist/widget/widgetShareState.d.ts +26 -0
  77. package/dist/widget/widgetShareState.d.ts.map +1 -0
  78. package/package.json +3 -3
  79. package/dist/DragDropImporter-6QOjnfSj.js.map +0 -1
  80. package/dist/DragDropImporter-CQ3EarQn.cjs +0 -2
  81. package/dist/DragDropImporter-CQ3EarQn.cjs.map +0 -1
package/dist/index.js CHANGED
@@ -1,8 +1,8 @@
1
- import { a as e, i as t, n, o as r, r as i, s as a, t as o } from "./DragDropImporter-6QOjnfSj.js";
2
- import { DARK_TERMINAL as s, DARK_THEME as ee, DEFAULT_DRAWING_STYLE as te, DEFAULT_RECONNECT as c, DEFAULT_SIGNAL_STYLE as l, DEFAULT_STREAM_CONFIG as u, DEFAULT_TIMEFRAME_FAVORITES as d, DEFAULT_TRADE_ZONE_STYLE as f, DEFAULT_TRADING_CONFIG as p, LIGHT_THEME as m, MARKET_CRYPTO as h, MARKET_HNX as g, MARKET_HOSE as _, MARKET_NYSE as v, MARKET_UPCOM as y, TIMEFRAMES_CRYPTO as b, TIMEFRAMES_FOREX as x, TIMEFRAMES_STOCK as S, VN_COLORS as C, computePriceLimits as w, createVNTheme as T, formatNumber as E, formatVND as D, formatVolumeLoc as O, getCurrentSession as k, getLocale as A, normalizeBar as j, normalizeBarTime as M, registerLocale as N, setLocale as P, t as F } from "@tradecanvas/commons";
3
- import { AlertManager as I, Animator as L, BarCountdown as R, BaseFinanceChart as z, BinanceAdapter as B, ChartLegend as V, ChartStateManager as H, CompareRenderer as U, CrosshairTooltip as W, CurrentPriceLine as G, DEFAULT_LEGEND_CONFIG as K, DataExporter as q, DrawingBase as J, Easing as Y, FinanceCrosshair as X, IndicatorBase as Z, KeyboardHandler as ne, MockAdapter as re, ReplayManager as ie, Screenshot as ae, SessionBreaks as oe, SignalMarkerManager as se, StreamManager as ce, TickAggregator as le, TradeZoneManager as ue, UndoRedoManager as de, VolumeRenderer as fe, Watermark as pe, layoutSquarifiedTreemap as me, layoutUniformGrid as he, renderDepthChart as ge, renderEquityCurve as _e, renderGauge as ve, renderHeatmap as ye, renderSparkline as be, renderWaterfall as xe, toHeikinAshi as Se, toKagi as Ce, toLineBreak as we, toPointAndFigure as Te, toRangeBars as Ee, toRenko as De } from "@tradecanvas/core";
1
+ import { a as e, c as t, d as n, f as r, i, l as a, m as o, n as s, o as c, p as l, r as u, s as ee, t as te, u as ne } from "./DragDropImporter-C4x09P7e.js";
2
+ import { DARK_TERMINAL as re, DARK_THEME as ie, DARK_THEME as d, DEFAULT_DRAWING_STYLE as ae, DEFAULT_RECONNECT as oe, DEFAULT_SIGNAL_STYLE as se, DEFAULT_STREAM_CONFIG as ce, DEFAULT_TIMEFRAME_FAVORITES as le, DEFAULT_TRADE_ZONE_STYLE as ue, DEFAULT_TRADING_CONFIG as de, LIGHT_THEME as fe, LIGHT_THEME as f, MARKET_CRYPTO as p, MARKET_HNX as m, MARKET_HOSE as h, MARKET_NYSE as g, MARKET_UPCOM as _, TIMEFRAMES_CRYPTO as v, TIMEFRAMES_FOREX as y, TIMEFRAMES_STOCK as b, VN_COLORS as x, computePriceLimits as S, createVNTheme as C, formatNumber as w, formatVND as T, formatVolumeLoc as E, getCurrentSession as D, getLocale as O, normalizeBar as k, normalizeBarTime as A, registerLocale as j, setLocale as M, t as N, timeframeBucketStart as P } from "@tradecanvas/commons";
3
+ import { AlertManager as F, Animator as I, BarCountdown as L, BaseFinanceChart as R, BinanceAdapter as z, BybitAdapter as B, ChartLegend as V, ChartStateManager as pe, CoinbaseAdapter as me, CompareRenderer as he, CrosshairTooltip as ge, CurrentPriceLine as _e, DEFAULT_LEGEND_CONFIG as ve, DataExporter as ye, DrawingBase as be, Easing as xe, FinanceCrosshair as H, IndicatorBase as Se, KeyboardHandler as U, KrakenAdapter as Ce, MockAdapter as we, PaperExecutionAdapter as Te, PollingAdapter as Ee, ReplayManager as De, Screenshot as Oe, SessionBreaks as ke, SignalMarkerManager as Ae, StreamManager as je, TickAggregator as Me, TradeZoneManager as Ne, UndoRedoManager as Pe, VolumeRenderer as Fe, Watermark as Ie, WebSocketAdapter as Le, layoutSquarifiedTreemap as Re, layoutUniformGrid as ze, lttbDownsample as Be, lttbVisibleIndices as Ve, renderDepthChart as He, renderEquityCurve as Ue, renderGauge as We, renderHeatmap as Ge, renderSparkline as Ke, renderWaterfall as qe, toHeikinAshi as Je, toKagi as Ye, toLineBreak as Xe, toPointAndFigure as Ze, toRangeBars as Qe, toRenko as $e } from "@tradecanvas/core";
4
4
  //#region src/grid/ChartGrid.ts
5
- var Q = {
5
+ var W = {
6
6
  "1x1": {
7
7
  cols: 1,
8
8
  rows: 1
@@ -35,7 +35,7 @@ var Q = {
35
35
  cols: 2,
36
36
  rows: 3
37
37
  }
38
- }, $ = class {
38
+ }, et = class {
39
39
  root;
40
40
  cells = [];
41
41
  layout;
@@ -46,15 +46,15 @@ var Q = {
46
46
  this.options = t, this.layout = t.layout ?? "2x2", this.root = document.createElement("div"), this.root.style.cssText = "display:grid;width:100%;height:100%;overflow:hidden;", e.appendChild(this.root), this.applyLayout(), this.createCells();
47
47
  }
48
48
  applyLayout() {
49
- let { cols: e, rows: t } = Q[this.layout], n = this.options.gap ?? 1;
49
+ let { cols: e, rows: t } = W[this.layout], n = this.options.gap ?? 1;
50
50
  this.root.style.gridTemplateColumns = `repeat(${e}, 1fr)`, this.root.style.gridTemplateRows = `repeat(${t}, 1fr)`, this.root.style.gap = `${n}px`;
51
51
  }
52
52
  createCells() {
53
- let { cols: e, rows: t } = Q[this.layout], n = e * t;
53
+ let { cols: e, rows: t } = W[this.layout], n = e * t;
54
54
  for (let e = 0; e < n; e++) {
55
55
  let t = this.options.cells?.[e] ?? {}, n = document.createElement("div");
56
56
  n.style.cssText = "position:relative;overflow:hidden;min-width:0;min-height:0;", this.root.appendChild(n);
57
- let r = new i(n, {
57
+ let r = new u(n, {
58
58
  chartType: "candlestick",
59
59
  autoScale: !0,
60
60
  features: {
@@ -69,7 +69,7 @@ var Q = {
69
69
  ...this.options.chartOptions,
70
70
  ...t.chartOptions,
71
71
  theme: this.options.theme
72
- }), a = {
72
+ }), i = {
73
73
  container: n,
74
74
  chart: r,
75
75
  symbol: t.symbol ?? `Chart ${e + 1}`,
@@ -90,20 +90,20 @@ var Q = {
90
90
  if (e && a) for (let t of this.cells) t.chart !== r && t.chart.setVisibleRange(e, a);
91
91
  }
92
92
  this.syncing = !1;
93
- }), this.cells.push(a);
93
+ }), this.cells.push(i);
94
94
  }
95
95
  }
96
96
  setLayout(e) {
97
97
  if (e === this.layout) return;
98
- let t = this.cells.length, { cols: n, rows: r } = Q[e], a = n * r;
99
- if (a < t) for (let e = t - 1; e >= a; e--) {
98
+ let t = this.cells.length, { cols: n, rows: r } = W[e], i = n * r;
99
+ if (i < t) for (let e = t - 1; e >= i; e--) {
100
100
  let t = this.cells[e];
101
101
  t.chart.destroy(), t.container.remove(), this.cells.pop();
102
102
  }
103
- if (this.layout = e, this.applyLayout(), a > t) for (let e = t; e < a; e++) {
103
+ if (this.layout = e, this.applyLayout(), i > t) for (let e = t; e < i; e++) {
104
104
  let t = this.options.cells?.[e] ?? {}, n = document.createElement("div");
105
105
  n.style.cssText = "position:relative;overflow:hidden;min-width:0;min-height:0;", this.root.appendChild(n);
106
- let r = new i(n, {
106
+ let r = new u(n, {
107
107
  chartType: "candlestick",
108
108
  autoScale: !0,
109
109
  ...this.options.chartOptions,
@@ -157,13 +157,13 @@ var Q = {
157
157
  this.cells = [], this.root.remove();
158
158
  }
159
159
  }
160
- }, Oe = class extends z {
160
+ }, tt = class extends R {
161
161
  options;
162
162
  constructor(e, t) {
163
163
  super(e, t.theme), this.options = t, this.requestRender();
164
164
  }
165
165
  renderChart(e, t, n, r) {
166
- be(e, t, n, this.options, r);
166
+ Ke(e, t, n, this.options, r);
167
167
  }
168
168
  update(e) {
169
169
  this.options = {
@@ -177,15 +177,15 @@ var Q = {
177
177
  ...e
178
178
  }, this.requestRender();
179
179
  }
180
- }, ke = class extends z {
180
+ }, nt = class extends R {
181
181
  options;
182
182
  crosshair = null;
183
183
  constructor(e, t) {
184
- super(e, t.theme), this.options = t, t.crosshair !== !1 && (this.crosshair = new X(this.canvas, () => this.requestRender())), this.requestRender();
184
+ super(e, t.theme), this.options = t, t.crosshair !== !1 && (this.crosshair = new H(this.canvas, () => this.requestRender())), this.requestRender();
185
185
  }
186
186
  renderChart(e, t, n, r) {
187
187
  let i = this.crosshair?.getPosition() ?? null;
188
- ge(e, t, n, this.options, r, i);
188
+ He(e, t, n, this.options, r, i);
189
189
  }
190
190
  update(e) {
191
191
  this.options = {
@@ -202,15 +202,15 @@ var Q = {
202
202
  destroy() {
203
203
  this.crosshair?.destroy(), super.destroy();
204
204
  }
205
- }, Ae = class extends z {
205
+ }, G = class extends R {
206
206
  options;
207
207
  crosshair = null;
208
208
  constructor(e, t) {
209
- super(e, t.theme), this.options = t, t.crosshair !== !1 && (this.crosshair = new X(this.canvas, () => this.requestRender())), this.requestRender();
209
+ super(e, t.theme), this.options = t, t.crosshair !== !1 && (this.crosshair = new H(this.canvas, () => this.requestRender())), this.requestRender();
210
210
  }
211
211
  renderChart(e, t, n, r) {
212
212
  let i = this.crosshair?.getPosition() ?? null;
213
- _e(e, t, n, this.options, r, i);
213
+ Ue(e, t, n, this.options, r, i);
214
214
  }
215
215
  update(e, t) {
216
216
  this.options = {
@@ -230,7 +230,7 @@ var Q = {
230
230
  destroy() {
231
231
  this.crosshair?.destroy(), super.destroy();
232
232
  }
233
- }, je = class extends z {
233
+ }, K = class extends R {
234
234
  options;
235
235
  crosshair = null;
236
236
  cachedRects = [];
@@ -239,7 +239,7 @@ var Q = {
239
239
  lastLayoutHeight = 0;
240
240
  handleClick = null;
241
241
  constructor(e, t) {
242
- super(e, t.theme), this.options = t, this.currentData = t.data ?? [], t.crosshair !== !1 && (this.crosshair = new X(this.canvas, () => this.requestRender())), t.onCellClick && (this.handleClick = (e) => {
242
+ super(e, t.theme), this.options = t, this.currentData = t.data ?? [], t.crosshair !== !1 && (this.crosshair = new H(this.canvas, () => this.requestRender())), t.onCellClick && (this.handleClick = (e) => {
243
243
  let t = this.canvas.getBoundingClientRect(), n = e.clientX - t.left, r = e.clientY - t.top;
244
244
  this.onCanvasClick(n, r);
245
245
  }, this.canvas.addEventListener("click", this.handleClick)), this.recomputeLayout(), this.requestRender();
@@ -256,8 +256,8 @@ var Q = {
256
256
  id: e.id,
257
257
  weight: e.weight ?? (Math.abs(e.value) || 1)
258
258
  }));
259
- this.cachedRects = me(n, e, t);
260
- } else this.cachedRects = he(this.currentData.map((e) => ({ id: e.id })), e, t);
259
+ this.cachedRects = Re(n, e, t);
260
+ } else this.cachedRects = ze(this.currentData.map((e) => ({ id: e.id })), e, t);
261
261
  }
262
262
  onCanvasClick(e, t) {
263
263
  if (this.options.onCellClick) for (let n of this.cachedRects) {
@@ -272,7 +272,7 @@ var Q = {
272
272
  renderChart(e, t, n, r) {
273
273
  (t !== this.lastLayoutWidth || n !== this.lastLayoutHeight) && this.recomputeLayout();
274
274
  let i = this.crosshair?.getPosition() ?? null;
275
- ye(e, t, n, this.currentData, this.cachedRects, this.options, r, i);
275
+ Ge(e, t, n, this.currentData, this.cachedRects, this.options, r, i);
276
276
  }
277
277
  update(e) {
278
278
  this.currentData = e, this.options = {
@@ -289,15 +289,15 @@ var Q = {
289
289
  destroy() {
290
290
  this.crosshair?.destroy(), this.handleClick && this.canvas.removeEventListener("click", this.handleClick), super.destroy();
291
291
  }
292
- }, Me = class extends z {
292
+ }, rt = class extends R {
293
293
  options;
294
294
  crosshair = null;
295
295
  constructor(e, t) {
296
- super(e, t.theme), this.options = t, t.crosshair !== !1 && (this.crosshair = new X(this.canvas, () => this.requestRender())), this.requestRender();
296
+ super(e, t.theme), this.options = t, t.crosshair !== !1 && (this.crosshair = new H(this.canvas, () => this.requestRender())), this.requestRender();
297
297
  }
298
298
  renderChart(e, t, n, r) {
299
299
  let i = this.crosshair?.getPosition() ?? null;
300
- xe(e, t, n, this.options, r, i);
300
+ qe(e, t, n, this.options, r, i);
301
301
  }
302
302
  update(e) {
303
303
  this.options = {
@@ -314,12 +314,12 @@ var Q = {
314
314
  destroy() {
315
315
  this.crosshair?.destroy(), super.destroy();
316
316
  }
317
- }, Ne = 500;
318
- function Pe(e) {
317
+ }, it = 500;
318
+ function at(e) {
319
319
  let t = 1 - e;
320
320
  return 1 - t * t * t;
321
321
  }
322
- var Fe = class extends z {
322
+ var ot = class extends R {
323
323
  options;
324
324
  currentValue;
325
325
  targetValue;
@@ -330,7 +330,7 @@ var Fe = class extends z {
330
330
  super(e, t.theme), this.options = t, this.currentValue = t.value, this.targetValue = t.value, this.requestRender();
331
331
  }
332
332
  renderChart(e, t, n, r) {
333
- ve(e, t, n, this.options, r, this.currentValue);
333
+ We(e, t, n, this.options, r, this.currentValue);
334
334
  }
335
335
  setValue(e) {
336
336
  if (this.options.animate === !1) {
@@ -360,7 +360,7 @@ var Fe = class extends z {
360
360
  if (this.animationFrameId !== null) return;
361
361
  let e = () => {
362
362
  if (this.animationFrameId = null, this.animationStart === null) return;
363
- let t = this.options.animationDuration ?? Ne, n = performance.now() - this.animationStart, r = Math.min(1, n / Math.max(1, t)), i = Pe(r);
363
+ let t = this.options.animationDuration ?? it, n = performance.now() - this.animationStart, r = Math.min(1, n / Math.max(1, t)), i = at(r);
364
364
  this.currentValue = this.animationFrom + (this.targetValue - this.animationFrom) * i, this.requestRender(), r < 1 ? this.animationFrameId = requestAnimationFrame(e) : (this.currentValue = this.targetValue, this.animationStart = null);
365
365
  };
366
366
  this.animationFrameId = requestAnimationFrame(e);
@@ -371,8 +371,265 @@ var Fe = class extends z {
371
371
  destroy() {
372
372
  this.cancelAnimation(), super.destroy();
373
373
  }
374
+ }, st = [
375
+ "Jan",
376
+ "Feb",
377
+ "Mar",
378
+ "Apr",
379
+ "May",
380
+ "Jun",
381
+ "Jul",
382
+ "Aug",
383
+ "Sep",
384
+ "Oct",
385
+ "Nov",
386
+ "Dec"
387
+ ];
388
+ function q(e) {
389
+ return e.map((e) => ({
390
+ time: e.time,
391
+ value: e.equity
392
+ }));
393
+ }
394
+ function J(e) {
395
+ let t = -Infinity;
396
+ return e.map((e) => {
397
+ e.equity > t && (t = e.equity);
398
+ let n = t > 0 ? (e.equity / t - 1) * 100 : 0;
399
+ return {
400
+ time: e.time,
401
+ value: n
402
+ };
403
+ });
404
+ }
405
+ function Y(e) {
406
+ if (e.length === 0) return [];
407
+ let t = [];
408
+ for (let n of e) {
409
+ let e = P(n.time, "1M"), r = t[t.length - 1];
410
+ r && r.key === e ? r.close = n.equity : t.push({
411
+ key: e,
412
+ close: n.equity
413
+ });
414
+ }
415
+ let n = e[0].equity, r = [];
416
+ for (let e of t) {
417
+ let t = n === 0 ? 1 : n, i = (e.close / t - 1) * 100;
418
+ n = e.close;
419
+ let a = new Date(e.key), o = a.getUTCFullYear(), s = a.getUTCMonth();
420
+ r.push({
421
+ id: `${o}-${String(s + 1).padStart(2, "0")}`,
422
+ label: st[s],
423
+ group: String(o),
424
+ value: i
425
+ });
426
+ }
427
+ return r;
428
+ }
429
+ function X(e) {
430
+ return `${e > 0 ? "+" : ""}${e.toFixed(2)}%`;
431
+ }
432
+ function Z(e) {
433
+ return e > 0 ? "positive" : e < 0 ? "negative" : "neutral";
434
+ }
435
+ function Q(e) {
436
+ return [
437
+ {
438
+ label: "Total Return",
439
+ value: X(e.totalReturnPct),
440
+ tone: Z(e.totalReturnPct)
441
+ },
442
+ {
443
+ label: "CAGR",
444
+ value: X(e.cagr * 100),
445
+ tone: Z(e.cagr)
446
+ },
447
+ {
448
+ label: "Sharpe",
449
+ value: e.sharpe.toFixed(2),
450
+ tone: Z(e.sharpe)
451
+ },
452
+ {
453
+ label: "Sortino",
454
+ value: e.sortino.toFixed(2),
455
+ tone: Z(e.sortino)
456
+ },
457
+ {
458
+ label: "Max Drawdown",
459
+ value: X(e.maxDrawdownPct),
460
+ tone: "negative"
461
+ },
462
+ {
463
+ label: "Win Rate",
464
+ value: `${(e.winRate * 100).toFixed(1)}%`,
465
+ tone: "neutral"
466
+ },
467
+ {
468
+ label: "Profit Factor",
469
+ value: Number.isFinite(e.profitFactor) ? e.profitFactor.toFixed(2) : "∞",
470
+ tone: Z(e.profitFactor - 1)
471
+ },
472
+ {
473
+ label: "Trades",
474
+ value: String(e.trades),
475
+ tone: "neutral"
476
+ }
477
+ ];
478
+ }
479
+ //#endregion
480
+ //#region src/finance/PerformanceDashboard.ts
481
+ function $(e) {
482
+ return !e || e === "dark" ? d : e === "light" ? f : e;
483
+ }
484
+ var ct = class {
485
+ options;
486
+ theme;
487
+ root;
488
+ equityChart = null;
489
+ drawdownChart = null;
490
+ heatmap = null;
491
+ constructor(e, t) {
492
+ this.options = t, this.theme = $(t.theme), this.root = document.createElement("div"), this.build(), e.appendChild(this.root);
493
+ }
494
+ build() {
495
+ let e = this.theme, { result: t, title: n, subtitle: r } = this.options, i = this.panelBackground(), a = e.grid;
496
+ if (this.root.style.cssText = [
497
+ "display:flex",
498
+ "flex-direction:column",
499
+ "gap:14px",
500
+ "width:100%",
501
+ "box-sizing:border-box",
502
+ "padding:16px",
503
+ `background:${e.background}`,
504
+ `color:${e.text}`,
505
+ `font-family:${e.font.family}`
506
+ ].join(";"), n || r) {
507
+ let t = document.createElement("div");
508
+ if (n) {
509
+ let r = document.createElement("div");
510
+ r.textContent = n, r.style.cssText = `font-size:${e.font.sizeLarge}px;font-weight:600;letter-spacing:-0.01em;`, t.appendChild(r);
511
+ }
512
+ if (r) {
513
+ let n = document.createElement("div");
514
+ n.textContent = r, n.style.cssText = `font-size:${e.font.sizeSmall}px;color:${e.textSecondary};margin-top:2px;`, t.appendChild(n);
515
+ }
516
+ this.root.appendChild(t);
517
+ }
518
+ this.root.appendChild(this.buildStatsStrip(Q(t.metrics), i, a));
519
+ let o = document.createElement("div");
520
+ o.style.cssText = [
521
+ "display:grid",
522
+ "grid-template-columns:repeat(auto-fit, minmax(280px, 1fr))",
523
+ "grid-auto-rows:220px",
524
+ "gap:14px"
525
+ ].join(";"), this.root.appendChild(o);
526
+ let s = this.buildPanel("Equity Curve", i, a);
527
+ s.wrap.style.gridColumn = "1 / -1", o.appendChild(s.wrap), this.equityChart = new G(s.body, {
528
+ data: q(t.equityCurve),
529
+ theme: e,
530
+ lineColor: e.candleUp,
531
+ fillArea: !0,
532
+ crosshair: !0
533
+ });
534
+ let c = this.buildPanel("Drawdown", i, a);
535
+ o.appendChild(c.wrap), this.drawdownChart = new G(c.body, {
536
+ data: J(t.equityCurve),
537
+ theme: e,
538
+ lineColor: e.candleDown,
539
+ fillArea: !0,
540
+ crosshair: !0,
541
+ valueFormat: (e) => `${e.toFixed(1)}%`
542
+ });
543
+ let l = Y(t.equityCurve), u = this.buildPanel("Monthly Returns", i, a);
544
+ o.appendChild(u.wrap), this.heatmap = new K(u.body, {
545
+ data: l,
546
+ theme: e,
547
+ showValues: !0,
548
+ valueFormat: (e) => `${e >= 0 ? "+" : ""}${e.toFixed(1)}`,
549
+ colorScale: {
550
+ negative: e.candleDown,
551
+ zero: i,
552
+ positive: e.candleUp
553
+ }
554
+ });
555
+ }
556
+ buildStatsStrip(e, t, n) {
557
+ let r = document.createElement("div");
558
+ r.style.cssText = [
559
+ "display:grid",
560
+ "grid-template-columns:repeat(auto-fit, minmax(120px, 1fr))",
561
+ "gap:10px"
562
+ ].join(";");
563
+ let i = this.theme;
564
+ for (let a of e) {
565
+ let e = document.createElement("div");
566
+ e.style.cssText = [
567
+ `background:${t}`,
568
+ `border:1px solid ${n}`,
569
+ "border-radius:10px",
570
+ "padding:10px 12px",
571
+ "display:flex",
572
+ "flex-direction:column",
573
+ "gap:4px"
574
+ ].join(";");
575
+ let o = document.createElement("div");
576
+ o.textContent = a.label, o.style.cssText = `font-size:${i.font.sizeSmall}px;color:${i.textSecondary};text-transform:uppercase;letter-spacing:0.04em;`;
577
+ let s = document.createElement("div");
578
+ s.textContent = a.value;
579
+ let c = a.tone === "positive" ? i.candleUp : a.tone === "negative" ? i.candleDown : i.text;
580
+ s.style.cssText = `font-size:${i.font.sizeLarge}px;font-weight:600;color:${c};font-variant-numeric:tabular-nums;`, e.appendChild(o), e.appendChild(s), r.appendChild(e);
581
+ }
582
+ return r;
583
+ }
584
+ buildPanel(e, t, n) {
585
+ let r = this.theme, i = document.createElement("div");
586
+ i.style.cssText = [
587
+ `background:${t}`,
588
+ `border:1px solid ${n}`,
589
+ "border-radius:10px",
590
+ "overflow:hidden",
591
+ "display:flex",
592
+ "flex-direction:column"
593
+ ].join(";");
594
+ let a = document.createElement("div");
595
+ a.textContent = e, a.style.cssText = [
596
+ `font-size:${r.font.sizeSmall}px`,
597
+ "font-weight:600",
598
+ `color:${r.textSecondary}`,
599
+ "padding:8px 12px",
600
+ `border-bottom:1px solid ${n}`,
601
+ "text-transform:uppercase",
602
+ "letter-spacing:0.04em"
603
+ ].join(";");
604
+ let o = document.createElement("div");
605
+ return o.style.cssText = "flex:1;min-height:0;position:relative;", i.appendChild(a), i.appendChild(o), {
606
+ wrap: i,
607
+ body: o
608
+ };
609
+ }
610
+ panelBackground() {
611
+ return this.theme.name === "light" ? "rgba(0,0,0,0.02)" : "rgba(255,255,255,0.03)";
612
+ }
613
+ update(e) {
614
+ this.options = {
615
+ ...this.options,
616
+ result: e
617
+ }, this.destroyCharts(), this.root.replaceChildren(), this.build();
618
+ }
619
+ setTheme(e) {
620
+ this.theme = $(e), this.options = {
621
+ ...this.options,
622
+ theme: e
623
+ }, this.destroyCharts(), this.root.replaceChildren(), this.build();
624
+ }
625
+ destroyCharts() {
626
+ this.equityChart?.destroy(), this.drawdownChart?.destroy(), this.heatmap?.destroy(), this.equityChart = null, this.drawdownChart = null, this.heatmap = null;
627
+ }
628
+ destroy() {
629
+ this.destroyCharts(), this.root.remove();
630
+ }
374
631
  };
375
632
  //#endregion
376
- export { I as AlertManager, L as Animator, R as BarCountdown, B as BinanceAdapter, i as Chart, $ as ChartGrid, V as ChartLegend, H as ChartStateManager, U as CompareRenderer, W as CrosshairTooltip, G as CurrentPriceLine, s as DARK_TERMINAL, ee as DARK_THEME, te as DEFAULT_DRAWING_STYLE, K as DEFAULT_LEGEND_CONFIG, c as DEFAULT_RECONNECT, l as DEFAULT_SIGNAL_STYLE, u as DEFAULT_STREAM_CONFIG, d as DEFAULT_TIMEFRAME_FAVORITES, f as DEFAULT_TRADE_ZONE_STYLE, p as DEFAULT_TRADING_CONFIG, q as DataExporter, a as DataManager, ke as DepthChart, o as DragDropImporter, J as DrawingBase, Y as Easing, Ae as EquityCurveChart, Fe as GaugeChart, je as HeatmapChart, Z as IndicatorBase, ne as KeyboardHandler, m as LIGHT_THEME, e as LayoutManager, h as MARKET_CRYPTO, g as MARKET_HNX, _ as MARKET_HOSE, v as MARKET_NYSE, y as MARKET_UPCOM, re as MockAdapter, t as PluginManager, ie as ReplayManager, ae as Screenshot, oe as SessionBreaks, se as SignalMarkerManager, Oe as SparklineChart, ce as StreamManager, b as TIMEFRAMES_CRYPTO, x as TIMEFRAMES_FOREX, S as TIMEFRAMES_STOCK, r as ThemeManager, le as TickAggregator, ue as TradeZoneManager, de as UndoRedoManager, C as VN_COLORS, fe as VolumeRenderer, Me as WaterfallChart, pe as Watermark, w as computePriceLimits, T as createVNTheme, E as formatNumber, D as formatVND, O as formatVolumeLoc, k as getCurrentSession, A as getLocale, j as normalizeBar, M as normalizeBarTime, n as parseOHLCV, N as registerLocale, P as setLocale, F as t, Se as toHeikinAshi, Ce as toKagi, we as toLineBreak, Te as toPointAndFigure, Ee as toRangeBars, De as toRenko };
633
+ export { F as AlertManager, I as Animator, L as BarCountdown, z as BinanceAdapter, B as BybitAdapter, u as Chart, et as ChartGrid, V as ChartLegend, pe as ChartStateManager, me as CoinbaseAdapter, he as CompareRenderer, ge as CrosshairTooltip, _e as CurrentPriceLine, re as DARK_TERMINAL, ie as DARK_THEME, ae as DEFAULT_DRAWING_STYLE, ve as DEFAULT_LEGEND_CONFIG, oe as DEFAULT_RECONNECT, se as DEFAULT_SIGNAL_STYLE, ce as DEFAULT_STREAM_CONFIG, le as DEFAULT_TIMEFRAME_FAVORITES, ue as DEFAULT_TRADE_ZONE_STYLE, de as DEFAULT_TRADING_CONFIG, ye as DataExporter, o as DataManager, nt as DepthChart, te as DragDropImporter, be as DrawingBase, xe as Easing, G as EquityCurveChart, ot as GaugeChart, K as HeatmapChart, Se as IndicatorBase, U as KeyboardHandler, Ce as KrakenAdapter, fe as LIGHT_THEME, r as LayoutManager, p as MARKET_CRYPTO, m as MARKET_HNX, h as MARKET_HOSE, g as MARKET_NYSE, _ as MARKET_UPCOM, we as MockAdapter, a as PLUGIN_API_VERSION, Te as PaperExecutionAdapter, ct as PerformanceDashboard, i as PluginManager, Ee as PollingAdapter, De as ReplayManager, Oe as Screenshot, ke as SessionBreaks, Ae as SignalMarkerManager, tt as SparklineChart, je as StreamManager, v as TIMEFRAMES_CRYPTO, y as TIMEFRAMES_FOREX, b as TIMEFRAMES_STOCK, l as ThemeManager, Me as TickAggregator, Ne as TradeZoneManager, Pe as UndoRedoManager, x as VN_COLORS, Fe as VolumeRenderer, rt as WaterfallChart, Ie as Watermark, Le as WebSocketAdapter, e as clearGlobalPlugins, J as computeDrawdownCurve, Y as computeMonthlyReturns, S as computePriceLimits, C as createVNTheme, w as formatNumber, T as formatVND, E as formatVolumeLoc, D as getCurrentSession, c as getGlobalPlugins, O as getLocale, Be as lttbDownsample, Ve as lttbVisibleIndices, k as normalizeBar, A as normalizeBarTime, ne as overlaysForLayer, s as parseOHLCV, n as pluginKey, j as registerLocale, ee as registerPlugin, Q as selectKeyStats, M as setLocale, N as t, q as toEquityPoints, Je as toHeikinAshi, Ye as toKagi, Xe as toLineBreak, Ze as toPointAndFigure, Qe as toRangeBars, $e as toRenko, t as unregisterPlugin };
377
634
 
378
635
  //# sourceMappingURL=index.js.map