@tradecanvas/chart 1.1.0 → 1.3.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 (52) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +100 -26
  3. package/dist/Chart.d.ts +45 -0
  4. package/dist/Chart.d.ts.map +1 -1
  5. package/dist/DataManager.d.ts.map +1 -1
  6. package/dist/DragDropImporter-BazeSQPD.cjs +2 -0
  7. package/dist/DragDropImporter-BazeSQPD.cjs.map +1 -0
  8. package/dist/{DragDropImporter-CLtRQjKD.js → DragDropImporter-cURSpfUb.js} +390 -253
  9. package/dist/DragDropImporter-cURSpfUb.js.map +1 -0
  10. package/dist/charts/IndicatorPriceRange.d.ts +7 -3
  11. package/dist/charts/IndicatorPriceRange.d.ts.map +1 -1
  12. package/dist/index.cjs +1 -1
  13. package/dist/index.cjs.map +1 -1
  14. package/dist/index.d.ts +4 -3
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js +29 -29
  17. package/dist/index.js.map +1 -1
  18. package/dist/interaction/verticalPanGate.d.ts +22 -0
  19. package/dist/interaction/verticalPanGate.d.ts.map +1 -0
  20. package/dist/layout/LayoutManager.d.ts +3 -0
  21. package/dist/layout/LayoutManager.d.ts.map +1 -1
  22. package/dist/layout/priceAxisWidth.d.ts +22 -0
  23. package/dist/layout/priceAxisWidth.d.ts.map +1 -0
  24. package/dist/widget/ChartWidget.d.ts +24 -1
  25. package/dist/widget/ChartWidget.d.ts.map +1 -1
  26. package/dist/widget/WidgetDrawingSidebar.d.ts.map +1 -1
  27. package/dist/widget/WidgetHotkeySheet.d.ts +4 -2
  28. package/dist/widget/WidgetHotkeySheet.d.ts.map +1 -1
  29. package/dist/widget/WidgetLoadingOverlay.d.ts +43 -0
  30. package/dist/widget/WidgetLoadingOverlay.d.ts.map +1 -0
  31. package/dist/widget/WidgetObjectTree.d.ts +1 -1
  32. package/dist/widget/WidgetObjectTree.d.ts.map +1 -1
  33. package/dist/widget/WidgetSettings.d.ts +3 -1
  34. package/dist/widget/WidgetSettings.d.ts.map +1 -1
  35. package/dist/widget/WidgetToolbar.d.ts +4 -1
  36. package/dist/widget/WidgetToolbar.d.ts.map +1 -1
  37. package/dist/widget/WidgetWatchlist.d.ts +4 -1
  38. package/dist/widget/WidgetWatchlist.d.ts.map +1 -1
  39. package/dist/widget/i18n.d.ts +70 -0
  40. package/dist/widget/i18n.d.ts.map +1 -0
  41. package/dist/widget/icons.d.ts.map +1 -1
  42. package/dist/widget/index.cjs +2554 -2380
  43. package/dist/widget/index.cjs.map +1 -1
  44. package/dist/widget/index.js +725 -258
  45. package/dist/widget/index.js.map +1 -1
  46. package/dist/widget/types.d.ts +10 -0
  47. package/dist/widget/types.d.ts.map +1 -1
  48. package/dist/widget/widgetConfig.d.ts.map +1 -1
  49. package/package.json +6 -3
  50. package/dist/DragDropImporter-CLtRQjKD.js.map +0 -1
  51. package/dist/DragDropImporter-pPS0fl5H.cjs +0 -2
  52. package/dist/DragDropImporter-pPS0fl5H.cjs.map +0 -1
package/dist/index.cjs CHANGED
@@ -1,2 +1,2 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./DragDropImporter-pPS0fl5H.cjs`);let t=require(`@tradecanvas/commons`),n=require(`@tradecanvas/core`);var r={"1x1":{cols:1,rows:1},"1x2":{cols:2,rows:1},"2x1":{cols:1,rows:2},"2x2":{cols:2,rows:2},"1x3":{cols:3,rows:1},"3x1":{cols:1,rows:3},"2x3":{cols:3,rows:2},"3x2":{cols:2,rows:3}},i=class{root;cells=[];layout;options;destroyed=!1;syncing=!1;constructor(e,t={}){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()}applyLayout(){let{cols:e,rows:t}=r[this.layout],n=this.options.gap??1;this.root.style.gridTemplateColumns=`repeat(${e}, 1fr)`,this.root.style.gridTemplateRows=`repeat(${t}, 1fr)`,this.root.style.gap=`${n}px`}createCells(){let{cols:t,rows:n}=r[this.layout],i=t*n;for(let t=0;t<i;t++){let n=this.options.cells?.[t]??{},r=document.createElement(`div`);r.style.cssText=`position:relative;overflow:hidden;min-width:0;min-height:0;`,this.root.appendChild(r);let i=new e.r(r,{chartType:`candlestick`,autoScale:!0,features:{crosshair:!0,keyboard:!0,volume:!0,legend:!0,priceAxis:!0,timeAxis:!0,grid:!0},...this.options.chartOptions,...n.chartOptions,theme:this.options.theme}),a={container:r,chart:i,symbol:n.symbol??`Chart ${t+1}`,timeframe:n.timeframe??`5m`};this.options.syncCrosshair!==!1&&i.on(`crosshairMove`,e=>{if(!this.syncing){this.syncing=!0;for(let t of this.cells)t.chart!==i&&t.chart.setCrosshairPosition(e.payload.point);this.syncing=!1}}),this.options.syncTimeAxis!==!1&&i.on(`visibleRangeChange`,e=>{if(this.syncing)return;this.syncing=!0;let{from:t,to:n}=e.payload,r=i.getData();if(r.length>0&&t>=0&&n<r.length){let e=r[t]?.time,a=r[n]?.time;if(e&&a)for(let t of this.cells)t.chart!==i&&t.chart.setVisibleRange(e,a)}this.syncing=!1}),this.cells.push(a)}}setLayout(t){if(t===this.layout)return;let n=this.cells.length,{cols:i,rows:a}=r[t],o=i*a;if(o<n)for(let e=n-1;e>=o;e--){let t=this.cells[e];t.chart.destroy(),t.container.remove(),this.cells.pop()}if(this.layout=t,this.applyLayout(),o>n)for(let t=n;t<o;t++){let n=this.options.cells?.[t]??{},r=document.createElement(`div`);r.style.cssText=`position:relative;overflow:hidden;min-width:0;min-height:0;`,this.root.appendChild(r);let i=new e.r(r,{chartType:`candlestick`,autoScale:!0,...this.options.chartOptions,...n.chartOptions,theme:this.options.theme});this.cells.push({container:r,chart:i,symbol:n.symbol??`Chart ${t+1}`,timeframe:n.timeframe??`5m`})}}getChart(e){return this.cells[e]?.chart??null}getCharts(){return this.cells.map(e=>e.chart)}getCellCount(){return this.cells.length}setData(e,t){this.cells[e]?.chart.setData(t)}setAllData(e){for(let t of this.cells)t.chart.setData(e)}async connectCell(e,t){let n=this.cells[e];n&&(n.symbol=t.symbol,n.timeframe=t.timeframe,await n.chart.connect(t))}async connectAll(e,t,n,r=500){let i=[];for(let a=0;a<this.cells.length&&a<t.length;a++)i.push(this.connectCell(a,{adapter:e,symbol:t[a],timeframe:n,historyLimit:r}));await Promise.all(i)}setTheme(e){for(let t of this.cells)t.chart.setTheme(e)}destroy(){if(!this.destroyed){this.destroyed=!0;for(let e of this.cells)e.chart.destroy(),e.container.remove();this.cells=[],this.root.remove()}}},a=class extends n.BaseFinanceChart{options;constructor(e,t){super(e,t.theme),this.options=t,this.requestRender()}renderChart(e,t,r,i){(0,n.renderSparkline)(e,t,r,this.options,i)}update(e){this.options={...this.options,data:e},this.requestRender()}setOptions(e){this.options={...this.options,...e},this.requestRender()}},o=class extends n.BaseFinanceChart{options;crosshair=null;constructor(e,t){super(e,t.theme),this.options=t,t.crosshair!==!1&&(this.crosshair=new n.FinanceCrosshair(this.canvas,()=>this.requestRender())),this.requestRender()}renderChart(e,t,r,i){let a=this.crosshair?.getPosition()??null;(0,n.renderDepthChart)(e,t,r,this.options,i,a)}update(e){this.options={...this.options,data:e},this.requestRender()}setOptions(e){this.options={...this.options,...e},this.requestRender()}destroy(){this.crosshair?.destroy(),super.destroy()}},s=class extends n.BaseFinanceChart{options;crosshair=null;constructor(e,t){super(e,t.theme),this.options=t,t.crosshair!==!1&&(this.crosshair=new n.FinanceCrosshair(this.canvas,()=>this.requestRender())),this.requestRender()}renderChart(e,t,r,i){let a=this.crosshair?.getPosition()??null;(0,n.renderEquityCurve)(e,t,r,this.options,i,a)}update(e,t){this.options={...this.options,data:e},t!==void 0&&(this.options={...this.options,benchmark:t}),this.requestRender()}setOptions(e){this.options={...this.options,...e},this.requestRender()}destroy(){this.crosshair?.destroy(),super.destroy()}},c=class extends n.BaseFinanceChart{options;crosshair=null;cachedRects=[];currentData=[];lastLayoutWidth=0;lastLayoutHeight=0;handleClick=null;constructor(e,t){super(e,t.theme),this.options=t,this.currentData=t.data??[],t.crosshair!==!1&&(this.crosshair=new n.FinanceCrosshair(this.canvas,()=>this.requestRender())),t.onCellClick&&(this.handleClick=e=>{let t=this.canvas.getBoundingClientRect(),n=e.clientX-t.left,r=e.clientY-t.top;this.onCanvasClick(n,r)},this.canvas.addEventListener(`click`,this.handleClick)),this.recomputeLayout(),this.requestRender()}recomputeLayout(){let e={x:0,y:0,width:this.width,height:this.height},t=this.options.cellPadding??2;if(this.lastLayoutWidth=this.width,this.lastLayoutHeight=this.height,this.options.weighted){let r=this.currentData.map(e=>({id:e.id,weight:e.weight??(Math.abs(e.value)||1)}));this.cachedRects=(0,n.layoutSquarifiedTreemap)(r,e,t)}else this.cachedRects=(0,n.layoutUniformGrid)(this.currentData.map(e=>({id:e.id})),e,t)}onCanvasClick(e,t){if(this.options.onCellClick)for(let n of this.cachedRects){let r=n.rect;if(e>=r.x&&e<=r.x+r.width&&t>=r.y&&t<=r.y+r.height){let e=this.currentData.find(e=>e.id===n.id);e&&this.options.onCellClick(e);return}}}renderChart(e,t,r,i){(t!==this.lastLayoutWidth||r!==this.lastLayoutHeight)&&this.recomputeLayout();let a=this.crosshair?.getPosition()??null;(0,n.renderHeatmap)(e,t,r,this.currentData,this.cachedRects,this.options,i,a)}update(e){this.currentData=e,this.options={...this.options,data:e},this.recomputeLayout(),this.requestRender()}setOptions(e){this.options={...this.options,...e},e.data&&(this.currentData=e.data),this.recomputeLayout(),this.requestRender()}destroy(){this.crosshair?.destroy(),this.handleClick&&this.canvas.removeEventListener(`click`,this.handleClick),super.destroy()}},l=class extends n.BaseFinanceChart{options;crosshair=null;constructor(e,t){super(e,t.theme),this.options=t,t.crosshair!==!1&&(this.crosshair=new n.FinanceCrosshair(this.canvas,()=>this.requestRender())),this.requestRender()}renderChart(e,t,r,i){let a=this.crosshair?.getPosition()??null;(0,n.renderWaterfall)(e,t,r,this.options,i,a)}update(e){this.options={...this.options,data:e},this.requestRender()}setOptions(e){this.options={...this.options,...e},this.requestRender()}destroy(){this.crosshair?.destroy(),super.destroy()}},u=500;function d(e){let t=1-e;return 1-t*t*t}var f=class extends n.BaseFinanceChart{options;currentValue;targetValue;animationStart=null;animationFrom=0;animationFrameId=null;constructor(e,t){super(e,t.theme),this.options=t,this.currentValue=t.value,this.targetValue=t.value,this.requestRender()}renderChart(e,t,r,i){(0,n.renderGauge)(e,t,r,this.options,i,this.currentValue)}setValue(e){if(this.options.animate===!1){this.cancelAnimation(),this.currentValue=e,this.targetValue=e,this.options={...this.options,value:e},this.requestRender();return}this.targetValue=e,this.animationFrom=this.currentValue,this.animationStart=performance.now(),this.options={...this.options,value:e},this.startAnimationLoop()}setOptions(e){let t={...this.options,...e};if(e.value!==void 0&&e.value!==this.targetValue){this.options=t,this.setValue(e.value);return}this.options=t,this.requestRender()}startAnimationLoop(){if(this.animationFrameId!==null)return;let e=()=>{if(this.animationFrameId=null,this.animationStart===null)return;let t=this.options.animationDuration??u,n=performance.now()-this.animationStart,r=Math.min(1,n/Math.max(1,t)),i=d(r);this.currentValue=this.animationFrom+(this.targetValue-this.animationFrom)*i,this.requestRender(),r<1?this.animationFrameId=requestAnimationFrame(e):(this.currentValue=this.targetValue,this.animationStart=null)};this.animationFrameId=requestAnimationFrame(e)}cancelAnimation(){this.animationFrameId!==null&&(cancelAnimationFrame(this.animationFrameId),this.animationFrameId=null),this.animationStart=null}destroy(){this.cancelAnimation(),super.destroy()}},p=[`Jan`,`Feb`,`Mar`,`Apr`,`May`,`Jun`,`Jul`,`Aug`,`Sep`,`Oct`,`Nov`,`Dec`];function m(e){return e.map(e=>({time:e.time,value:e.equity}))}function h(e){let t=-1/0;return e.map(e=>{e.equity>t&&(t=e.equity);let n=t>0?(e.equity/t-1)*100:0;return{time:e.time,value:n}})}function g(e){if(e.length===0)return[];let n=[];for(let r of e){let e=(0,t.timeframeBucketStart)(r.time,`1M`),i=n[n.length-1];i&&i.key===e?i.close=r.equity:n.push({key:e,close:r.equity})}let r=e[0].equity,i=[];for(let e of n){let t=r===0?1:r,n=(e.close/t-1)*100;r=e.close;let a=new Date(e.key),o=a.getUTCFullYear(),s=a.getUTCMonth();i.push({id:`${o}-${String(s+1).padStart(2,`0`)}`,label:p[s],group:String(o),value:n})}return i}function _(e){return`${e>0?`+`:``}${e.toFixed(2)}%`}function v(e){return e>0?`positive`:e<0?`negative`:`neutral`}function y(e){return[{label:`Total Return`,value:_(e.totalReturnPct),tone:v(e.totalReturnPct)},{label:`CAGR`,value:_(e.cagr*100),tone:v(e.cagr)},{label:`Sharpe`,value:e.sharpe.toFixed(2),tone:v(e.sharpe)},{label:`Sortino`,value:e.sortino.toFixed(2),tone:v(e.sortino)},{label:`Max Drawdown`,value:_(e.maxDrawdownPct),tone:`negative`},{label:`Win Rate`,value:`${(e.winRate*100).toFixed(1)}%`,tone:`neutral`},{label:`Profit Factor`,value:Number.isFinite(e.profitFactor)?e.profitFactor.toFixed(2):`∞`,tone:v(e.profitFactor-1)},{label:`Trades`,value:String(e.trades),tone:`neutral`}]}function b(e){return!e||e===`dark`?t.DARK_THEME:e===`light`?t.LIGHT_THEME:e}var x=class{options;theme;root;equityChart=null;drawdownChart=null;heatmap=null;constructor(e,t){this.options=t,this.theme=b(t.theme),this.root=document.createElement(`div`),this.build(),e.appendChild(this.root)}build(){let e=this.theme,{result:t,title:n,subtitle:r}=this.options,i=this.panelBackground(),a=e.grid;if(this.root.style.cssText=[`display:flex`,`flex-direction:column`,`gap:14px`,`width:100%`,`box-sizing:border-box`,`padding:16px`,`background:${e.background}`,`color:${e.text}`,`font-family:${e.font.family}`].join(`;`),n||r){let t=document.createElement(`div`);if(n){let r=document.createElement(`div`);r.textContent=n,r.style.cssText=`font-size:${e.font.sizeLarge}px;font-weight:600;letter-spacing:-0.01em;`,t.appendChild(r)}if(r){let n=document.createElement(`div`);n.textContent=r,n.style.cssText=`font-size:${e.font.sizeSmall}px;color:${e.textSecondary};margin-top:2px;`,t.appendChild(n)}this.root.appendChild(t)}this.root.appendChild(this.buildStatsStrip(y(t.metrics),i,a));let o=document.createElement(`div`);o.style.cssText=[`display:grid`,`grid-template-columns:repeat(auto-fit, minmax(280px, 1fr))`,`grid-auto-rows:220px`,`gap:14px`].join(`;`),this.root.appendChild(o);let l=this.buildPanel(`Equity Curve`,i,a);l.wrap.style.gridColumn=`1 / -1`,o.appendChild(l.wrap),this.equityChart=new s(l.body,{data:m(t.equityCurve),theme:e,lineColor:e.candleUp,fillArea:!0,crosshair:!0});let u=this.buildPanel(`Drawdown`,i,a);o.appendChild(u.wrap),this.drawdownChart=new s(u.body,{data:h(t.equityCurve),theme:e,lineColor:e.candleDown,fillArea:!0,crosshair:!0,valueFormat:e=>`${e.toFixed(1)}%`});let d=g(t.equityCurve),f=this.buildPanel(`Monthly Returns`,i,a);o.appendChild(f.wrap),this.heatmap=new c(f.body,{data:d,theme:e,showValues:!0,valueFormat:e=>`${e>=0?`+`:``}${e.toFixed(1)}`,colorScale:{negative:e.candleDown,zero:i,positive:e.candleUp}})}buildStatsStrip(e,t,n){let r=document.createElement(`div`);r.style.cssText=[`display:grid`,`grid-template-columns:repeat(auto-fit, minmax(120px, 1fr))`,`gap:10px`].join(`;`);let i=this.theme;for(let a of e){let e=document.createElement(`div`);e.style.cssText=[`background:${t}`,`border:1px solid ${n}`,`border-radius:10px`,`padding:10px 12px`,`display:flex`,`flex-direction:column`,`gap:4px`].join(`;`);let o=document.createElement(`div`);o.textContent=a.label,o.style.cssText=`font-size:${i.font.sizeSmall}px;color:${i.textSecondary};text-transform:uppercase;letter-spacing:0.04em;`;let s=document.createElement(`div`);s.textContent=a.value;let c=a.tone===`positive`?i.candleUp:a.tone===`negative`?i.candleDown:i.text;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)}return r}buildPanel(e,t,n){let r=this.theme,i=document.createElement(`div`);i.style.cssText=[`background:${t}`,`border:1px solid ${n}`,`border-radius:10px`,`overflow:hidden`,`display:flex`,`flex-direction:column`].join(`;`);let a=document.createElement(`div`);a.textContent=e,a.style.cssText=[`font-size:${r.font.sizeSmall}px`,`font-weight:600`,`color:${r.textSecondary}`,`padding:8px 12px`,`border-bottom:1px solid ${n}`,`text-transform:uppercase`,`letter-spacing:0.04em`].join(`;`);let o=document.createElement(`div`);return o.style.cssText=`flex:1;min-height:0;position:relative;`,i.appendChild(a),i.appendChild(o),{wrap:i,body:o}}panelBackground(){return this.theme.name===`light`?`rgba(0,0,0,0.02)`:`rgba(255,255,255,0.03)`}update(e){this.options={...this.options,result:e},this.destroyCharts(),this.root.replaceChildren(),this.build()}setTheme(e){this.theme=b(e),this.options={...this.options,theme:e},this.destroyCharts(),this.root.replaceChildren(),this.build()}destroyCharts(){this.equityChart?.destroy(),this.drawdownChart?.destroy(),this.heatmap?.destroy(),this.equityChart=null,this.drawdownChart=null,this.heatmap=null}destroy(){this.destroyCharts(),this.root.remove()}};Object.defineProperty(exports,`AlertManager`,{enumerable:!0,get:function(){return n.AlertManager}}),Object.defineProperty(exports,`Animator`,{enumerable:!0,get:function(){return n.Animator}}),Object.defineProperty(exports,`BarCountdown`,{enumerable:!0,get:function(){return n.BarCountdown}}),Object.defineProperty(exports,`BinanceAdapter`,{enumerable:!0,get:function(){return n.BinanceAdapter}}),Object.defineProperty(exports,`BybitAdapter`,{enumerable:!0,get:function(){return n.BybitAdapter}}),exports.Chart=e.r,exports.ChartGrid=i,Object.defineProperty(exports,`ChartLegend`,{enumerable:!0,get:function(){return n.ChartLegend}}),Object.defineProperty(exports,`ChartStateManager`,{enumerable:!0,get:function(){return n.ChartStateManager}}),Object.defineProperty(exports,`CoinbaseAdapter`,{enumerable:!0,get:function(){return n.CoinbaseAdapter}}),Object.defineProperty(exports,`CompareRenderer`,{enumerable:!0,get:function(){return n.CompareRenderer}}),Object.defineProperty(exports,`CrosshairTooltip`,{enumerable:!0,get:function(){return n.CrosshairTooltip}}),Object.defineProperty(exports,`CurrentPriceLine`,{enumerable:!0,get:function(){return n.CurrentPriceLine}}),Object.defineProperty(exports,`DARK_TERMINAL`,{enumerable:!0,get:function(){return t.DARK_TERMINAL}}),Object.defineProperty(exports,`DARK_THEME`,{enumerable:!0,get:function(){return t.DARK_THEME}}),Object.defineProperty(exports,`DEFAULT_DRAWING_STYLE`,{enumerable:!0,get:function(){return t.DEFAULT_DRAWING_STYLE}}),Object.defineProperty(exports,`DEFAULT_LEGEND_CONFIG`,{enumerable:!0,get:function(){return n.DEFAULT_LEGEND_CONFIG}}),Object.defineProperty(exports,`DEFAULT_RECONNECT`,{enumerable:!0,get:function(){return t.DEFAULT_RECONNECT}}),Object.defineProperty(exports,`DEFAULT_SESSION_HOURS`,{enumerable:!0,get:function(){return n.DEFAULT_SESSION_HOURS}}),Object.defineProperty(exports,`DEFAULT_SIGNAL_STYLE`,{enumerable:!0,get:function(){return t.DEFAULT_SIGNAL_STYLE}}),Object.defineProperty(exports,`DEFAULT_STREAM_CONFIG`,{enumerable:!0,get:function(){return t.DEFAULT_STREAM_CONFIG}}),Object.defineProperty(exports,`DEFAULT_TIMEFRAME_FAVORITES`,{enumerable:!0,get:function(){return t.DEFAULT_TIMEFRAME_FAVORITES}}),Object.defineProperty(exports,`DEFAULT_TRADE_ZONE_STYLE`,{enumerable:!0,get:function(){return t.DEFAULT_TRADE_ZONE_STYLE}}),Object.defineProperty(exports,`DEFAULT_TRADING_CONFIG`,{enumerable:!0,get:function(){return t.DEFAULT_TRADING_CONFIG}}),Object.defineProperty(exports,`DataExporter`,{enumerable:!0,get:function(){return n.DataExporter}}),exports.DataManager=e.m,exports.DepthChart=o,exports.DragDropImporter=e.t,Object.defineProperty(exports,`DrawingBase`,{enumerable:!0,get:function(){return n.DrawingBase}}),Object.defineProperty(exports,`Easing`,{enumerable:!0,get:function(){return n.Easing}}),exports.EquityCurveChart=s,exports.GaugeChart=f,exports.HeatmapChart=c,Object.defineProperty(exports,`IndicatorBase`,{enumerable:!0,get:function(){return n.IndicatorBase}}),Object.defineProperty(exports,`KeyboardHandler`,{enumerable:!0,get:function(){return n.KeyboardHandler}}),Object.defineProperty(exports,`KrakenAdapter`,{enumerable:!0,get:function(){return n.KrakenAdapter}}),Object.defineProperty(exports,`LIGHT_THEME`,{enumerable:!0,get:function(){return t.LIGHT_THEME}}),exports.LayoutManager=e.f,Object.defineProperty(exports,`MARKET_CRYPTO`,{enumerable:!0,get:function(){return t.MARKET_CRYPTO}}),Object.defineProperty(exports,`MARKET_HNX`,{enumerable:!0,get:function(){return t.MARKET_HNX}}),Object.defineProperty(exports,`MARKET_HOSE`,{enumerable:!0,get:function(){return t.MARKET_HOSE}}),Object.defineProperty(exports,`MARKET_NYSE`,{enumerable:!0,get:function(){return t.MARKET_NYSE}}),Object.defineProperty(exports,`MARKET_UPCOM`,{enumerable:!0,get:function(){return t.MARKET_UPCOM}}),Object.defineProperty(exports,`MockAdapter`,{enumerable:!0,get:function(){return n.MockAdapter}}),exports.PLUGIN_API_VERSION=e.l,Object.defineProperty(exports,`PaperExecutionAdapter`,{enumerable:!0,get:function(){return n.PaperExecutionAdapter}}),exports.PerformanceDashboard=x,exports.PluginManager=e.i,Object.defineProperty(exports,`PollingAdapter`,{enumerable:!0,get:function(){return n.PollingAdapter}}),Object.defineProperty(exports,`ReplayManager`,{enumerable:!0,get:function(){return n.ReplayManager}}),Object.defineProperty(exports,`Screenshot`,{enumerable:!0,get:function(){return n.Screenshot}}),Object.defineProperty(exports,`SessionBreaks`,{enumerable:!0,get:function(){return n.SessionBreaks}}),Object.defineProperty(exports,`SessionShading`,{enumerable:!0,get:function(){return n.SessionShading}}),Object.defineProperty(exports,`SignalMarkerManager`,{enumerable:!0,get:function(){return n.SignalMarkerManager}}),exports.SparklineChart=a,Object.defineProperty(exports,`StreamManager`,{enumerable:!0,get:function(){return n.StreamManager}}),Object.defineProperty(exports,`TIMEFRAMES_CRYPTO`,{enumerable:!0,get:function(){return t.TIMEFRAMES_CRYPTO}}),Object.defineProperty(exports,`TIMEFRAMES_FOREX`,{enumerable:!0,get:function(){return t.TIMEFRAMES_FOREX}}),Object.defineProperty(exports,`TIMEFRAMES_STOCK`,{enumerable:!0,get:function(){return t.TIMEFRAMES_STOCK}}),exports.ThemeManager=e.p,Object.defineProperty(exports,`TickAggregator`,{enumerable:!0,get:function(){return n.TickAggregator}}),Object.defineProperty(exports,`TradeZoneManager`,{enumerable:!0,get:function(){return n.TradeZoneManager}}),Object.defineProperty(exports,`UndoRedoManager`,{enumerable:!0,get:function(){return n.UndoRedoManager}}),Object.defineProperty(exports,`VN_COLORS`,{enumerable:!0,get:function(){return t.VN_COLORS}}),Object.defineProperty(exports,`VolumeRenderer`,{enumerable:!0,get:function(){return n.VolumeRenderer}}),exports.WaterfallChart=l,Object.defineProperty(exports,`Watermark`,{enumerable:!0,get:function(){return n.Watermark}}),Object.defineProperty(exports,`WebSocketAdapter`,{enumerable:!0,get:function(){return n.WebSocketAdapter}}),exports.clearGlobalPlugins=e.a,exports.computeDrawdownCurve=h,exports.computeMonthlyReturns=g,Object.defineProperty(exports,`computePriceLimits`,{enumerable:!0,get:function(){return t.computePriceLimits}}),Object.defineProperty(exports,`createVNTheme`,{enumerable:!0,get:function(){return t.createVNTheme}}),Object.defineProperty(exports,`formatNumber`,{enumerable:!0,get:function(){return t.formatNumber}}),Object.defineProperty(exports,`formatVND`,{enumerable:!0,get:function(){return t.formatVND}}),Object.defineProperty(exports,`formatVolumeLoc`,{enumerable:!0,get:function(){return t.formatVolumeLoc}}),Object.defineProperty(exports,`getCurrentSession`,{enumerable:!0,get:function(){return t.getCurrentSession}}),exports.getGlobalPlugins=e.o,Object.defineProperty(exports,`getLocale`,{enumerable:!0,get:function(){return t.getLocale}}),Object.defineProperty(exports,`lttbDownsample`,{enumerable:!0,get:function(){return n.lttbDownsample}}),Object.defineProperty(exports,`lttbVisibleIndices`,{enumerable:!0,get:function(){return n.lttbVisibleIndices}}),Object.defineProperty(exports,`normalizeBar`,{enumerable:!0,get:function(){return t.normalizeBar}}),Object.defineProperty(exports,`normalizeBarTime`,{enumerable:!0,get:function(){return t.normalizeBarTime}}),exports.overlaysForLayer=e.u,exports.parseOHLCV=e.n,exports.pluginKey=e.d,Object.defineProperty(exports,`registerLocale`,{enumerable:!0,get:function(){return t.registerLocale}}),exports.registerPlugin=e.s,exports.selectKeyStats=y,Object.defineProperty(exports,`setLocale`,{enumerable:!0,get:function(){return t.setLocale}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return t.t}}),exports.toEquityPoints=m,Object.defineProperty(exports,`toHeikinAshi`,{enumerable:!0,get:function(){return n.toHeikinAshi}}),Object.defineProperty(exports,`toKagi`,{enumerable:!0,get:function(){return n.toKagi}}),Object.defineProperty(exports,`toLineBreak`,{enumerable:!0,get:function(){return n.toLineBreak}}),Object.defineProperty(exports,`toPointAndFigure`,{enumerable:!0,get:function(){return n.toPointAndFigure}}),Object.defineProperty(exports,`toRangeBars`,{enumerable:!0,get:function(){return n.toRangeBars}}),Object.defineProperty(exports,`toRenko`,{enumerable:!0,get:function(){return n.toRenko}}),exports.unregisterPlugin=e.c;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./DragDropImporter-BazeSQPD.cjs`);let t=require(`@tradecanvas/commons`),n=require(`@tradecanvas/core`);var r={"1x1":{cols:1,rows:1},"1x2":{cols:2,rows:1},"2x1":{cols:1,rows:2},"2x2":{cols:2,rows:2},"1x3":{cols:3,rows:1},"3x1":{cols:1,rows:3},"2x3":{cols:3,rows:2},"3x2":{cols:2,rows:3}},i=class{root;cells=[];layout;options;destroyed=!1;syncing=!1;constructor(e,t={}){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()}applyLayout(){let{cols:e,rows:t}=r[this.layout],n=this.options.gap??1;this.root.style.gridTemplateColumns=`repeat(${e}, 1fr)`,this.root.style.gridTemplateRows=`repeat(${t}, 1fr)`,this.root.style.gap=`${n}px`}createCells(){let{cols:t,rows:n}=r[this.layout],i=t*n;for(let t=0;t<i;t++){let n=this.options.cells?.[t]??{},r=document.createElement(`div`);r.style.cssText=`position:relative;overflow:hidden;min-width:0;min-height:0;`,this.root.appendChild(r);let i=new e.r(r,{chartType:`candlestick`,autoScale:!0,features:{crosshair:!0,keyboard:!0,volume:!0,legend:!0,priceAxis:!0,timeAxis:!0,grid:!0},...this.options.chartOptions,...n.chartOptions,theme:this.options.theme}),a={container:r,chart:i,symbol:n.symbol??`Chart ${t+1}`,timeframe:n.timeframe??`5m`};this.options.syncCrosshair!==!1&&i.on(`crosshairMove`,e=>{if(!this.syncing){this.syncing=!0;for(let t of this.cells)t.chart!==i&&t.chart.setCrosshairPosition(e.payload.point);this.syncing=!1}}),this.options.syncTimeAxis!==!1&&i.on(`visibleRangeChange`,e=>{if(this.syncing)return;this.syncing=!0;let{from:t,to:n}=e.payload,r=i.getData();if(r.length>0&&t>=0&&n<r.length){let e=r[t]?.time,a=r[n]?.time;if(e&&a)for(let t of this.cells)t.chart!==i&&t.chart.setVisibleRange(e,a)}this.syncing=!1}),this.cells.push(a)}}setLayout(t){if(t===this.layout)return;let n=this.cells.length,{cols:i,rows:a}=r[t],o=i*a;if(o<n)for(let e=n-1;e>=o;e--){let t=this.cells[e];t.chart.destroy(),t.container.remove(),this.cells.pop()}if(this.layout=t,this.applyLayout(),o>n)for(let t=n;t<o;t++){let n=this.options.cells?.[t]??{},r=document.createElement(`div`);r.style.cssText=`position:relative;overflow:hidden;min-width:0;min-height:0;`,this.root.appendChild(r);let i=new e.r(r,{chartType:`candlestick`,autoScale:!0,...this.options.chartOptions,...n.chartOptions,theme:this.options.theme});this.cells.push({container:r,chart:i,symbol:n.symbol??`Chart ${t+1}`,timeframe:n.timeframe??`5m`})}}getChart(e){return this.cells[e]?.chart??null}getCharts(){return this.cells.map(e=>e.chart)}getCellCount(){return this.cells.length}setData(e,t){this.cells[e]?.chart.setData(t)}setAllData(e){for(let t of this.cells)t.chart.setData(e)}async connectCell(e,t){let n=this.cells[e];n&&(n.symbol=t.symbol,n.timeframe=t.timeframe,await n.chart.connect(t))}async connectAll(e,t,n,r=500){let i=[];for(let a=0;a<this.cells.length&&a<t.length;a++)i.push(this.connectCell(a,{adapter:e,symbol:t[a],timeframe:n,historyLimit:r}));await Promise.all(i)}setTheme(e){for(let t of this.cells)t.chart.setTheme(e)}destroy(){if(!this.destroyed){this.destroyed=!0;for(let e of this.cells)e.chart.destroy(),e.container.remove();this.cells=[],this.root.remove()}}},a=class extends n.BaseFinanceChart{options;constructor(e,t){super(e,t.theme),this.options=t,this.requestRender()}renderChart(e,t,r,i){(0,n.renderSparkline)(e,t,r,this.options,i)}update(e){this.options={...this.options,data:e},this.requestRender()}setOptions(e){this.options={...this.options,...e},this.requestRender()}},o=class extends n.BaseFinanceChart{options;crosshair=null;constructor(e,t){super(e,t.theme),this.options=t,t.crosshair!==!1&&(this.crosshair=new n.FinanceCrosshair(this.canvas,()=>this.requestRender())),this.requestRender()}renderChart(e,t,r,i){let a=this.crosshair?.getPosition()??null;(0,n.renderDepthChart)(e,t,r,this.options,i,a)}update(e){this.options={...this.options,data:e},this.requestRender()}setOptions(e){this.options={...this.options,...e},this.requestRender()}destroy(){this.crosshair?.destroy(),super.destroy()}},s=class extends n.BaseFinanceChart{options;crosshair=null;constructor(e,t){super(e,t.theme),this.options=t,t.crosshair!==!1&&(this.crosshair=new n.FinanceCrosshair(this.canvas,()=>this.requestRender())),this.requestRender()}renderChart(e,t,r,i){let a=this.crosshair?.getPosition()??null;(0,n.renderEquityCurve)(e,t,r,this.options,i,a)}update(e,t){this.options={...this.options,data:e},t!==void 0&&(this.options={...this.options,benchmark:t}),this.requestRender()}setOptions(e){this.options={...this.options,...e},this.requestRender()}destroy(){this.crosshair?.destroy(),super.destroy()}},c=class extends n.BaseFinanceChart{options;crosshair=null;cachedRects=[];currentData=[];lastLayoutWidth=0;lastLayoutHeight=0;handleClick=null;constructor(e,t){super(e,t.theme),this.options=t,this.currentData=t.data??[],t.crosshair!==!1&&(this.crosshair=new n.FinanceCrosshair(this.canvas,()=>this.requestRender())),t.onCellClick&&(this.handleClick=e=>{let t=this.canvas.getBoundingClientRect(),n=e.clientX-t.left,r=e.clientY-t.top;this.onCanvasClick(n,r)},this.canvas.addEventListener(`click`,this.handleClick)),this.recomputeLayout(),this.requestRender()}recomputeLayout(){let e={x:0,y:0,width:this.width,height:this.height},t=this.options.cellPadding??2;if(this.lastLayoutWidth=this.width,this.lastLayoutHeight=this.height,this.options.weighted){let r=this.currentData.map(e=>({id:e.id,weight:e.weight??(Math.abs(e.value)||1)}));this.cachedRects=(0,n.layoutSquarifiedTreemap)(r,e,t)}else this.cachedRects=(0,n.layoutUniformGrid)(this.currentData.map(e=>({id:e.id})),e,t)}onCanvasClick(e,t){if(this.options.onCellClick)for(let n of this.cachedRects){let r=n.rect;if(e>=r.x&&e<=r.x+r.width&&t>=r.y&&t<=r.y+r.height){let e=this.currentData.find(e=>e.id===n.id);e&&this.options.onCellClick(e);return}}}renderChart(e,t,r,i){(t!==this.lastLayoutWidth||r!==this.lastLayoutHeight)&&this.recomputeLayout();let a=this.crosshair?.getPosition()??null;(0,n.renderHeatmap)(e,t,r,this.currentData,this.cachedRects,this.options,i,a)}update(e){this.currentData=e,this.options={...this.options,data:e},this.recomputeLayout(),this.requestRender()}setOptions(e){this.options={...this.options,...e},e.data&&(this.currentData=e.data),this.recomputeLayout(),this.requestRender()}destroy(){this.crosshair?.destroy(),this.handleClick&&this.canvas.removeEventListener(`click`,this.handleClick),super.destroy()}},l=class extends n.BaseFinanceChart{options;crosshair=null;constructor(e,t){super(e,t.theme),this.options=t,t.crosshair!==!1&&(this.crosshair=new n.FinanceCrosshair(this.canvas,()=>this.requestRender())),this.requestRender()}renderChart(e,t,r,i){let a=this.crosshair?.getPosition()??null;(0,n.renderWaterfall)(e,t,r,this.options,i,a)}update(e){this.options={...this.options,data:e},this.requestRender()}setOptions(e){this.options={...this.options,...e},this.requestRender()}destroy(){this.crosshair?.destroy(),super.destroy()}},u=500;function d(e){let t=1-e;return 1-t*t*t}var f=class extends n.BaseFinanceChart{options;currentValue;targetValue;animationStart=null;animationFrom=0;animationFrameId=null;constructor(e,t){super(e,t.theme),this.options=t,this.currentValue=t.value,this.targetValue=t.value,this.requestRender()}renderChart(e,t,r,i){(0,n.renderGauge)(e,t,r,this.options,i,this.currentValue)}setValue(e){if(this.options.animate===!1){this.cancelAnimation(),this.currentValue=e,this.targetValue=e,this.options={...this.options,value:e},this.requestRender();return}this.targetValue=e,this.animationFrom=this.currentValue,this.animationStart=performance.now(),this.options={...this.options,value:e},this.startAnimationLoop()}setOptions(e){let t={...this.options,...e};if(e.value!==void 0&&e.value!==this.targetValue){this.options=t,this.setValue(e.value);return}this.options=t,this.requestRender()}startAnimationLoop(){if(this.animationFrameId!==null)return;let e=()=>{if(this.animationFrameId=null,this.animationStart===null)return;let t=this.options.animationDuration??u,n=performance.now()-this.animationStart,r=Math.min(1,n/Math.max(1,t)),i=d(r);this.currentValue=this.animationFrom+(this.targetValue-this.animationFrom)*i,this.requestRender(),r<1?this.animationFrameId=requestAnimationFrame(e):(this.currentValue=this.targetValue,this.animationStart=null)};this.animationFrameId=requestAnimationFrame(e)}cancelAnimation(){this.animationFrameId!==null&&(cancelAnimationFrame(this.animationFrameId),this.animationFrameId=null),this.animationStart=null}destroy(){this.cancelAnimation(),super.destroy()}},p=[`Jan`,`Feb`,`Mar`,`Apr`,`May`,`Jun`,`Jul`,`Aug`,`Sep`,`Oct`,`Nov`,`Dec`];function m(e){return e.map(e=>({time:e.time,value:e.equity}))}function h(e){let t=-1/0;return e.map(e=>{e.equity>t&&(t=e.equity);let n=t>0?(e.equity/t-1)*100:0;return{time:e.time,value:n}})}function g(e){if(e.length===0)return[];let n=[];for(let r of e){let e=(0,t.timeframeBucketStart)(r.time,`1M`),i=n[n.length-1];i&&i.key===e?i.close=r.equity:n.push({key:e,close:r.equity})}let r=e[0].equity,i=[];for(let e of n){let t=r===0?1:r,n=(e.close/t-1)*100;r=e.close;let a=new Date(e.key),o=a.getUTCFullYear(),s=a.getUTCMonth();i.push({id:`${o}-${String(s+1).padStart(2,`0`)}`,label:p[s],group:String(o),value:n})}return i}function _(e){return`${e>0?`+`:``}${e.toFixed(2)}%`}function v(e){return e>0?`positive`:e<0?`negative`:`neutral`}function y(e){return[{label:`Total Return`,value:_(e.totalReturnPct),tone:v(e.totalReturnPct)},{label:`CAGR`,value:_(e.cagr*100),tone:v(e.cagr)},{label:`Sharpe`,value:e.sharpe.toFixed(2),tone:v(e.sharpe)},{label:`Sortino`,value:e.sortino.toFixed(2),tone:v(e.sortino)},{label:`Max Drawdown`,value:_(e.maxDrawdownPct),tone:`negative`},{label:`Win Rate`,value:`${(e.winRate*100).toFixed(1)}%`,tone:`neutral`},{label:`Profit Factor`,value:Number.isFinite(e.profitFactor)?e.profitFactor.toFixed(2):`∞`,tone:v(e.profitFactor-1)},{label:`Trades`,value:String(e.trades),tone:`neutral`}]}function b(e){return!e||e===`dark`?t.DARK_THEME:e===`light`?t.LIGHT_THEME:e}var x=class{options;theme;root;equityChart=null;drawdownChart=null;heatmap=null;constructor(e,t){this.options=t,this.theme=b(t.theme),this.root=document.createElement(`div`),this.build(),e.appendChild(this.root)}build(){let e=this.theme,{result:t,title:n,subtitle:r}=this.options,i=this.panelBackground(),a=e.grid;if(this.root.style.cssText=[`display:flex`,`flex-direction:column`,`gap:14px`,`width:100%`,`box-sizing:border-box`,`padding:16px`,`background:${e.background}`,`color:${e.text}`,`font-family:${e.font.family}`].join(`;`),n||r){let t=document.createElement(`div`);if(n){let r=document.createElement(`div`);r.textContent=n,r.style.cssText=`font-size:${e.font.sizeLarge}px;font-weight:600;letter-spacing:-0.01em;`,t.appendChild(r)}if(r){let n=document.createElement(`div`);n.textContent=r,n.style.cssText=`font-size:${e.font.sizeSmall}px;color:${e.textSecondary};margin-top:2px;`,t.appendChild(n)}this.root.appendChild(t)}this.root.appendChild(this.buildStatsStrip(y(t.metrics),i,a));let o=document.createElement(`div`);o.style.cssText=[`display:grid`,`grid-template-columns:repeat(auto-fit, minmax(280px, 1fr))`,`grid-auto-rows:220px`,`gap:14px`].join(`;`),this.root.appendChild(o);let l=this.buildPanel(`Equity Curve`,i,a);l.wrap.style.gridColumn=`1 / -1`,o.appendChild(l.wrap),this.equityChart=new s(l.body,{data:m(t.equityCurve),theme:e,lineColor:e.candleUp,fillArea:!0,crosshair:!0});let u=this.buildPanel(`Drawdown`,i,a);o.appendChild(u.wrap),this.drawdownChart=new s(u.body,{data:h(t.equityCurve),theme:e,lineColor:e.candleDown,fillArea:!0,crosshair:!0,valueFormat:e=>`${e.toFixed(1)}%`});let d=g(t.equityCurve),f=this.buildPanel(`Monthly Returns`,i,a);o.appendChild(f.wrap),this.heatmap=new c(f.body,{data:d,theme:e,showValues:!0,valueFormat:e=>`${e>=0?`+`:``}${e.toFixed(1)}`,colorScale:{negative:e.candleDown,zero:i,positive:e.candleUp}})}buildStatsStrip(e,t,n){let r=document.createElement(`div`);r.style.cssText=[`display:grid`,`grid-template-columns:repeat(auto-fit, minmax(120px, 1fr))`,`gap:10px`].join(`;`);let i=this.theme;for(let a of e){let e=document.createElement(`div`);e.style.cssText=[`background:${t}`,`border:1px solid ${n}`,`border-radius:10px`,`padding:10px 12px`,`display:flex`,`flex-direction:column`,`gap:4px`].join(`;`);let o=document.createElement(`div`);o.textContent=a.label,o.style.cssText=`font-size:${i.font.sizeSmall}px;color:${i.textSecondary};text-transform:uppercase;letter-spacing:0.04em;`;let s=document.createElement(`div`);s.textContent=a.value;let c=a.tone===`positive`?i.candleUp:a.tone===`negative`?i.candleDown:i.text;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)}return r}buildPanel(e,t,n){let r=this.theme,i=document.createElement(`div`);i.style.cssText=[`background:${t}`,`border:1px solid ${n}`,`border-radius:10px`,`overflow:hidden`,`display:flex`,`flex-direction:column`].join(`;`);let a=document.createElement(`div`);a.textContent=e,a.style.cssText=[`font-size:${r.font.sizeSmall}px`,`font-weight:600`,`color:${r.textSecondary}`,`padding:8px 12px`,`border-bottom:1px solid ${n}`,`text-transform:uppercase`,`letter-spacing:0.04em`].join(`;`);let o=document.createElement(`div`);return o.style.cssText=`flex:1;min-height:0;position:relative;`,i.appendChild(a),i.appendChild(o),{wrap:i,body:o}}panelBackground(){return this.theme.name===`light`?`rgba(0,0,0,0.02)`:`rgba(255,255,255,0.03)`}update(e){this.options={...this.options,result:e},this.destroyCharts(),this.root.replaceChildren(),this.build()}setTheme(e){this.theme=b(e),this.options={...this.options,theme:e},this.destroyCharts(),this.root.replaceChildren(),this.build()}destroyCharts(){this.equityChart?.destroy(),this.drawdownChart?.destroy(),this.heatmap?.destroy(),this.equityChart=null,this.drawdownChart=null,this.heatmap=null}destroy(){this.destroyCharts(),this.root.remove()}};Object.defineProperty(exports,`AlertManager`,{enumerable:!0,get:function(){return n.AlertManager}}),Object.defineProperty(exports,`Animator`,{enumerable:!0,get:function(){return n.Animator}}),Object.defineProperty(exports,`BarCountdown`,{enumerable:!0,get:function(){return n.BarCountdown}}),Object.defineProperty(exports,`BinanceAdapter`,{enumerable:!0,get:function(){return n.BinanceAdapter}}),Object.defineProperty(exports,`BybitAdapter`,{enumerable:!0,get:function(){return n.BybitAdapter}}),exports.Chart=e.r,exports.ChartGrid=i,Object.defineProperty(exports,`ChartLegend`,{enumerable:!0,get:function(){return n.ChartLegend}}),Object.defineProperty(exports,`ChartStateManager`,{enumerable:!0,get:function(){return n.ChartStateManager}}),Object.defineProperty(exports,`CoinbaseAdapter`,{enumerable:!0,get:function(){return n.CoinbaseAdapter}}),Object.defineProperty(exports,`CompareRenderer`,{enumerable:!0,get:function(){return n.CompareRenderer}}),Object.defineProperty(exports,`CrosshairTooltip`,{enumerable:!0,get:function(){return n.CrosshairTooltip}}),Object.defineProperty(exports,`CurrentPriceLine`,{enumerable:!0,get:function(){return n.CurrentPriceLine}}),Object.defineProperty(exports,`DARK_TERMINAL`,{enumerable:!0,get:function(){return t.DARK_TERMINAL}}),Object.defineProperty(exports,`DARK_THEME`,{enumerable:!0,get:function(){return t.DARK_THEME}}),Object.defineProperty(exports,`DEFAULT_DRAWING_STYLE`,{enumerable:!0,get:function(){return t.DEFAULT_DRAWING_STYLE}}),Object.defineProperty(exports,`DEFAULT_LEGEND_CONFIG`,{enumerable:!0,get:function(){return n.DEFAULT_LEGEND_CONFIG}}),Object.defineProperty(exports,`DEFAULT_RECONNECT`,{enumerable:!0,get:function(){return t.DEFAULT_RECONNECT}}),Object.defineProperty(exports,`DEFAULT_SESSION_HOURS`,{enumerable:!0,get:function(){return n.DEFAULT_SESSION_HOURS}}),Object.defineProperty(exports,`DEFAULT_SIGNAL_STYLE`,{enumerable:!0,get:function(){return t.DEFAULT_SIGNAL_STYLE}}),Object.defineProperty(exports,`DEFAULT_STREAM_CONFIG`,{enumerable:!0,get:function(){return t.DEFAULT_STREAM_CONFIG}}),Object.defineProperty(exports,`DEFAULT_TIMEFRAME_FAVORITES`,{enumerable:!0,get:function(){return t.DEFAULT_TIMEFRAME_FAVORITES}}),Object.defineProperty(exports,`DEFAULT_TRADE_ZONE_STYLE`,{enumerable:!0,get:function(){return t.DEFAULT_TRADE_ZONE_STYLE}}),Object.defineProperty(exports,`DEFAULT_TRADING_CONFIG`,{enumerable:!0,get:function(){return t.DEFAULT_TRADING_CONFIG}}),Object.defineProperty(exports,`DataExporter`,{enumerable:!0,get:function(){return n.DataExporter}}),exports.DataManager=e.m,exports.DepthChart=o,exports.DragDropImporter=e.t,Object.defineProperty(exports,`DrawingBase`,{enumerable:!0,get:function(){return n.DrawingBase}}),Object.defineProperty(exports,`Easing`,{enumerable:!0,get:function(){return n.Easing}}),exports.EquityCurveChart=s,exports.GaugeChart=f,exports.HeatmapChart=c,Object.defineProperty(exports,`IndicatorBase`,{enumerable:!0,get:function(){return n.IndicatorBase}}),Object.defineProperty(exports,`IndicatorValueMap`,{enumerable:!0,get:function(){return n.IndicatorValueMap}}),Object.defineProperty(exports,`KeyboardHandler`,{enumerable:!0,get:function(){return n.KeyboardHandler}}),Object.defineProperty(exports,`KrakenAdapter`,{enumerable:!0,get:function(){return n.KrakenAdapter}}),Object.defineProperty(exports,`LIGHT_THEME`,{enumerable:!0,get:function(){return t.LIGHT_THEME}}),exports.LayoutManager=e.f,Object.defineProperty(exports,`MARKET_CRYPTO`,{enumerable:!0,get:function(){return t.MARKET_CRYPTO}}),Object.defineProperty(exports,`MARKET_HNX`,{enumerable:!0,get:function(){return t.MARKET_HNX}}),Object.defineProperty(exports,`MARKET_HOSE`,{enumerable:!0,get:function(){return t.MARKET_HOSE}}),Object.defineProperty(exports,`MARKET_NYSE`,{enumerable:!0,get:function(){return t.MARKET_NYSE}}),Object.defineProperty(exports,`MARKET_UPCOM`,{enumerable:!0,get:function(){return t.MARKET_UPCOM}}),Object.defineProperty(exports,`MockAdapter`,{enumerable:!0,get:function(){return n.MockAdapter}}),exports.PLUGIN_API_VERSION=e.l,Object.defineProperty(exports,`PaperExecutionAdapter`,{enumerable:!0,get:function(){return n.PaperExecutionAdapter}}),exports.PerformanceDashboard=x,exports.PluginManager=e.i,Object.defineProperty(exports,`PollingAdapter`,{enumerable:!0,get:function(){return n.PollingAdapter}}),Object.defineProperty(exports,`ReplayManager`,{enumerable:!0,get:function(){return n.ReplayManager}}),Object.defineProperty(exports,`Screenshot`,{enumerable:!0,get:function(){return n.Screenshot}}),Object.defineProperty(exports,`SessionBreaks`,{enumerable:!0,get:function(){return n.SessionBreaks}}),Object.defineProperty(exports,`SessionShading`,{enumerable:!0,get:function(){return n.SessionShading}}),Object.defineProperty(exports,`SignalMarkerManager`,{enumerable:!0,get:function(){return n.SignalMarkerManager}}),exports.SparklineChart=a,Object.defineProperty(exports,`StreamManager`,{enumerable:!0,get:function(){return n.StreamManager}}),Object.defineProperty(exports,`TC_PALETTE`,{enumerable:!0,get:function(){return t.TC_PALETTE}}),Object.defineProperty(exports,`TC_SERIES_COLORS`,{enumerable:!0,get:function(){return t.TC_SERIES_COLORS}}),Object.defineProperty(exports,`TIMEFRAMES_CRYPTO`,{enumerable:!0,get:function(){return t.TIMEFRAMES_CRYPTO}}),Object.defineProperty(exports,`TIMEFRAMES_FOREX`,{enumerable:!0,get:function(){return t.TIMEFRAMES_FOREX}}),Object.defineProperty(exports,`TIMEFRAMES_STOCK`,{enumerable:!0,get:function(){return t.TIMEFRAMES_STOCK}}),exports.ThemeManager=e.p,Object.defineProperty(exports,`TickAggregator`,{enumerable:!0,get:function(){return n.TickAggregator}}),Object.defineProperty(exports,`TradeZoneManager`,{enumerable:!0,get:function(){return n.TradeZoneManager}}),Object.defineProperty(exports,`UndoRedoManager`,{enumerable:!0,get:function(){return n.UndoRedoManager}}),Object.defineProperty(exports,`VN_COLORS`,{enumerable:!0,get:function(){return t.VN_COLORS}}),Object.defineProperty(exports,`VolumeRenderer`,{enumerable:!0,get:function(){return n.VolumeRenderer}}),exports.WaterfallChart=l,Object.defineProperty(exports,`Watermark`,{enumerable:!0,get:function(){return n.Watermark}}),Object.defineProperty(exports,`WebSocketAdapter`,{enumerable:!0,get:function(){return n.WebSocketAdapter}}),exports.clearGlobalPlugins=e.a,exports.computeDrawdownCurve=h,exports.computeMonthlyReturns=g,Object.defineProperty(exports,`computePriceLimits`,{enumerable:!0,get:function(){return t.computePriceLimits}}),Object.defineProperty(exports,`createVNTheme`,{enumerable:!0,get:function(){return t.createVNTheme}}),Object.defineProperty(exports,`formatNumber`,{enumerable:!0,get:function(){return t.formatNumber}}),Object.defineProperty(exports,`formatTooltipTime`,{enumerable:!0,get:function(){return n.formatTooltipTime}}),Object.defineProperty(exports,`formatVND`,{enumerable:!0,get:function(){return t.formatVND}}),Object.defineProperty(exports,`formatVolumeLoc`,{enumerable:!0,get:function(){return t.formatVolumeLoc}}),Object.defineProperty(exports,`getCurrentSession`,{enumerable:!0,get:function(){return t.getCurrentSession}}),exports.getGlobalPlugins=e.o,Object.defineProperty(exports,`getLocale`,{enumerable:!0,get:function(){return t.getLocale}}),Object.defineProperty(exports,`lttbDownsample`,{enumerable:!0,get:function(){return n.lttbDownsample}}),Object.defineProperty(exports,`lttbVisibleIndices`,{enumerable:!0,get:function(){return n.lttbVisibleIndices}}),Object.defineProperty(exports,`normalizeBar`,{enumerable:!0,get:function(){return t.normalizeBar}}),Object.defineProperty(exports,`normalizeBarTime`,{enumerable:!0,get:function(){return t.normalizeBarTime}}),exports.overlaysForLayer=e.u,exports.parseOHLCV=e.n,exports.pluginKey=e.d,Object.defineProperty(exports,`registerLocale`,{enumerable:!0,get:function(){return t.registerLocale}}),exports.registerPlugin=e.s,exports.selectKeyStats=y,Object.defineProperty(exports,`setLocale`,{enumerable:!0,get:function(){return t.setLocale}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return t.t}}),exports.toEquityPoints=m,Object.defineProperty(exports,`toHeikinAshi`,{enumerable:!0,get:function(){return n.toHeikinAshi}}),Object.defineProperty(exports,`toKagi`,{enumerable:!0,get:function(){return n.toKagi}}),Object.defineProperty(exports,`toLineBreak`,{enumerable:!0,get:function(){return n.toLineBreak}}),Object.defineProperty(exports,`toPointAndFigure`,{enumerable:!0,get:function(){return n.toPointAndFigure}}),Object.defineProperty(exports,`toRangeBars`,{enumerable:!0,get:function(){return n.toRangeBars}}),Object.defineProperty(exports,`toRenko`,{enumerable:!0,get:function(){return n.toRenko}}),exports.unregisterPlugin=e.c;
2
2
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":[],"sources":["../src/grid/ChartGrid.ts","../src/finance/SparklineChart.ts","../src/finance/DepthChart.ts","../src/finance/EquityCurveChart.ts","../src/finance/HeatmapChart.ts","../src/finance/WaterfallChart.ts","../src/finance/GaugeChart.ts","../src/finance/performanceData.ts","../src/finance/PerformanceDashboard.ts"],"sourcesContent":["import type { ChartOptions, Theme, TimeFrame, DataSeries, DataAdapter, StreamConfig } from '@tradecanvas/commons';\nimport { Chart } from '../Chart.js';\n\nexport type GridLayout = '1x1' | '1x2' | '2x1' | '2x2' | '1x3' | '3x1' | '2x3' | '3x2';\n\nexport interface GridCellConfig {\n symbol?: string;\n timeframe?: TimeFrame;\n chartOptions?: Partial<ChartOptions>;\n}\n\nexport interface ChartGridOptions {\n layout?: GridLayout;\n theme?: ChartOptions['theme'];\n syncCrosshair?: boolean;\n syncTimeAxis?: boolean;\n gap?: number;\n cells?: GridCellConfig[];\n chartOptions?: Partial<ChartOptions>;\n}\n\ninterface GridCell {\n container: HTMLDivElement;\n chart: Chart;\n symbol: string;\n timeframe: TimeFrame;\n}\n\nconst LAYOUT_MAP: Record<GridLayout, { cols: number; rows: number }> = {\n '1x1': { cols: 1, rows: 1 },\n '1x2': { cols: 2, rows: 1 },\n '2x1': { cols: 1, rows: 2 },\n '2x2': { cols: 2, rows: 2 },\n '1x3': { cols: 3, rows: 1 },\n '3x1': { cols: 1, rows: 3 },\n '2x3': { cols: 3, rows: 2 },\n '3x2': { cols: 2, rows: 3 },\n};\n\nexport class ChartGrid {\n private root: HTMLDivElement;\n private cells: GridCell[] = [];\n private layout: GridLayout;\n private options: ChartGridOptions;\n private destroyed = false;\n private syncing = false;\n\n constructor(container: HTMLElement, options: ChartGridOptions = {}) {\n this.options = options;\n this.layout = options.layout ?? '2x2';\n\n this.root = document.createElement('div');\n this.root.style.cssText = 'display:grid;width:100%;height:100%;overflow:hidden;';\n container.appendChild(this.root);\n\n this.applyLayout();\n this.createCells();\n }\n\n private applyLayout(): void {\n const { cols, rows } = LAYOUT_MAP[this.layout];\n const gap = this.options.gap ?? 1;\n this.root.style.gridTemplateColumns = `repeat(${cols}, 1fr)`;\n this.root.style.gridTemplateRows = `repeat(${rows}, 1fr)`;\n this.root.style.gap = `${gap}px`;\n }\n\n private createCells(): void {\n const { cols, rows } = LAYOUT_MAP[this.layout];\n const count = cols * rows;\n\n for (let i = 0; i < count; i++) {\n const cellConfig = this.options.cells?.[i] ?? {};\n\n const cellEl = document.createElement('div');\n cellEl.style.cssText = 'position:relative;overflow:hidden;min-width:0;min-height:0;';\n this.root.appendChild(cellEl);\n\n const chartOpts: ChartOptions = {\n chartType: 'candlestick',\n autoScale: true,\n features: {\n crosshair: true,\n keyboard: true,\n volume: true,\n legend: true,\n priceAxis: true,\n timeAxis: true,\n grid: true,\n },\n ...this.options.chartOptions,\n ...cellConfig.chartOptions,\n theme: this.options.theme,\n };\n\n const chart = new Chart(cellEl, chartOpts);\n\n const cell: GridCell = {\n container: cellEl,\n chart,\n symbol: cellConfig.symbol ?? `Chart ${i + 1}`,\n timeframe: cellConfig.timeframe ?? '5m',\n };\n\n if (this.options.syncCrosshair !== false) {\n chart.on('crosshairMove', (e) => {\n if (this.syncing) return;\n this.syncing = true;\n for (const other of this.cells) {\n if (other.chart !== chart) {\n other.chart.setCrosshairPosition(e.payload.point);\n }\n }\n this.syncing = false;\n });\n }\n\n if (this.options.syncTimeAxis !== false) {\n chart.on('visibleRangeChange', (e) => {\n if (this.syncing) return;\n this.syncing = true;\n const { from, to } = e.payload;\n const srcData = chart.getData();\n if (srcData.length > 0 && from >= 0 && to < srcData.length) {\n const fromTime = srcData[from]?.time;\n const toTime = srcData[to]?.time;\n if (fromTime && toTime) {\n for (const other of this.cells) {\n if (other.chart !== chart) {\n other.chart.setVisibleRange(fromTime, toTime);\n }\n }\n }\n }\n this.syncing = false;\n });\n }\n\n this.cells.push(cell);\n }\n }\n\n setLayout(layout: GridLayout): void {\n if (layout === this.layout) return;\n const oldCount = this.cells.length;\n const { cols, rows } = LAYOUT_MAP[layout];\n const newCount = cols * rows;\n\n if (newCount < oldCount) {\n for (let i = oldCount - 1; i >= newCount; i--) {\n const cell = this.cells[i];\n cell.chart.destroy();\n cell.container.remove();\n this.cells.pop();\n }\n }\n\n this.layout = layout;\n this.applyLayout();\n\n if (newCount > oldCount) {\n for (let i = oldCount; i < newCount; i++) {\n const cellConfig = this.options.cells?.[i] ?? {};\n const cellEl = document.createElement('div');\n cellEl.style.cssText = 'position:relative;overflow:hidden;min-width:0;min-height:0;';\n this.root.appendChild(cellEl);\n\n const chart = new Chart(cellEl, {\n chartType: 'candlestick',\n autoScale: true,\n ...this.options.chartOptions,\n ...cellConfig.chartOptions,\n theme: this.options.theme,\n });\n\n this.cells.push({\n container: cellEl,\n chart,\n symbol: cellConfig.symbol ?? `Chart ${i + 1}`,\n timeframe: cellConfig.timeframe ?? '5m',\n });\n }\n }\n }\n\n getChart(index: number): Chart | null {\n return this.cells[index]?.chart ?? null;\n }\n\n getCharts(): Chart[] {\n return this.cells.map(c => c.chart);\n }\n\n getCellCount(): number {\n return this.cells.length;\n }\n\n setData(index: number, data: DataSeries): void {\n this.cells[index]?.chart.setData(data);\n }\n\n setAllData(data: DataSeries): void {\n for (const cell of this.cells) {\n cell.chart.setData(data);\n }\n }\n\n async connectCell(index: number, config: StreamConfig): Promise<void> {\n const cell = this.cells[index];\n if (!cell) return;\n cell.symbol = config.symbol;\n cell.timeframe = config.timeframe;\n await cell.chart.connect(config);\n }\n\n async connectAll(adapter: DataAdapter, symbols: string[], timeframe: TimeFrame, historyLimit = 500): Promise<void> {\n const promises: Promise<void>[] = [];\n for (let i = 0; i < this.cells.length && i < symbols.length; i++) {\n promises.push(this.connectCell(i, {\n adapter,\n symbol: symbols[i],\n timeframe,\n historyLimit,\n }));\n }\n await Promise.all(promises);\n }\n\n setTheme(theme: Theme): void {\n for (const cell of this.cells) {\n cell.chart.setTheme(theme);\n }\n }\n\n destroy(): void {\n if (this.destroyed) return;\n this.destroyed = true;\n for (const cell of this.cells) {\n cell.chart.destroy();\n cell.container.remove();\n }\n this.cells = [];\n this.root.remove();\n }\n}\n","import type { SparklineOptions, Theme } from '@tradecanvas/commons';\nimport { BaseFinanceChart, renderSparkline } from '@tradecanvas/core';\n\nexport class SparklineChart extends BaseFinanceChart {\n private options: SparklineOptions;\n\n constructor(container: HTMLElement, options: SparklineOptions) {\n super(container, options.theme);\n this.options = options;\n this.requestRender();\n }\n\n protected renderChart(\n ctx: CanvasRenderingContext2D,\n width: number,\n height: number,\n theme: Theme,\n ): void {\n renderSparkline(ctx, width, height, this.options, theme);\n }\n\n update(data: number[]): void {\n this.options = { ...this.options, data };\n this.requestRender();\n }\n\n setOptions(opts: Partial<SparklineOptions>): void {\n this.options = { ...this.options, ...opts };\n this.requestRender();\n }\n}\n","import type { DepthChartOptions, DepthData, Theme } from '@tradecanvas/commons';\nimport { BaseFinanceChart, FinanceCrosshair, renderDepthChart } from '@tradecanvas/core';\n\nexport class DepthChart extends BaseFinanceChart {\n private options: DepthChartOptions;\n private crosshair: FinanceCrosshair | null = null;\n\n constructor(container: HTMLElement, options: DepthChartOptions) {\n super(container, options.theme);\n this.options = options;\n\n if (options.crosshair !== false) {\n this.crosshair = new FinanceCrosshair(this.canvas, () => this.requestRender());\n }\n\n this.requestRender();\n }\n\n protected renderChart(\n ctx: CanvasRenderingContext2D,\n width: number,\n height: number,\n theme: Theme,\n ): void {\n const pos = this.crosshair?.getPosition() ?? null;\n renderDepthChart(ctx, width, height, this.options, theme, pos);\n }\n\n update(data: DepthData): void {\n this.options = { ...this.options, data };\n this.requestRender();\n }\n\n setOptions(opts: Partial<DepthChartOptions>): void {\n this.options = { ...this.options, ...opts };\n this.requestRender();\n }\n\n destroy(): void {\n this.crosshair?.destroy();\n super.destroy();\n }\n}\n","import type { EquityCurveOptions, EquityPoint, Theme } from '@tradecanvas/commons';\nimport { BaseFinanceChart, FinanceCrosshair, renderEquityCurve } from '@tradecanvas/core';\n\nexport class EquityCurveChart extends BaseFinanceChart {\n private options: EquityCurveOptions;\n private crosshair: FinanceCrosshair | null = null;\n\n constructor(container: HTMLElement, options: EquityCurveOptions) {\n super(container, options.theme);\n this.options = options;\n\n if (options.crosshair !== false) {\n this.crosshair = new FinanceCrosshair(this.canvas, () => this.requestRender());\n }\n\n this.requestRender();\n }\n\n protected renderChart(\n ctx: CanvasRenderingContext2D,\n width: number,\n height: number,\n theme: Theme,\n ): void {\n const pos = this.crosshair?.getPosition() ?? null;\n renderEquityCurve(ctx, width, height, this.options, theme, pos);\n }\n\n update(data: EquityPoint[], benchmark?: EquityPoint[]): void {\n this.options = { ...this.options, data };\n if (benchmark !== undefined) {\n this.options = { ...this.options, benchmark };\n }\n this.requestRender();\n }\n\n setOptions(opts: Partial<EquityCurveOptions>): void {\n this.options = { ...this.options, ...opts };\n this.requestRender();\n }\n\n destroy(): void {\n this.crosshair?.destroy();\n super.destroy();\n }\n}\n","import type { HeatmapCell, HeatmapOptions, Theme } from '@tradecanvas/commons';\nimport {\n BaseFinanceChart,\n FinanceCrosshair,\n layoutUniformGrid,\n layoutSquarifiedTreemap,\n renderHeatmap,\n} from '@tradecanvas/core';\nimport type { LayoutRect } from '@tradecanvas/core';\n\nexport class HeatmapChart extends BaseFinanceChart {\n private options: HeatmapOptions;\n private crosshair: FinanceCrosshair | null = null;\n private cachedRects: LayoutRect[] = [];\n private currentData: HeatmapCell[] = [];\n private lastLayoutWidth = 0;\n private lastLayoutHeight = 0;\n private handleClick: ((e: MouseEvent) => void) | null = null;\n\n constructor(container: HTMLElement, options: HeatmapOptions) {\n super(container, options.theme);\n this.options = options;\n this.currentData = options.data ?? [];\n\n if (options.crosshair !== false) {\n this.crosshair = new FinanceCrosshair(this.canvas, () => this.requestRender());\n }\n\n if (options.onCellClick) {\n this.handleClick = (e: MouseEvent) => {\n const rect = this.canvas.getBoundingClientRect();\n const x = e.clientX - rect.left;\n const y = e.clientY - rect.top;\n this.onCanvasClick(x, y);\n };\n this.canvas.addEventListener('click', this.handleClick);\n }\n\n this.recomputeLayout();\n this.requestRender();\n }\n\n private recomputeLayout(): void {\n const bounds = { x: 0, y: 0, width: this.width, height: this.height };\n const padding = this.options.cellPadding ?? 2;\n this.lastLayoutWidth = this.width;\n this.lastLayoutHeight = this.height;\n\n if (this.options.weighted) {\n const weighted = this.currentData.map(c => ({\n id: c.id,\n weight: c.weight ?? (Math.abs(c.value) || 1),\n }));\n this.cachedRects = layoutSquarifiedTreemap(weighted, bounds, padding);\n } else {\n this.cachedRects = layoutUniformGrid(\n this.currentData.map(c => ({ id: c.id })),\n bounds,\n padding,\n );\n }\n }\n\n private onCanvasClick(x: number, y: number): void {\n if (!this.options.onCellClick) return;\n\n for (const lr of this.cachedRects) {\n const r = lr.rect;\n if (x >= r.x && x <= r.x + r.width && y >= r.y && y <= r.y + r.height) {\n const cell = this.currentData.find(c => c.id === lr.id);\n if (cell) this.options.onCellClick(cell);\n return;\n }\n }\n }\n\n protected renderChart(\n ctx: CanvasRenderingContext2D,\n width: number,\n height: number,\n theme: Theme,\n ): void {\n if (width !== this.lastLayoutWidth || height !== this.lastLayoutHeight) {\n this.recomputeLayout();\n }\n\n const pos = this.crosshair?.getPosition() ?? null;\n renderHeatmap(ctx, width, height, this.currentData, this.cachedRects, this.options, theme, pos);\n }\n\n update(data: HeatmapCell[]): void {\n this.currentData = data;\n this.options = { ...this.options, data };\n this.recomputeLayout();\n this.requestRender();\n }\n\n setOptions(opts: Partial<HeatmapOptions>): void {\n this.options = { ...this.options, ...opts };\n if (opts.data) {\n this.currentData = opts.data;\n }\n this.recomputeLayout();\n this.requestRender();\n }\n\n destroy(): void {\n this.crosshair?.destroy();\n if (this.handleClick) {\n this.canvas.removeEventListener('click', this.handleClick);\n }\n super.destroy();\n }\n}\n","import type { Theme, WaterfallBar, WaterfallOptions } from '@tradecanvas/commons';\nimport { BaseFinanceChart, FinanceCrosshair, renderWaterfall } from '@tradecanvas/core';\n\nexport class WaterfallChart extends BaseFinanceChart {\n private options: WaterfallOptions;\n private crosshair: FinanceCrosshair | null = null;\n\n constructor(container: HTMLElement, options: WaterfallOptions) {\n super(container, options.theme);\n this.options = options;\n\n if (options.crosshair !== false) {\n this.crosshair = new FinanceCrosshair(this.canvas, () => this.requestRender());\n }\n\n this.requestRender();\n }\n\n protected renderChart(\n ctx: CanvasRenderingContext2D,\n width: number,\n height: number,\n theme: Theme,\n ): void {\n const pos = this.crosshair?.getPosition() ?? null;\n renderWaterfall(ctx, width, height, this.options, theme, pos);\n }\n\n update(data: WaterfallBar[]): void {\n this.options = { ...this.options, data };\n this.requestRender();\n }\n\n setOptions(opts: Partial<WaterfallOptions>): void {\n this.options = { ...this.options, ...opts };\n this.requestRender();\n }\n\n destroy(): void {\n this.crosshair?.destroy();\n super.destroy();\n }\n}\n","import type { GaugeOptions, Theme } from '@tradecanvas/commons';\nimport { BaseFinanceChart, renderGauge } from '@tradecanvas/core';\n\nconst DEFAULT_ANIMATION_MS = 500;\n\nfunction easeOutCubic(t: number): number {\n const inv = 1 - t;\n return 1 - inv * inv * inv;\n}\n\nexport class GaugeChart extends BaseFinanceChart {\n private options: GaugeOptions;\n private currentValue: number;\n private targetValue: number;\n private animationStart: number | null = null;\n private animationFrom = 0;\n private animationFrameId: number | null = null;\n\n constructor(container: HTMLElement, options: GaugeOptions) {\n super(container, options.theme);\n this.options = options;\n this.currentValue = options.value;\n this.targetValue = options.value;\n this.requestRender();\n }\n\n protected renderChart(\n ctx: CanvasRenderingContext2D,\n width: number,\n height: number,\n theme: Theme,\n ): void {\n renderGauge(ctx, width, height, this.options, theme, this.currentValue);\n }\n\n setValue(value: number): void {\n const animate = this.options.animate !== false;\n if (!animate) {\n this.cancelAnimation();\n this.currentValue = value;\n this.targetValue = value;\n this.options = { ...this.options, value };\n this.requestRender();\n return;\n }\n\n this.targetValue = value;\n this.animationFrom = this.currentValue;\n this.animationStart = performance.now();\n this.options = { ...this.options, value };\n this.startAnimationLoop();\n }\n\n setOptions(opts: Partial<GaugeOptions>): void {\n const next = { ...this.options, ...opts };\n // If `value` is part of the partial, route through animation path\n if (opts.value !== undefined && opts.value !== this.targetValue) {\n this.options = next;\n this.setValue(opts.value);\n return;\n }\n this.options = next;\n this.requestRender();\n }\n\n private startAnimationLoop(): void {\n if (this.animationFrameId !== null) return;\n const step = (): void => {\n this.animationFrameId = null;\n if (this.animationStart === null) return;\n\n const duration = this.options.animationDuration ?? DEFAULT_ANIMATION_MS;\n const elapsed = performance.now() - this.animationStart;\n const t = Math.min(1, elapsed / Math.max(1, duration));\n const eased = easeOutCubic(t);\n this.currentValue = this.animationFrom + (this.targetValue - this.animationFrom) * eased;\n\n this.requestRender();\n\n if (t < 1) {\n this.animationFrameId = requestAnimationFrame(step);\n } else {\n this.currentValue = this.targetValue;\n this.animationStart = null;\n }\n };\n this.animationFrameId = requestAnimationFrame(step);\n }\n\n private cancelAnimation(): void {\n if (this.animationFrameId !== null) {\n cancelAnimationFrame(this.animationFrameId);\n this.animationFrameId = null;\n }\n this.animationStart = null;\n }\n\n destroy(): void {\n this.cancelAnimation();\n super.destroy();\n }\n}\n","import type { EquityPoint, HeatmapCell } from '@tradecanvas/commons';\nimport { timeframeBucketStart } from '@tradecanvas/commons';\n\n/** Minimal equity sample shape — structurally satisfied by analytics' EquityPoint. */\nexport interface EquitySample {\n time: number;\n equity: number;\n}\n\n/** Subset of analytics RiskMetrics needed to render the stats strip. */\nexport interface RiskMetricsLike {\n totalReturnPct: number;\n cagr: number;\n sharpe: number;\n sortino: number;\n maxDrawdownPct: number;\n winRate: number;\n profitFactor: number;\n trades: number;\n}\n\nexport interface DashboardStat {\n label: string;\n value: string;\n tone: 'positive' | 'negative' | 'neutral';\n}\n\nconst MONTH_LABELS = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];\n\n/** Map an analytics equity curve to the finance EquityCurveChart point shape. */\nexport function toEquityPoints(curve: ReadonlyArray<EquitySample>): EquityPoint[] {\n return curve.map((p) => ({ time: p.time, value: p.equity }));\n}\n\n/**\n * Underwater drawdown curve as a percentage (<= 0). Each point is the equity's\n * shortfall from the running peak: `equity / peak - 1`, expressed in percent.\n */\nexport function computeDrawdownCurve(curve: ReadonlyArray<EquitySample>): EquityPoint[] {\n let peak = -Infinity;\n return curve.map((p) => {\n if (p.equity > peak) peak = p.equity;\n const dd = peak > 0 ? (p.equity / peak - 1) * 100 : 0;\n return { time: p.time, value: dd };\n });\n}\n\n/**\n * Calendar-month returns as heatmap cells. Each month's return is chained off\n * the prior month's closing equity (the first month chains off its own opening\n * equity), so the series reads as sequential monthly performance. `group` is\n * the year and `value` is the return in percent.\n */\nexport function computeMonthlyReturns(curve: ReadonlyArray<EquitySample>): HeatmapCell[] {\n if (curve.length === 0) return [];\n\n // Collapse the curve to one closing equity per calendar month, in order.\n const months: { key: number; close: number }[] = [];\n for (const p of curve) {\n const key = timeframeBucketStart(p.time, '1M');\n const last = months[months.length - 1];\n if (last && last.key === key) {\n last.close = p.equity;\n } else {\n months.push({ key, close: p.equity });\n }\n }\n\n let prevClose = curve[0].equity;\n const cells: HeatmapCell[] = [];\n for (const m of months) {\n const base = prevClose === 0 ? 1 : prevClose;\n const returnPct = (m.close / base - 1) * 100;\n prevClose = m.close;\n const d = new Date(m.key);\n const year = d.getUTCFullYear();\n const month = d.getUTCMonth();\n cells.push({\n id: `${year}-${String(month + 1).padStart(2, '0')}`,\n label: MONTH_LABELS[month],\n group: String(year),\n value: returnPct,\n });\n }\n return cells;\n}\n\nfunction pct(value: number): string {\n const sign = value > 0 ? '+' : '';\n return `${sign}${value.toFixed(2)}%`;\n}\n\nfunction tone(value: number): DashboardStat['tone'] {\n if (value > 0) return 'positive';\n if (value < 0) return 'negative';\n return 'neutral';\n}\n\n/** The headline stats rendered as cards above the charts. */\nexport function selectKeyStats(metrics: RiskMetricsLike): DashboardStat[] {\n return [\n { label: 'Total Return', value: pct(metrics.totalReturnPct), tone: tone(metrics.totalReturnPct) },\n { label: 'CAGR', value: pct(metrics.cagr * 100), tone: tone(metrics.cagr) },\n { label: 'Sharpe', value: metrics.sharpe.toFixed(2), tone: tone(metrics.sharpe) },\n { label: 'Sortino', value: metrics.sortino.toFixed(2), tone: tone(metrics.sortino) },\n { label: 'Max Drawdown', value: pct(metrics.maxDrawdownPct), tone: 'negative' },\n { label: 'Win Rate', value: `${(metrics.winRate * 100).toFixed(1)}%`, tone: 'neutral' },\n { label: 'Profit Factor', value: Number.isFinite(metrics.profitFactor) ? metrics.profitFactor.toFixed(2) : '∞', tone: tone(metrics.profitFactor - 1) },\n { label: 'Trades', value: String(metrics.trades), tone: 'neutral' },\n ];\n}\n","import type { Theme, ThemeName } from '@tradecanvas/commons';\nimport { DARK_THEME, LIGHT_THEME } from '@tradecanvas/commons';\nimport { EquityCurveChart } from './EquityCurveChart.js';\nimport { HeatmapChart } from './HeatmapChart.js';\nimport {\n toEquityPoints,\n computeDrawdownCurve,\n computeMonthlyReturns,\n selectKeyStats,\n type EquitySample,\n type RiskMetricsLike,\n type DashboardStat,\n} from './performanceData.js';\n\n/** Structurally satisfied by analytics' `BacktestResult`. */\nexport interface PerformanceResult {\n equityCurve: ReadonlyArray<EquitySample>;\n metrics: RiskMetricsLike;\n}\n\nexport interface PerformanceDashboardOptions {\n result: PerformanceResult;\n theme?: ThemeName | Theme;\n title?: string;\n subtitle?: string;\n}\n\nfunction resolveTheme(theme?: ThemeName | Theme): Theme {\n if (!theme || theme === 'dark') return DARK_THEME;\n if (theme === 'light') return LIGHT_THEME;\n return theme as Theme;\n}\n\n/**\n * A composed strategy-performance dashboard: a headline stats strip, an equity\n * curve, an underwater drawdown panel, and a monthly-returns heatmap. Built\n * entirely from a backtest `result`, reusing the finance chart renderers.\n *\n * ```ts\n * const result = new Backtester(opts).run(bars, strategy);\n * const dash = new PerformanceDashboard(el, { result, theme: 'dark' });\n * ```\n */\nexport class PerformanceDashboard {\n private options: PerformanceDashboardOptions;\n private theme: Theme;\n private root: HTMLDivElement;\n private equityChart: EquityCurveChart | null = null;\n private drawdownChart: EquityCurveChart | null = null;\n private heatmap: HeatmapChart | null = null;\n\n constructor(container: HTMLElement, options: PerformanceDashboardOptions) {\n this.options = options;\n this.theme = resolveTheme(options.theme);\n this.root = document.createElement('div');\n this.build();\n container.appendChild(this.root);\n }\n\n private build(): void {\n const t = this.theme;\n const { result, title, subtitle } = this.options;\n const surface = this.panelBackground();\n const border = t.grid;\n\n this.root.style.cssText = [\n 'display:flex',\n 'flex-direction:column',\n 'gap:14px',\n 'width:100%',\n 'box-sizing:border-box',\n 'padding:16px',\n `background:${t.background}`,\n `color:${t.text}`,\n `font-family:${t.font.family}`,\n ].join(';');\n\n if (title || subtitle) {\n const header = document.createElement('div');\n if (title) {\n const h = document.createElement('div');\n h.textContent = title;\n h.style.cssText = `font-size:${t.font.sizeLarge}px;font-weight:600;letter-spacing:-0.01em;`;\n header.appendChild(h);\n }\n if (subtitle) {\n const s = document.createElement('div');\n s.textContent = subtitle;\n s.style.cssText = `font-size:${t.font.sizeSmall}px;color:${t.textSecondary};margin-top:2px;`;\n header.appendChild(s);\n }\n this.root.appendChild(header);\n }\n\n // Stats strip\n this.root.appendChild(this.buildStatsStrip(selectKeyStats(result.metrics), surface, border));\n\n // Chart grid\n const grid = document.createElement('div');\n grid.style.cssText = [\n 'display:grid',\n 'grid-template-columns:repeat(auto-fit, minmax(280px, 1fr))',\n 'grid-auto-rows:220px',\n 'gap:14px',\n ].join(';');\n this.root.appendChild(grid);\n\n const equityPanel = this.buildPanel('Equity Curve', surface, border);\n equityPanel.wrap.style.gridColumn = '1 / -1';\n grid.appendChild(equityPanel.wrap);\n this.equityChart = new EquityCurveChart(equityPanel.body, {\n data: toEquityPoints(result.equityCurve),\n theme: t,\n lineColor: t.candleUp,\n fillArea: true,\n crosshair: true,\n });\n\n const ddPanel = this.buildPanel('Drawdown', surface, border);\n grid.appendChild(ddPanel.wrap);\n this.drawdownChart = new EquityCurveChart(ddPanel.body, {\n data: computeDrawdownCurve(result.equityCurve),\n theme: t,\n lineColor: t.candleDown,\n fillArea: true,\n crosshair: true,\n valueFormat: (v) => `${v.toFixed(1)}%`,\n });\n\n const monthlyCells = computeMonthlyReturns(result.equityCurve);\n const heatPanel = this.buildPanel('Monthly Returns', surface, border);\n grid.appendChild(heatPanel.wrap);\n this.heatmap = new HeatmapChart(heatPanel.body, {\n data: monthlyCells,\n theme: t,\n showValues: true,\n valueFormat: (v) => `${v >= 0 ? '+' : ''}${v.toFixed(1)}`,\n colorScale: { negative: t.candleDown, zero: surface, positive: t.candleUp },\n });\n }\n\n private buildStatsStrip(stats: DashboardStat[], surface: string, border: string): HTMLDivElement {\n const strip = document.createElement('div');\n strip.style.cssText = [\n 'display:grid',\n 'grid-template-columns:repeat(auto-fit, minmax(120px, 1fr))',\n 'gap:10px',\n ].join(';');\n\n const t = this.theme;\n for (const stat of stats) {\n const card = document.createElement('div');\n card.style.cssText = [\n `background:${surface}`,\n `border:1px solid ${border}`,\n 'border-radius:10px',\n 'padding:10px 12px',\n 'display:flex',\n 'flex-direction:column',\n 'gap:4px',\n ].join(';');\n\n const label = document.createElement('div');\n label.textContent = stat.label;\n label.style.cssText = `font-size:${t.font.sizeSmall}px;color:${t.textSecondary};text-transform:uppercase;letter-spacing:0.04em;`;\n\n const value = document.createElement('div');\n value.textContent = stat.value;\n const color = stat.tone === 'positive' ? t.candleUp : stat.tone === 'negative' ? t.candleDown : t.text;\n value.style.cssText = `font-size:${t.font.sizeLarge}px;font-weight:600;color:${color};font-variant-numeric:tabular-nums;`;\n\n card.appendChild(label);\n card.appendChild(value);\n strip.appendChild(card);\n }\n return strip;\n }\n\n private buildPanel(title: string, surface: string, border: string): { wrap: HTMLDivElement; body: HTMLDivElement } {\n const t = this.theme;\n const wrap = document.createElement('div');\n wrap.style.cssText = [\n `background:${surface}`,\n `border:1px solid ${border}`,\n 'border-radius:10px',\n 'overflow:hidden',\n 'display:flex',\n 'flex-direction:column',\n ].join(';');\n\n const head = document.createElement('div');\n head.textContent = title;\n head.style.cssText = [\n `font-size:${t.font.sizeSmall}px`,\n 'font-weight:600',\n `color:${t.textSecondary}`,\n 'padding:8px 12px',\n `border-bottom:1px solid ${border}`,\n 'text-transform:uppercase',\n 'letter-spacing:0.04em',\n ].join(';');\n\n const body = document.createElement('div');\n body.style.cssText = 'flex:1;min-height:0;position:relative;';\n\n wrap.appendChild(head);\n wrap.appendChild(body);\n return { wrap, body };\n }\n\n /** A subtle surface tint distinct from the page background, per theme. */\n private panelBackground(): string {\n return this.theme.name === 'light' ? 'rgba(0,0,0,0.02)' : 'rgba(255,255,255,0.03)';\n }\n\n /** Replace the displayed result and re-render all panels. */\n update(result: PerformanceResult): void {\n this.options = { ...this.options, result };\n this.destroyCharts();\n this.root.replaceChildren();\n this.build();\n }\n\n setTheme(theme: ThemeName | Theme): void {\n this.theme = resolveTheme(theme);\n this.options = { ...this.options, theme };\n this.destroyCharts();\n this.root.replaceChildren();\n this.build();\n }\n\n private destroyCharts(): void {\n this.equityChart?.destroy();\n this.drawdownChart?.destroy();\n this.heatmap?.destroy();\n this.equityChart = null;\n this.drawdownChart = null;\n this.heatmap = null;\n }\n\n destroy(): void {\n this.destroyCharts();\n this.root.remove();\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","names":[],"sources":["../src/grid/ChartGrid.ts","../src/finance/SparklineChart.ts","../src/finance/DepthChart.ts","../src/finance/EquityCurveChart.ts","../src/finance/HeatmapChart.ts","../src/finance/WaterfallChart.ts","../src/finance/GaugeChart.ts","../src/finance/performanceData.ts","../src/finance/PerformanceDashboard.ts"],"sourcesContent":["import type { ChartOptions, Theme, TimeFrame, DataSeries, DataAdapter, StreamConfig } from '@tradecanvas/commons';\r\nimport { Chart } from '../Chart.js';\r\n\r\nexport type GridLayout = '1x1' | '1x2' | '2x1' | '2x2' | '1x3' | '3x1' | '2x3' | '3x2';\r\n\r\nexport interface GridCellConfig {\r\n symbol?: string;\r\n timeframe?: TimeFrame;\r\n chartOptions?: Partial<ChartOptions>;\r\n}\r\n\r\nexport interface ChartGridOptions {\r\n layout?: GridLayout;\r\n theme?: ChartOptions['theme'];\r\n syncCrosshair?: boolean;\r\n syncTimeAxis?: boolean;\r\n gap?: number;\r\n cells?: GridCellConfig[];\r\n chartOptions?: Partial<ChartOptions>;\r\n}\r\n\r\ninterface GridCell {\r\n container: HTMLDivElement;\r\n chart: Chart;\r\n symbol: string;\r\n timeframe: TimeFrame;\r\n}\r\n\r\nconst LAYOUT_MAP: Record<GridLayout, { cols: number; rows: number }> = {\r\n '1x1': { cols: 1, rows: 1 },\r\n '1x2': { cols: 2, rows: 1 },\r\n '2x1': { cols: 1, rows: 2 },\r\n '2x2': { cols: 2, rows: 2 },\r\n '1x3': { cols: 3, rows: 1 },\r\n '3x1': { cols: 1, rows: 3 },\r\n '2x3': { cols: 3, rows: 2 },\r\n '3x2': { cols: 2, rows: 3 },\r\n};\r\n\r\nexport class ChartGrid {\r\n private root: HTMLDivElement;\r\n private cells: GridCell[] = [];\r\n private layout: GridLayout;\r\n private options: ChartGridOptions;\r\n private destroyed = false;\r\n private syncing = false;\r\n\r\n constructor(container: HTMLElement, options: ChartGridOptions = {}) {\r\n this.options = options;\r\n this.layout = options.layout ?? '2x2';\r\n\r\n this.root = document.createElement('div');\r\n this.root.style.cssText = 'display:grid;width:100%;height:100%;overflow:hidden;';\r\n container.appendChild(this.root);\r\n\r\n this.applyLayout();\r\n this.createCells();\r\n }\r\n\r\n private applyLayout(): void {\r\n const { cols, rows } = LAYOUT_MAP[this.layout];\r\n const gap = this.options.gap ?? 1;\r\n this.root.style.gridTemplateColumns = `repeat(${cols}, 1fr)`;\r\n this.root.style.gridTemplateRows = `repeat(${rows}, 1fr)`;\r\n this.root.style.gap = `${gap}px`;\r\n }\r\n\r\n private createCells(): void {\r\n const { cols, rows } = LAYOUT_MAP[this.layout];\r\n const count = cols * rows;\r\n\r\n for (let i = 0; i < count; i++) {\r\n const cellConfig = this.options.cells?.[i] ?? {};\r\n\r\n const cellEl = document.createElement('div');\r\n cellEl.style.cssText = 'position:relative;overflow:hidden;min-width:0;min-height:0;';\r\n this.root.appendChild(cellEl);\r\n\r\n const chartOpts: ChartOptions = {\r\n chartType: 'candlestick',\r\n autoScale: true,\r\n features: {\r\n crosshair: true,\r\n keyboard: true,\r\n volume: true,\r\n legend: true,\r\n priceAxis: true,\r\n timeAxis: true,\r\n grid: true,\r\n },\r\n ...this.options.chartOptions,\r\n ...cellConfig.chartOptions,\r\n theme: this.options.theme,\r\n };\r\n\r\n const chart = new Chart(cellEl, chartOpts);\r\n\r\n const cell: GridCell = {\r\n container: cellEl,\r\n chart,\r\n symbol: cellConfig.symbol ?? `Chart ${i + 1}`,\r\n timeframe: cellConfig.timeframe ?? '5m',\r\n };\r\n\r\n if (this.options.syncCrosshair !== false) {\r\n chart.on('crosshairMove', (e) => {\r\n if (this.syncing) return;\r\n this.syncing = true;\r\n for (const other of this.cells) {\r\n if (other.chart !== chart) {\r\n other.chart.setCrosshairPosition(e.payload.point);\r\n }\r\n }\r\n this.syncing = false;\r\n });\r\n }\r\n\r\n if (this.options.syncTimeAxis !== false) {\r\n chart.on('visibleRangeChange', (e) => {\r\n if (this.syncing) return;\r\n this.syncing = true;\r\n const { from, to } = e.payload;\r\n const srcData = chart.getData();\r\n if (srcData.length > 0 && from >= 0 && to < srcData.length) {\r\n const fromTime = srcData[from]?.time;\r\n const toTime = srcData[to]?.time;\r\n if (fromTime && toTime) {\r\n for (const other of this.cells) {\r\n if (other.chart !== chart) {\r\n other.chart.setVisibleRange(fromTime, toTime);\r\n }\r\n }\r\n }\r\n }\r\n this.syncing = false;\r\n });\r\n }\r\n\r\n this.cells.push(cell);\r\n }\r\n }\r\n\r\n setLayout(layout: GridLayout): void {\r\n if (layout === this.layout) return;\r\n const oldCount = this.cells.length;\r\n const { cols, rows } = LAYOUT_MAP[layout];\r\n const newCount = cols * rows;\r\n\r\n if (newCount < oldCount) {\r\n for (let i = oldCount - 1; i >= newCount; i--) {\r\n const cell = this.cells[i];\r\n cell.chart.destroy();\r\n cell.container.remove();\r\n this.cells.pop();\r\n }\r\n }\r\n\r\n this.layout = layout;\r\n this.applyLayout();\r\n\r\n if (newCount > oldCount) {\r\n for (let i = oldCount; i < newCount; i++) {\r\n const cellConfig = this.options.cells?.[i] ?? {};\r\n const cellEl = document.createElement('div');\r\n cellEl.style.cssText = 'position:relative;overflow:hidden;min-width:0;min-height:0;';\r\n this.root.appendChild(cellEl);\r\n\r\n const chart = new Chart(cellEl, {\r\n chartType: 'candlestick',\r\n autoScale: true,\r\n ...this.options.chartOptions,\r\n ...cellConfig.chartOptions,\r\n theme: this.options.theme,\r\n });\r\n\r\n this.cells.push({\r\n container: cellEl,\r\n chart,\r\n symbol: cellConfig.symbol ?? `Chart ${i + 1}`,\r\n timeframe: cellConfig.timeframe ?? '5m',\r\n });\r\n }\r\n }\r\n }\r\n\r\n getChart(index: number): Chart | null {\r\n return this.cells[index]?.chart ?? null;\r\n }\r\n\r\n getCharts(): Chart[] {\r\n return this.cells.map(c => c.chart);\r\n }\r\n\r\n getCellCount(): number {\r\n return this.cells.length;\r\n }\r\n\r\n setData(index: number, data: DataSeries): void {\r\n this.cells[index]?.chart.setData(data);\r\n }\r\n\r\n setAllData(data: DataSeries): void {\r\n for (const cell of this.cells) {\r\n cell.chart.setData(data);\r\n }\r\n }\r\n\r\n async connectCell(index: number, config: StreamConfig): Promise<void> {\r\n const cell = this.cells[index];\r\n if (!cell) return;\r\n cell.symbol = config.symbol;\r\n cell.timeframe = config.timeframe;\r\n await cell.chart.connect(config);\r\n }\r\n\r\n async connectAll(adapter: DataAdapter, symbols: string[], timeframe: TimeFrame, historyLimit = 500): Promise<void> {\r\n const promises: Promise<void>[] = [];\r\n for (let i = 0; i < this.cells.length && i < symbols.length; i++) {\r\n promises.push(this.connectCell(i, {\r\n adapter,\r\n symbol: symbols[i],\r\n timeframe,\r\n historyLimit,\r\n }));\r\n }\r\n await Promise.all(promises);\r\n }\r\n\r\n setTheme(theme: Theme): void {\r\n for (const cell of this.cells) {\r\n cell.chart.setTheme(theme);\r\n }\r\n }\r\n\r\n destroy(): void {\r\n if (this.destroyed) return;\r\n this.destroyed = true;\r\n for (const cell of this.cells) {\r\n cell.chart.destroy();\r\n cell.container.remove();\r\n }\r\n this.cells = [];\r\n this.root.remove();\r\n }\r\n}\r\n","import type { SparklineOptions, Theme } from '@tradecanvas/commons';\r\nimport { BaseFinanceChart, renderSparkline } from '@tradecanvas/core';\r\n\r\nexport class SparklineChart extends BaseFinanceChart {\r\n private options: SparklineOptions;\r\n\r\n constructor(container: HTMLElement, options: SparklineOptions) {\r\n super(container, options.theme);\r\n this.options = options;\r\n this.requestRender();\r\n }\r\n\r\n protected renderChart(\r\n ctx: CanvasRenderingContext2D,\r\n width: number,\r\n height: number,\r\n theme: Theme,\r\n ): void {\r\n renderSparkline(ctx, width, height, this.options, theme);\r\n }\r\n\r\n update(data: number[]): void {\r\n this.options = { ...this.options, data };\r\n this.requestRender();\r\n }\r\n\r\n setOptions(opts: Partial<SparklineOptions>): void {\r\n this.options = { ...this.options, ...opts };\r\n this.requestRender();\r\n }\r\n}\r\n","import type { DepthChartOptions, DepthData, Theme } from '@tradecanvas/commons';\r\nimport { BaseFinanceChart, FinanceCrosshair, renderDepthChart } from '@tradecanvas/core';\r\n\r\nexport class DepthChart extends BaseFinanceChart {\r\n private options: DepthChartOptions;\r\n private crosshair: FinanceCrosshair | null = null;\r\n\r\n constructor(container: HTMLElement, options: DepthChartOptions) {\r\n super(container, options.theme);\r\n this.options = options;\r\n\r\n if (options.crosshair !== false) {\r\n this.crosshair = new FinanceCrosshair(this.canvas, () => this.requestRender());\r\n }\r\n\r\n this.requestRender();\r\n }\r\n\r\n protected renderChart(\r\n ctx: CanvasRenderingContext2D,\r\n width: number,\r\n height: number,\r\n theme: Theme,\r\n ): void {\r\n const pos = this.crosshair?.getPosition() ?? null;\r\n renderDepthChart(ctx, width, height, this.options, theme, pos);\r\n }\r\n\r\n update(data: DepthData): void {\r\n this.options = { ...this.options, data };\r\n this.requestRender();\r\n }\r\n\r\n setOptions(opts: Partial<DepthChartOptions>): void {\r\n this.options = { ...this.options, ...opts };\r\n this.requestRender();\r\n }\r\n\r\n destroy(): void {\r\n this.crosshair?.destroy();\r\n super.destroy();\r\n }\r\n}\r\n","import type { EquityCurveOptions, EquityPoint, Theme } from '@tradecanvas/commons';\r\nimport { BaseFinanceChart, FinanceCrosshair, renderEquityCurve } from '@tradecanvas/core';\r\n\r\nexport class EquityCurveChart extends BaseFinanceChart {\r\n private options: EquityCurveOptions;\r\n private crosshair: FinanceCrosshair | null = null;\r\n\r\n constructor(container: HTMLElement, options: EquityCurveOptions) {\r\n super(container, options.theme);\r\n this.options = options;\r\n\r\n if (options.crosshair !== false) {\r\n this.crosshair = new FinanceCrosshair(this.canvas, () => this.requestRender());\r\n }\r\n\r\n this.requestRender();\r\n }\r\n\r\n protected renderChart(\r\n ctx: CanvasRenderingContext2D,\r\n width: number,\r\n height: number,\r\n theme: Theme,\r\n ): void {\r\n const pos = this.crosshair?.getPosition() ?? null;\r\n renderEquityCurve(ctx, width, height, this.options, theme, pos);\r\n }\r\n\r\n update(data: EquityPoint[], benchmark?: EquityPoint[]): void {\r\n this.options = { ...this.options, data };\r\n if (benchmark !== undefined) {\r\n this.options = { ...this.options, benchmark };\r\n }\r\n this.requestRender();\r\n }\r\n\r\n setOptions(opts: Partial<EquityCurveOptions>): void {\r\n this.options = { ...this.options, ...opts };\r\n this.requestRender();\r\n }\r\n\r\n destroy(): void {\r\n this.crosshair?.destroy();\r\n super.destroy();\r\n }\r\n}\r\n","import type { HeatmapCell, HeatmapOptions, Theme } from '@tradecanvas/commons';\r\nimport {\r\n BaseFinanceChart,\r\n FinanceCrosshair,\r\n layoutUniformGrid,\r\n layoutSquarifiedTreemap,\r\n renderHeatmap,\r\n} from '@tradecanvas/core';\r\nimport type { LayoutRect } from '@tradecanvas/core';\r\n\r\nexport class HeatmapChart extends BaseFinanceChart {\r\n private options: HeatmapOptions;\r\n private crosshair: FinanceCrosshair | null = null;\r\n private cachedRects: LayoutRect[] = [];\r\n private currentData: HeatmapCell[] = [];\r\n private lastLayoutWidth = 0;\r\n private lastLayoutHeight = 0;\r\n private handleClick: ((e: MouseEvent) => void) | null = null;\r\n\r\n constructor(container: HTMLElement, options: HeatmapOptions) {\r\n super(container, options.theme);\r\n this.options = options;\r\n this.currentData = options.data ?? [];\r\n\r\n if (options.crosshair !== false) {\r\n this.crosshair = new FinanceCrosshair(this.canvas, () => this.requestRender());\r\n }\r\n\r\n if (options.onCellClick) {\r\n this.handleClick = (e: MouseEvent) => {\r\n const rect = this.canvas.getBoundingClientRect();\r\n const x = e.clientX - rect.left;\r\n const y = e.clientY - rect.top;\r\n this.onCanvasClick(x, y);\r\n };\r\n this.canvas.addEventListener('click', this.handleClick);\r\n }\r\n\r\n this.recomputeLayout();\r\n this.requestRender();\r\n }\r\n\r\n private recomputeLayout(): void {\r\n const bounds = { x: 0, y: 0, width: this.width, height: this.height };\r\n const padding = this.options.cellPadding ?? 2;\r\n this.lastLayoutWidth = this.width;\r\n this.lastLayoutHeight = this.height;\r\n\r\n if (this.options.weighted) {\r\n const weighted = this.currentData.map(c => ({\r\n id: c.id,\r\n weight: c.weight ?? (Math.abs(c.value) || 1),\r\n }));\r\n this.cachedRects = layoutSquarifiedTreemap(weighted, bounds, padding);\r\n } else {\r\n this.cachedRects = layoutUniformGrid(\r\n this.currentData.map(c => ({ id: c.id })),\r\n bounds,\r\n padding,\r\n );\r\n }\r\n }\r\n\r\n private onCanvasClick(x: number, y: number): void {\r\n if (!this.options.onCellClick) return;\r\n\r\n for (const lr of this.cachedRects) {\r\n const r = lr.rect;\r\n if (x >= r.x && x <= r.x + r.width && y >= r.y && y <= r.y + r.height) {\r\n const cell = this.currentData.find(c => c.id === lr.id);\r\n if (cell) this.options.onCellClick(cell);\r\n return;\r\n }\r\n }\r\n }\r\n\r\n protected renderChart(\r\n ctx: CanvasRenderingContext2D,\r\n width: number,\r\n height: number,\r\n theme: Theme,\r\n ): void {\r\n if (width !== this.lastLayoutWidth || height !== this.lastLayoutHeight) {\r\n this.recomputeLayout();\r\n }\r\n\r\n const pos = this.crosshair?.getPosition() ?? null;\r\n renderHeatmap(ctx, width, height, this.currentData, this.cachedRects, this.options, theme, pos);\r\n }\r\n\r\n update(data: HeatmapCell[]): void {\r\n this.currentData = data;\r\n this.options = { ...this.options, data };\r\n this.recomputeLayout();\r\n this.requestRender();\r\n }\r\n\r\n setOptions(opts: Partial<HeatmapOptions>): void {\r\n this.options = { ...this.options, ...opts };\r\n if (opts.data) {\r\n this.currentData = opts.data;\r\n }\r\n this.recomputeLayout();\r\n this.requestRender();\r\n }\r\n\r\n destroy(): void {\r\n this.crosshair?.destroy();\r\n if (this.handleClick) {\r\n this.canvas.removeEventListener('click', this.handleClick);\r\n }\r\n super.destroy();\r\n }\r\n}\r\n","import type { Theme, WaterfallBar, WaterfallOptions } from '@tradecanvas/commons';\r\nimport { BaseFinanceChart, FinanceCrosshair, renderWaterfall } from '@tradecanvas/core';\r\n\r\nexport class WaterfallChart extends BaseFinanceChart {\r\n private options: WaterfallOptions;\r\n private crosshair: FinanceCrosshair | null = null;\r\n\r\n constructor(container: HTMLElement, options: WaterfallOptions) {\r\n super(container, options.theme);\r\n this.options = options;\r\n\r\n if (options.crosshair !== false) {\r\n this.crosshair = new FinanceCrosshair(this.canvas, () => this.requestRender());\r\n }\r\n\r\n this.requestRender();\r\n }\r\n\r\n protected renderChart(\r\n ctx: CanvasRenderingContext2D,\r\n width: number,\r\n height: number,\r\n theme: Theme,\r\n ): void {\r\n const pos = this.crosshair?.getPosition() ?? null;\r\n renderWaterfall(ctx, width, height, this.options, theme, pos);\r\n }\r\n\r\n update(data: WaterfallBar[]): void {\r\n this.options = { ...this.options, data };\r\n this.requestRender();\r\n }\r\n\r\n setOptions(opts: Partial<WaterfallOptions>): void {\r\n this.options = { ...this.options, ...opts };\r\n this.requestRender();\r\n }\r\n\r\n destroy(): void {\r\n this.crosshair?.destroy();\r\n super.destroy();\r\n }\r\n}\r\n","import type { GaugeOptions, Theme } from '@tradecanvas/commons';\r\nimport { BaseFinanceChart, renderGauge } from '@tradecanvas/core';\r\n\r\nconst DEFAULT_ANIMATION_MS = 500;\r\n\r\nfunction easeOutCubic(t: number): number {\r\n const inv = 1 - t;\r\n return 1 - inv * inv * inv;\r\n}\r\n\r\nexport class GaugeChart extends BaseFinanceChart {\r\n private options: GaugeOptions;\r\n private currentValue: number;\r\n private targetValue: number;\r\n private animationStart: number | null = null;\r\n private animationFrom = 0;\r\n private animationFrameId: number | null = null;\r\n\r\n constructor(container: HTMLElement, options: GaugeOptions) {\r\n super(container, options.theme);\r\n this.options = options;\r\n this.currentValue = options.value;\r\n this.targetValue = options.value;\r\n this.requestRender();\r\n }\r\n\r\n protected renderChart(\r\n ctx: CanvasRenderingContext2D,\r\n width: number,\r\n height: number,\r\n theme: Theme,\r\n ): void {\r\n renderGauge(ctx, width, height, this.options, theme, this.currentValue);\r\n }\r\n\r\n setValue(value: number): void {\r\n const animate = this.options.animate !== false;\r\n if (!animate) {\r\n this.cancelAnimation();\r\n this.currentValue = value;\r\n this.targetValue = value;\r\n this.options = { ...this.options, value };\r\n this.requestRender();\r\n return;\r\n }\r\n\r\n this.targetValue = value;\r\n this.animationFrom = this.currentValue;\r\n this.animationStart = performance.now();\r\n this.options = { ...this.options, value };\r\n this.startAnimationLoop();\r\n }\r\n\r\n setOptions(opts: Partial<GaugeOptions>): void {\r\n const next = { ...this.options, ...opts };\r\n // If `value` is part of the partial, route through animation path\r\n if (opts.value !== undefined && opts.value !== this.targetValue) {\r\n this.options = next;\r\n this.setValue(opts.value);\r\n return;\r\n }\r\n this.options = next;\r\n this.requestRender();\r\n }\r\n\r\n private startAnimationLoop(): void {\r\n if (this.animationFrameId !== null) return;\r\n const step = (): void => {\r\n this.animationFrameId = null;\r\n if (this.animationStart === null) return;\r\n\r\n const duration = this.options.animationDuration ?? DEFAULT_ANIMATION_MS;\r\n const elapsed = performance.now() - this.animationStart;\r\n const t = Math.min(1, elapsed / Math.max(1, duration));\r\n const eased = easeOutCubic(t);\r\n this.currentValue = this.animationFrom + (this.targetValue - this.animationFrom) * eased;\r\n\r\n this.requestRender();\r\n\r\n if (t < 1) {\r\n this.animationFrameId = requestAnimationFrame(step);\r\n } else {\r\n this.currentValue = this.targetValue;\r\n this.animationStart = null;\r\n }\r\n };\r\n this.animationFrameId = requestAnimationFrame(step);\r\n }\r\n\r\n private cancelAnimation(): void {\r\n if (this.animationFrameId !== null) {\r\n cancelAnimationFrame(this.animationFrameId);\r\n this.animationFrameId = null;\r\n }\r\n this.animationStart = null;\r\n }\r\n\r\n destroy(): void {\r\n this.cancelAnimation();\r\n super.destroy();\r\n }\r\n}\r\n","import type { EquityPoint, HeatmapCell } from '@tradecanvas/commons';\r\nimport { timeframeBucketStart } from '@tradecanvas/commons';\r\n\r\n/** Minimal equity sample shape — structurally satisfied by analytics' EquityPoint. */\r\nexport interface EquitySample {\r\n time: number;\r\n equity: number;\r\n}\r\n\r\n/** Subset of analytics RiskMetrics needed to render the stats strip. */\r\nexport interface RiskMetricsLike {\r\n totalReturnPct: number;\r\n cagr: number;\r\n sharpe: number;\r\n sortino: number;\r\n maxDrawdownPct: number;\r\n winRate: number;\r\n profitFactor: number;\r\n trades: number;\r\n}\r\n\r\nexport interface DashboardStat {\r\n label: string;\r\n value: string;\r\n tone: 'positive' | 'negative' | 'neutral';\r\n}\r\n\r\nconst MONTH_LABELS = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];\r\n\r\n/** Map an analytics equity curve to the finance EquityCurveChart point shape. */\r\nexport function toEquityPoints(curve: ReadonlyArray<EquitySample>): EquityPoint[] {\r\n return curve.map((p) => ({ time: p.time, value: p.equity }));\r\n}\r\n\r\n/**\r\n * Underwater drawdown curve as a percentage (<= 0). Each point is the equity's\r\n * shortfall from the running peak: `equity / peak - 1`, expressed in percent.\r\n */\r\nexport function computeDrawdownCurve(curve: ReadonlyArray<EquitySample>): EquityPoint[] {\r\n let peak = -Infinity;\r\n return curve.map((p) => {\r\n if (p.equity > peak) peak = p.equity;\r\n const dd = peak > 0 ? (p.equity / peak - 1) * 100 : 0;\r\n return { time: p.time, value: dd };\r\n });\r\n}\r\n\r\n/**\r\n * Calendar-month returns as heatmap cells. Each month's return is chained off\r\n * the prior month's closing equity (the first month chains off its own opening\r\n * equity), so the series reads as sequential monthly performance. `group` is\r\n * the year and `value` is the return in percent.\r\n */\r\nexport function computeMonthlyReturns(curve: ReadonlyArray<EquitySample>): HeatmapCell[] {\r\n if (curve.length === 0) return [];\r\n\r\n // Collapse the curve to one closing equity per calendar month, in order.\r\n const months: { key: number; close: number }[] = [];\r\n for (const p of curve) {\r\n const key = timeframeBucketStart(p.time, '1M');\r\n const last = months[months.length - 1];\r\n if (last && last.key === key) {\r\n last.close = p.equity;\r\n } else {\r\n months.push({ key, close: p.equity });\r\n }\r\n }\r\n\r\n let prevClose = curve[0].equity;\r\n const cells: HeatmapCell[] = [];\r\n for (const m of months) {\r\n const base = prevClose === 0 ? 1 : prevClose;\r\n const returnPct = (m.close / base - 1) * 100;\r\n prevClose = m.close;\r\n const d = new Date(m.key);\r\n const year = d.getUTCFullYear();\r\n const month = d.getUTCMonth();\r\n cells.push({\r\n id: `${year}-${String(month + 1).padStart(2, '0')}`,\r\n label: MONTH_LABELS[month],\r\n group: String(year),\r\n value: returnPct,\r\n });\r\n }\r\n return cells;\r\n}\r\n\r\nfunction pct(value: number): string {\r\n const sign = value > 0 ? '+' : '';\r\n return `${sign}${value.toFixed(2)}%`;\r\n}\r\n\r\nfunction tone(value: number): DashboardStat['tone'] {\r\n if (value > 0) return 'positive';\r\n if (value < 0) return 'negative';\r\n return 'neutral';\r\n}\r\n\r\n/** The headline stats rendered as cards above the charts. */\r\nexport function selectKeyStats(metrics: RiskMetricsLike): DashboardStat[] {\r\n return [\r\n { label: 'Total Return', value: pct(metrics.totalReturnPct), tone: tone(metrics.totalReturnPct) },\r\n { label: 'CAGR', value: pct(metrics.cagr * 100), tone: tone(metrics.cagr) },\r\n { label: 'Sharpe', value: metrics.sharpe.toFixed(2), tone: tone(metrics.sharpe) },\r\n { label: 'Sortino', value: metrics.sortino.toFixed(2), tone: tone(metrics.sortino) },\r\n { label: 'Max Drawdown', value: pct(metrics.maxDrawdownPct), tone: 'negative' },\r\n { label: 'Win Rate', value: `${(metrics.winRate * 100).toFixed(1)}%`, tone: 'neutral' },\r\n { label: 'Profit Factor', value: Number.isFinite(metrics.profitFactor) ? metrics.profitFactor.toFixed(2) : '∞', tone: tone(metrics.profitFactor - 1) },\r\n { label: 'Trades', value: String(metrics.trades), tone: 'neutral' },\r\n ];\r\n}\r\n","import type { Theme, ThemeName } from '@tradecanvas/commons';\r\nimport { DARK_THEME, LIGHT_THEME } from '@tradecanvas/commons';\r\nimport { EquityCurveChart } from './EquityCurveChart.js';\r\nimport { HeatmapChart } from './HeatmapChart.js';\r\nimport {\r\n toEquityPoints,\r\n computeDrawdownCurve,\r\n computeMonthlyReturns,\r\n selectKeyStats,\r\n type EquitySample,\r\n type RiskMetricsLike,\r\n type DashboardStat,\r\n} from './performanceData.js';\r\n\r\n/** Structurally satisfied by analytics' `BacktestResult`. */\r\nexport interface PerformanceResult {\r\n equityCurve: ReadonlyArray<EquitySample>;\r\n metrics: RiskMetricsLike;\r\n}\r\n\r\nexport interface PerformanceDashboardOptions {\r\n result: PerformanceResult;\r\n theme?: ThemeName | Theme;\r\n title?: string;\r\n subtitle?: string;\r\n}\r\n\r\nfunction resolveTheme(theme?: ThemeName | Theme): Theme {\r\n if (!theme || theme === 'dark') return DARK_THEME;\r\n if (theme === 'light') return LIGHT_THEME;\r\n return theme as Theme;\r\n}\r\n\r\n/**\r\n * A composed strategy-performance dashboard: a headline stats strip, an equity\r\n * curve, an underwater drawdown panel, and a monthly-returns heatmap. Built\r\n * entirely from a backtest `result`, reusing the finance chart renderers.\r\n *\r\n * ```ts\r\n * const result = new Backtester(opts).run(bars, strategy);\r\n * const dash = new PerformanceDashboard(el, { result, theme: 'dark' });\r\n * ```\r\n */\r\nexport class PerformanceDashboard {\r\n private options: PerformanceDashboardOptions;\r\n private theme: Theme;\r\n private root: HTMLDivElement;\r\n private equityChart: EquityCurveChart | null = null;\r\n private drawdownChart: EquityCurveChart | null = null;\r\n private heatmap: HeatmapChart | null = null;\r\n\r\n constructor(container: HTMLElement, options: PerformanceDashboardOptions) {\r\n this.options = options;\r\n this.theme = resolveTheme(options.theme);\r\n this.root = document.createElement('div');\r\n this.build();\r\n container.appendChild(this.root);\r\n }\r\n\r\n private build(): void {\r\n const t = this.theme;\r\n const { result, title, subtitle } = this.options;\r\n const surface = this.panelBackground();\r\n const border = t.grid;\r\n\r\n this.root.style.cssText = [\r\n 'display:flex',\r\n 'flex-direction:column',\r\n 'gap:14px',\r\n 'width:100%',\r\n 'box-sizing:border-box',\r\n 'padding:16px',\r\n `background:${t.background}`,\r\n `color:${t.text}`,\r\n `font-family:${t.font.family}`,\r\n ].join(';');\r\n\r\n if (title || subtitle) {\r\n const header = document.createElement('div');\r\n if (title) {\r\n const h = document.createElement('div');\r\n h.textContent = title;\r\n h.style.cssText = `font-size:${t.font.sizeLarge}px;font-weight:600;letter-spacing:-0.01em;`;\r\n header.appendChild(h);\r\n }\r\n if (subtitle) {\r\n const s = document.createElement('div');\r\n s.textContent = subtitle;\r\n s.style.cssText = `font-size:${t.font.sizeSmall}px;color:${t.textSecondary};margin-top:2px;`;\r\n header.appendChild(s);\r\n }\r\n this.root.appendChild(header);\r\n }\r\n\r\n // Stats strip\r\n this.root.appendChild(this.buildStatsStrip(selectKeyStats(result.metrics), surface, border));\r\n\r\n // Chart grid\r\n const grid = document.createElement('div');\r\n grid.style.cssText = [\r\n 'display:grid',\r\n 'grid-template-columns:repeat(auto-fit, minmax(280px, 1fr))',\r\n 'grid-auto-rows:220px',\r\n 'gap:14px',\r\n ].join(';');\r\n this.root.appendChild(grid);\r\n\r\n const equityPanel = this.buildPanel('Equity Curve', surface, border);\r\n equityPanel.wrap.style.gridColumn = '1 / -1';\r\n grid.appendChild(equityPanel.wrap);\r\n this.equityChart = new EquityCurveChart(equityPanel.body, {\r\n data: toEquityPoints(result.equityCurve),\r\n theme: t,\r\n lineColor: t.candleUp,\r\n fillArea: true,\r\n crosshair: true,\r\n });\r\n\r\n const ddPanel = this.buildPanel('Drawdown', surface, border);\r\n grid.appendChild(ddPanel.wrap);\r\n this.drawdownChart = new EquityCurveChart(ddPanel.body, {\r\n data: computeDrawdownCurve(result.equityCurve),\r\n theme: t,\r\n lineColor: t.candleDown,\r\n fillArea: true,\r\n crosshair: true,\r\n valueFormat: (v) => `${v.toFixed(1)}%`,\r\n });\r\n\r\n const monthlyCells = computeMonthlyReturns(result.equityCurve);\r\n const heatPanel = this.buildPanel('Monthly Returns', surface, border);\r\n grid.appendChild(heatPanel.wrap);\r\n this.heatmap = new HeatmapChart(heatPanel.body, {\r\n data: monthlyCells,\r\n theme: t,\r\n showValues: true,\r\n valueFormat: (v) => `${v >= 0 ? '+' : ''}${v.toFixed(1)}`,\r\n colorScale: { negative: t.candleDown, zero: surface, positive: t.candleUp },\r\n });\r\n }\r\n\r\n private buildStatsStrip(stats: DashboardStat[], surface: string, border: string): HTMLDivElement {\r\n const strip = document.createElement('div');\r\n strip.style.cssText = [\r\n 'display:grid',\r\n 'grid-template-columns:repeat(auto-fit, minmax(120px, 1fr))',\r\n 'gap:10px',\r\n ].join(';');\r\n\r\n const t = this.theme;\r\n for (const stat of stats) {\r\n const card = document.createElement('div');\r\n card.style.cssText = [\r\n `background:${surface}`,\r\n `border:1px solid ${border}`,\r\n 'border-radius:10px',\r\n 'padding:10px 12px',\r\n 'display:flex',\r\n 'flex-direction:column',\r\n 'gap:4px',\r\n ].join(';');\r\n\r\n const label = document.createElement('div');\r\n label.textContent = stat.label;\r\n label.style.cssText = `font-size:${t.font.sizeSmall}px;color:${t.textSecondary};text-transform:uppercase;letter-spacing:0.04em;`;\r\n\r\n const value = document.createElement('div');\r\n value.textContent = stat.value;\r\n const color = stat.tone === 'positive' ? t.candleUp : stat.tone === 'negative' ? t.candleDown : t.text;\r\n value.style.cssText = `font-size:${t.font.sizeLarge}px;font-weight:600;color:${color};font-variant-numeric:tabular-nums;`;\r\n\r\n card.appendChild(label);\r\n card.appendChild(value);\r\n strip.appendChild(card);\r\n }\r\n return strip;\r\n }\r\n\r\n private buildPanel(title: string, surface: string, border: string): { wrap: HTMLDivElement; body: HTMLDivElement } {\r\n const t = this.theme;\r\n const wrap = document.createElement('div');\r\n wrap.style.cssText = [\r\n `background:${surface}`,\r\n `border:1px solid ${border}`,\r\n 'border-radius:10px',\r\n 'overflow:hidden',\r\n 'display:flex',\r\n 'flex-direction:column',\r\n ].join(';');\r\n\r\n const head = document.createElement('div');\r\n head.textContent = title;\r\n head.style.cssText = [\r\n `font-size:${t.font.sizeSmall}px`,\r\n 'font-weight:600',\r\n `color:${t.textSecondary}`,\r\n 'padding:8px 12px',\r\n `border-bottom:1px solid ${border}`,\r\n 'text-transform:uppercase',\r\n 'letter-spacing:0.04em',\r\n ].join(';');\r\n\r\n const body = document.createElement('div');\r\n body.style.cssText = 'flex:1;min-height:0;position:relative;';\r\n\r\n wrap.appendChild(head);\r\n wrap.appendChild(body);\r\n return { wrap, body };\r\n }\r\n\r\n /** A subtle surface tint distinct from the page background, per theme. */\r\n private panelBackground(): string {\r\n return this.theme.name === 'light' ? 'rgba(0,0,0,0.02)' : 'rgba(255,255,255,0.03)';\r\n }\r\n\r\n /** Replace the displayed result and re-render all panels. */\r\n update(result: PerformanceResult): void {\r\n this.options = { ...this.options, result };\r\n this.destroyCharts();\r\n this.root.replaceChildren();\r\n this.build();\r\n }\r\n\r\n setTheme(theme: ThemeName | Theme): void {\r\n this.theme = resolveTheme(theme);\r\n this.options = { ...this.options, theme };\r\n this.destroyCharts();\r\n this.root.replaceChildren();\r\n this.build();\r\n }\r\n\r\n private destroyCharts(): void {\r\n this.equityChart?.destroy();\r\n this.drawdownChart?.destroy();\r\n this.heatmap?.destroy();\r\n this.equityChart = null;\r\n this.drawdownChart = null;\r\n this.heatmap = null;\r\n }\r\n\r\n destroy(): void {\r\n this.destroyCharts();\r\n this.root.remove();\r\n }\r\n}\r\n"],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -6,11 +6,11 @@ export * from './plugins/index.js';
6
6
  export { parseOHLCV, DragDropImporter } from './io/index.js';
7
7
  export type { ParseResult, DragDropImporterCallbacks } from './io/index.js';
8
8
  export type { OHLCBar, DataSeries, TimeFrame, ChartOptions, ChartType, Theme, ThemeName, ChartEventType, ChartEvent, ChartEventMap, IndicatorPlugin, IndicatorDescriptor, IndicatorConfig, IndicatorOutput, IndicatorValue, TauriBridgeOptions, ViewportState, CrosshairMovePayload, BarClickPayload, VisibleRangeChangePayload, OrderModifyPayload, OrderCancelPayload, PositionModifyPayload, PositionClosePayload, OrderPlacePayload, IndicatorChangePayload, ThemeChangePayload, ResizePayload, ZoomChangePayload, PriceRangeChangePayload, DrawingCreatePayload, DrawingRemovePayload, SignalMarkerAddPayload, SignalMarkerRemovePayload, TradeZoneAddPayload, TradeZoneRemovePayload, DrawingToolType, DrawingState, DrawingStyle, DrawingPlugin, DrawingDescriptor, FeaturesConfig, SessionBreakOptions, PriceAxisOptions, TimeAxisOptions, AnchorPoint, PanelPosition, PanelConfig, ResolvedLayout, TradingOrder, TradingPosition, DepthData, DepthLevel, TradingConfig, OrderSide, OrderType, OrderStatus, OrderLabel, OrderPlaceIntent, OrderModifyIntent, OrderCancelIntent, PositionModifyIntent, PositionCloseIntent, ExecutionAdapter, ExecutionConfig, ExecutionEvent, ExecutionEventType, ExecutionListener, FillEvent, ExecutionError, Locale, LocaleStrings, MarketConfig, MarketType, StockExchange, MarketColorScheme, TradingSession, PriceLimitInfo, DataAdapter, DataAdapterConfig, DataAdapterEventType, StreamConfig, ConnectionState, ConnectionInfo, RawTick, AggregatedBar, ReconnectConfig, ResolvedIndicatorStyle, WatermarkConfig, GridOptions, CrosshairOptions, SignalMarker, SignalDirection, SignalMarkerStyle, TradeZone, TradeZoneDirection, TradeZoneStyle, } from '@tradecanvas/commons';
9
- export { DARK_THEME, LIGHT_THEME, DARK_TERMINAL, DEFAULT_DRAWING_STYLE, DEFAULT_TRADING_CONFIG, DEFAULT_SIGNAL_STYLE, DEFAULT_TRADE_ZONE_STYLE, TIMEFRAMES_CRYPTO, TIMEFRAMES_STOCK, TIMEFRAMES_FOREX, DEFAULT_TIMEFRAME_FAVORITES, } from '@tradecanvas/commons';
9
+ export { DARK_THEME, LIGHT_THEME, DARK_TERMINAL, TC_PALETTE, TC_SERIES_COLORS, DEFAULT_DRAWING_STYLE, DEFAULT_TRADING_CONFIG, DEFAULT_SIGNAL_STYLE, DEFAULT_TRADE_ZONE_STYLE, TIMEFRAMES_CRYPTO, TIMEFRAMES_STOCK, TIMEFRAMES_FOREX, DEFAULT_TIMEFRAME_FAVORITES, } from '@tradecanvas/commons';
10
10
  export { normalizeBarTime, normalizeBar } from '@tradecanvas/commons';
11
11
  export { setLocale, getLocale, t, registerLocale, formatNumber, formatVND, formatVolumeLoc } from '@tradecanvas/commons';
12
12
  export { MARKET_HOSE, MARKET_HNX, MARKET_UPCOM, MARKET_CRYPTO, MARKET_NYSE, VN_COLORS, createVNTheme, computePriceLimits, getCurrentSession, } from '@tradecanvas/commons';
13
- export { IndicatorBase, DrawingBase } from '@tradecanvas/core';
13
+ export { IndicatorBase, IndicatorValueMap, DrawingBase } from '@tradecanvas/core';
14
14
  export { StreamManager, BinanceAdapter, MockAdapter, TickAggregator, CurrentPriceLine, PaperExecutionAdapter, WebSocketAdapter, PollingAdapter, CoinbaseAdapter, BybitAdapter, KrakenAdapter } from '@tradecanvas/core';
15
15
  export type { PaperExecutionOptions, WebSocketAdapterOptions, WsParseResult, PollingAdapterOptions, CoinbaseAdapterOptions, BybitAdapterOptions, KrakenAdapterOptions } from '@tradecanvas/core';
16
16
  export { DEFAULT_RECONNECT, DEFAULT_STREAM_CONFIG } from '@tradecanvas/commons';
@@ -25,7 +25,8 @@ export { AlertManager, ReplayManager, ChartStateManager, UndoRedoManager, Signal
25
25
  export type { PriceAlert, AlertCondition, ReplayConfig, ChartSnapshot, UndoableAction } from '@tradecanvas/core';
26
26
  export { Animator, Easing } from '@tradecanvas/core';
27
27
  export type { EasingFn, AnimationOptions } from '@tradecanvas/core';
28
- export { KeyboardHandler, CrosshairTooltip } from '@tradecanvas/core';
28
+ export { KeyboardHandler, CrosshairTooltip, formatTooltipTime } from '@tradecanvas/core';
29
+ export type { CrosshairTooltipContext } from '@tradecanvas/core';
29
30
  export { ChartGrid } from './grid/ChartGrid.js';
30
31
  export type { GridLayout, GridCellConfig, ChartGridOptions } from './grid/ChartGrid.js';
31
32
  export { SparklineChart, DepthChart, EquityCurveChart, HeatmapChart, WaterfallChart, GaugeChart, PerformanceDashboard } from './finance/index.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,cAAc,oBAAoB,CAAC;AACnC,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAC7D,YAAY,EAAE,WAAW,EAAE,yBAAyB,EAAE,MAAM,eAAe,CAAC;AAG5E,YAAY,EACV,OAAO,EACP,UAAU,EACV,SAAS,EACT,YAAY,EACZ,SAAS,EACT,KAAK,EACL,SAAS,EACT,cAAc,EACd,UAAU,EACV,aAAa,EACb,eAAe,EACf,mBAAmB,EACnB,eAAe,EACf,eAAe,EACf,cAAc,EACd,kBAAkB,EAClB,aAAa,EACb,oBAAoB,EACpB,eAAe,EACf,yBAAyB,EACzB,kBAAkB,EAClB,kBAAkB,EAClB,qBAAqB,EACrB,oBAAoB,EACpB,iBAAiB,EACjB,sBAAsB,EACtB,kBAAkB,EAClB,aAAa,EACb,iBAAiB,EACjB,uBAAuB,EACvB,oBAAoB,EACpB,oBAAoB,EACpB,sBAAsB,EACtB,yBAAyB,EACzB,mBAAmB,EACnB,sBAAsB,EACtB,eAAe,EACf,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,iBAAiB,EACjB,cAAc,EACd,mBAAmB,EACnB,gBAAgB,EAChB,eAAe,EACf,WAAW,EACX,aAAa,EACb,WAAW,EACX,cAAc,EACd,YAAY,EACZ,eAAe,EACf,SAAS,EACT,UAAU,EACV,aAAa,EACb,SAAS,EACT,SAAS,EACT,WAAW,EACX,UAAU,EACV,gBAAgB,EAChB,iBAAiB,EACjB,iBAAiB,EACjB,oBAAoB,EACpB,mBAAmB,EACnB,gBAAgB,EAChB,eAAe,EACf,cAAc,EACd,kBAAkB,EAClB,iBAAiB,EACjB,SAAS,EACT,cAAc,EACd,MAAM,EACN,aAAa,EACb,YAAY,EACZ,UAAU,EACV,aAAa,EACb,iBAAiB,EACjB,cAAc,EACd,cAAc,EACd,WAAW,EACX,iBAAiB,EACjB,oBAAoB,EACpB,YAAY,EACZ,eAAe,EACf,cAAc,EACd,OAAO,EACP,aAAa,EACb,eAAe,EACf,sBAAsB,EACtB,eAAe,EACf,WAAW,EACX,gBAAgB,EAChB,YAAY,EACZ,eAAe,EACf,iBAAiB,EACjB,SAAS,EACT,kBAAkB,EAClB,cAAc,GACf,MAAM,sBAAsB,CAAC;AAG9B,OAAO,EACL,UAAU,EAAE,WAAW,EAAE,aAAa,EAAE,UAAU,EAAE,gBAAgB,EACpE,qBAAqB,EAAE,sBAAsB,EAC7C,oBAAoB,EAAE,wBAAwB,EAC9C,iBAAiB,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,2BAA2B,GACnF,MAAM,sBAAsB,CAAC;AAG9B,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAGtE,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC,EAAE,cAAc,EAAE,YAAY,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAGzH,OAAO,EACL,WAAW,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,WAAW,EACjE,SAAS,EAAE,aAAa,EAAE,kBAAkB,EAAE,iBAAiB,GAChE,MAAM,sBAAsB,CAAC;AAG9B,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGlF,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,WAAW,EAAE,cAAc,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,cAAc,EAAE,eAAe,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACxN,YAAY,EAAE,qBAAqB,EAAE,uBAAuB,EAAE,aAAa,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACjM,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAGhF,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAClK,YAAY,EAAE,YAAY,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAG7G,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpE,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvE,YAAY,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAG9G,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAGjD,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,iBAAiB,EAAE,eAAe,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAC3I,YAAY,EAAE,UAAU,EAAE,cAAc,EAAE,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAGjH,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AACrD,YAAY,EAAE,QAAQ,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAGpE,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACzF,YAAY,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAGjE,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,YAAY,EAAE,UAAU,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAGxF,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,gBAAgB,EAAE,YAAY,EAAE,cAAc,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAClJ,OAAO,EACL,cAAc,EACd,oBAAoB,EACpB,qBAAqB,EACrB,cAAc,GACf,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EACV,2BAA2B,EAC3B,iBAAiB,EACjB,YAAY,EACZ,eAAe,EACf,aAAa,GACd,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EACV,uBAAuB,EACvB,gBAAgB,EAChB,iBAAiB,EACjB,WAAW,EACX,kBAAkB,EAClB,WAAW,EACX,cAAc,EACd,YAAY,EACZ,gBAAgB,EAChB,SAAS,EACT,YAAY,GACb,MAAM,sBAAsB,CAAC"}
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
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 d, t as ee, u as te } from "./DragDropImporter-CLtRQjKD.js";
2
- import { DARK_TERMINAL as ne, DARK_THEME as re, DARK_THEME as ie, 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, DEFAULT_SESSION_HOURS as ye, DataExporter as be, DrawingBase as xe, Easing as Se, FinanceCrosshair as H, IndicatorBase as Ce, KeyboardHandler as we, KrakenAdapter as Te, MockAdapter as Ee, PaperExecutionAdapter as De, PollingAdapter as Oe, ReplayManager as ke, Screenshot as Ae, SessionBreaks as je, SessionShading as Me, SignalMarkerManager as Ne, StreamManager as Pe, TickAggregator as Fe, TradeZoneManager as Ie, UndoRedoManager as Le, VolumeRenderer as Re, Watermark as ze, WebSocketAdapter as Be, layoutSquarifiedTreemap as Ve, layoutUniformGrid as He, lttbDownsample as Ue, lttbVisibleIndices as We, renderDepthChart as Ge, renderEquityCurve as Ke, renderGauge as qe, renderHeatmap as Je, renderSparkline as Ye, renderWaterfall as Xe, toHeikinAshi as Ze, toKagi as Qe, toLineBreak as $e, toPointAndFigure as et, toRangeBars as tt, toRenko as nt } 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 d, t as ee, u as te } from "./DragDropImporter-cURSpfUb.js";
2
+ import { DARK_TERMINAL as ne, DARK_THEME as re, DARK_THEME as ie, 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 _, TC_PALETTE as v, TC_SERIES_COLORS 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, timeframeBucketStart as I } from "@tradecanvas/commons";
3
+ import { AlertManager as L, Animator as R, BarCountdown as z, BaseFinanceChart as B, BinanceAdapter as V, BybitAdapter as pe, ChartLegend as me, ChartStateManager as he, CoinbaseAdapter as ge, CompareRenderer as _e, CrosshairTooltip as ve, CurrentPriceLine as ye, DEFAULT_LEGEND_CONFIG as be, DEFAULT_SESSION_HOURS as xe, DataExporter as Se, DrawingBase as Ce, Easing as we, FinanceCrosshair as H, IndicatorBase as Te, IndicatorValueMap as Ee, KeyboardHandler as De, KrakenAdapter as Oe, MockAdapter as ke, PaperExecutionAdapter as Ae, PollingAdapter as je, ReplayManager as Me, Screenshot as Ne, SessionBreaks as Pe, SessionShading as Fe, SignalMarkerManager as Ie, StreamManager as Le, TickAggregator as Re, TradeZoneManager as ze, UndoRedoManager as Be, VolumeRenderer as Ve, Watermark as He, WebSocketAdapter as Ue, formatTooltipTime as We, layoutSquarifiedTreemap as Ge, layoutUniformGrid as Ke, lttbDownsample as qe, lttbVisibleIndices as Je, renderDepthChart as Ye, renderEquityCurve as Xe, renderGauge as Ze, renderHeatmap as Qe, renderSparkline as $e, renderWaterfall as et, toHeikinAshi as tt, toKagi as nt, toLineBreak as rt, toPointAndFigure as it, toRangeBars as at, toRenko as ot } from "@tradecanvas/core";
4
4
  //#region src/grid/ChartGrid.ts
5
5
  var U = {
6
6
  "1x1": {
@@ -35,7 +35,7 @@ var U = {
35
35
  cols: 2,
36
36
  rows: 3
37
37
  }
38
- }, rt = class {
38
+ }, st = class {
39
39
  root;
40
40
  cells = [];
41
41
  layout;
@@ -157,13 +157,13 @@ var U = {
157
157
  this.cells = [], this.root.remove();
158
158
  }
159
159
  }
160
- }, W = class extends R {
160
+ }, ct = class extends B {
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
- Ye(e, t, n, this.options, r);
166
+ $e(e, t, n, this.options, r);
167
167
  }
168
168
  update(e) {
169
169
  this.options = {
@@ -177,7 +177,7 @@ var U = {
177
177
  ...e
178
178
  }, this.requestRender();
179
179
  }
180
- }, it = class extends R {
180
+ }, lt = class extends B {
181
181
  options;
182
182
  crosshair = null;
183
183
  constructor(e, t) {
@@ -185,7 +185,7 @@ var U = {
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
+ Ye(e, t, n, this.options, r, i);
189
189
  }
190
190
  update(e) {
191
191
  this.options = {
@@ -202,7 +202,7 @@ var U = {
202
202
  destroy() {
203
203
  this.crosshair?.destroy(), super.destroy();
204
204
  }
205
- }, G = class extends R {
205
+ }, W = class extends B {
206
206
  options;
207
207
  crosshair = null;
208
208
  constructor(e, t) {
@@ -210,7 +210,7 @@ var U = {
210
210
  }
211
211
  renderChart(e, t, n, r) {
212
212
  let i = this.crosshair?.getPosition() ?? null;
213
- Ke(e, t, n, this.options, r, i);
213
+ Xe(e, t, n, this.options, r, i);
214
214
  }
215
215
  update(e, t) {
216
216
  this.options = {
@@ -230,7 +230,7 @@ var U = {
230
230
  destroy() {
231
231
  this.crosshair?.destroy(), super.destroy();
232
232
  }
233
- }, K = class extends R {
233
+ }, G = class extends B {
234
234
  options;
235
235
  crosshair = null;
236
236
  cachedRects = [];
@@ -256,8 +256,8 @@ var U = {
256
256
  id: e.id,
257
257
  weight: e.weight ?? (Math.abs(e.value) || 1)
258
258
  }));
259
- this.cachedRects = Ve(n, e, t);
260
- } else this.cachedRects = He(this.currentData.map((e) => ({ id: e.id })), e, t);
259
+ this.cachedRects = Ge(n, e, t);
260
+ } else this.cachedRects = Ke(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 U = {
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
- Je(e, t, n, this.currentData, this.cachedRects, this.options, r, i);
275
+ Qe(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,7 +289,7 @@ var U = {
289
289
  destroy() {
290
290
  this.crosshair?.destroy(), this.handleClick && this.canvas.removeEventListener("click", this.handleClick), super.destroy();
291
291
  }
292
- }, at = class extends R {
292
+ }, ut = class extends B {
293
293
  options;
294
294
  crosshair = null;
295
295
  constructor(e, t) {
@@ -297,7 +297,7 @@ var U = {
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
+ et(e, t, n, this.options, r, i);
301
301
  }
302
302
  update(e) {
303
303
  this.options = {
@@ -314,12 +314,12 @@ var U = {
314
314
  destroy() {
315
315
  this.crosshair?.destroy(), super.destroy();
316
316
  }
317
- }, ot = 500;
318
- function st(e) {
317
+ }, dt = 500;
318
+ function K(e) {
319
319
  let t = 1 - e;
320
320
  return 1 - t * t * t;
321
321
  }
322
- var ct = class extends R {
322
+ var ft = class extends B {
323
323
  options;
324
324
  currentValue;
325
325
  targetValue;
@@ -330,7 +330,7 @@ var ct = class extends R {
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
- qe(e, t, n, this.options, r, this.currentValue);
333
+ Ze(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 ct = class extends R {
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 ?? ot, n = performance.now() - this.animationStart, r = Math.min(1, n / Math.max(1, t)), i = st(r);
363
+ let t = this.options.animationDuration ?? dt, n = performance.now() - this.animationStart, r = Math.min(1, n / Math.max(1, t)), i = K(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,7 +371,7 @@ var ct = class extends R {
371
371
  destroy() {
372
372
  this.cancelAnimation(), super.destroy();
373
373
  }
374
- }, lt = [
374
+ }, pt = [
375
375
  "Jan",
376
376
  "Feb",
377
377
  "Mar",
@@ -406,7 +406,7 @@ function Y(e) {
406
406
  if (e.length === 0) return [];
407
407
  let t = [];
408
408
  for (let n of e) {
409
- let e = P(n.time, "1M"), r = t[t.length - 1];
409
+ let e = I(n.time, "1M"), r = t[t.length - 1];
410
410
  r && r.key === e ? r.close = n.equity : t.push({
411
411
  key: e,
412
412
  close: n.equity
@@ -419,7 +419,7 @@ function Y(e) {
419
419
  let a = new Date(e.key), o = a.getUTCFullYear(), s = a.getUTCMonth();
420
420
  r.push({
421
421
  id: `${o}-${String(s + 1).padStart(2, "0")}`,
422
- label: lt[s],
422
+ label: pt[s],
423
423
  group: String(o),
424
424
  value: i
425
425
  });
@@ -481,7 +481,7 @@ function Q(e) {
481
481
  function $(e) {
482
482
  return !e || e === "dark" ? ie : e === "light" ? f : e;
483
483
  }
484
- var ut = class {
484
+ var mt = class {
485
485
  options;
486
486
  theme;
487
487
  root;
@@ -524,7 +524,7 @@ var ut = class {
524
524
  "gap:14px"
525
525
  ].join(";"), this.root.appendChild(o);
526
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, {
527
+ s.wrap.style.gridColumn = "1 / -1", o.appendChild(s.wrap), this.equityChart = new W(s.body, {
528
528
  data: q(t.equityCurve),
529
529
  theme: e,
530
530
  lineColor: e.candleUp,
@@ -532,7 +532,7 @@ var ut = class {
532
532
  crosshair: !0
533
533
  });
534
534
  let c = this.buildPanel("Drawdown", i, a);
535
- o.appendChild(c.wrap), this.drawdownChart = new G(c.body, {
535
+ o.appendChild(c.wrap), this.drawdownChart = new W(c.body, {
536
536
  data: J(t.equityCurve),
537
537
  theme: e,
538
538
  lineColor: e.candleDown,
@@ -541,7 +541,7 @@ var ut = class {
541
541
  valueFormat: (e) => `${e.toFixed(1)}%`
542
542
  });
543
543
  let l = Y(t.equityCurve), u = this.buildPanel("Monthly Returns", i, a);
544
- o.appendChild(u.wrap), this.heatmap = new K(u.body, {
544
+ o.appendChild(u.wrap), this.heatmap = new G(u.body, {
545
545
  data: l,
546
546
  theme: e,
547
547
  showValues: !0,
@@ -630,6 +630,6 @@ var ut = class {
630
630
  }
631
631
  };
632
632
  //#endregion
633
- export { F as AlertManager, I as Animator, L as BarCountdown, z as BinanceAdapter, B as BybitAdapter, u as Chart, rt as ChartGrid, V as ChartLegend, pe as ChartStateManager, me as CoinbaseAdapter, he as CompareRenderer, ge as CrosshairTooltip, _e as CurrentPriceLine, ne as DARK_TERMINAL, re as DARK_THEME, ae as DEFAULT_DRAWING_STYLE, ve as DEFAULT_LEGEND_CONFIG, oe as DEFAULT_RECONNECT, ye as DEFAULT_SESSION_HOURS, 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, be as DataExporter, o as DataManager, it as DepthChart, ee as DragDropImporter, xe as DrawingBase, Se as Easing, G as EquityCurveChart, ct as GaugeChart, K as HeatmapChart, Ce as IndicatorBase, we as KeyboardHandler, Te 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, Ee as MockAdapter, a as PLUGIN_API_VERSION, De as PaperExecutionAdapter, ut as PerformanceDashboard, i as PluginManager, Oe as PollingAdapter, ke as ReplayManager, Ae as Screenshot, je as SessionBreaks, Me as SessionShading, Ne as SignalMarkerManager, W as SparklineChart, Pe as StreamManager, v as TIMEFRAMES_CRYPTO, y as TIMEFRAMES_FOREX, b as TIMEFRAMES_STOCK, l as ThemeManager, Fe as TickAggregator, Ie as TradeZoneManager, Le as UndoRedoManager, x as VN_COLORS, Re as VolumeRenderer, at as WaterfallChart, ze as Watermark, Be 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, Ue as lttbDownsample, We as lttbVisibleIndices, k as normalizeBar, A as normalizeBarTime, te as overlaysForLayer, s as parseOHLCV, n as pluginKey, j as registerLocale, d as registerPlugin, Q as selectKeyStats, M as setLocale, N as t, q as toEquityPoints, Ze as toHeikinAshi, Qe as toKagi, $e as toLineBreak, et as toPointAndFigure, tt as toRangeBars, nt as toRenko, t as unregisterPlugin };
633
+ export { L as AlertManager, R as Animator, z as BarCountdown, V as BinanceAdapter, pe as BybitAdapter, u as Chart, st as ChartGrid, me as ChartLegend, he as ChartStateManager, ge as CoinbaseAdapter, _e as CompareRenderer, ve as CrosshairTooltip, ye as CurrentPriceLine, ne as DARK_TERMINAL, re as DARK_THEME, ae as DEFAULT_DRAWING_STYLE, be as DEFAULT_LEGEND_CONFIG, oe as DEFAULT_RECONNECT, xe as DEFAULT_SESSION_HOURS, 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, Se as DataExporter, o as DataManager, lt as DepthChart, ee as DragDropImporter, Ce as DrawingBase, we as Easing, W as EquityCurveChart, ft as GaugeChart, G as HeatmapChart, Te as IndicatorBase, Ee as IndicatorValueMap, De as KeyboardHandler, Oe 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, ke as MockAdapter, a as PLUGIN_API_VERSION, Ae as PaperExecutionAdapter, mt as PerformanceDashboard, i as PluginManager, je as PollingAdapter, Me as ReplayManager, Ne as Screenshot, Pe as SessionBreaks, Fe as SessionShading, Ie as SignalMarkerManager, ct as SparklineChart, Le as StreamManager, v as TC_PALETTE, y as TC_SERIES_COLORS, b as TIMEFRAMES_CRYPTO, x as TIMEFRAMES_FOREX, S as TIMEFRAMES_STOCK, l as ThemeManager, Re as TickAggregator, ze as TradeZoneManager, Be as UndoRedoManager, C as VN_COLORS, Ve as VolumeRenderer, ut as WaterfallChart, He as Watermark, Ue as WebSocketAdapter, e as clearGlobalPlugins, J as computeDrawdownCurve, Y as computeMonthlyReturns, w as computePriceLimits, T as createVNTheme, E as formatNumber, We as formatTooltipTime, D as formatVND, O as formatVolumeLoc, k as getCurrentSession, c as getGlobalPlugins, A as getLocale, qe as lttbDownsample, Je as lttbVisibleIndices, j as normalizeBar, M as normalizeBarTime, te as overlaysForLayer, s as parseOHLCV, n as pluginKey, N as registerLocale, d as registerPlugin, Q as selectKeyStats, P as setLocale, F as t, q as toEquityPoints, tt as toHeikinAshi, nt as toKagi, rt as toLineBreak, it as toPointAndFigure, at as toRangeBars, ot as toRenko, t as unregisterPlugin };
634
634
 
635
635
  //# sourceMappingURL=index.js.map