@363045841yyt/klinechart-core 0.8.11-alpha.0 → 0.8.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/alerts/createAlertController.d.ts +30 -0
- package/dist/alerts/createAlertController.d.ts.map +1 -0
- package/dist/alerts/createAlertController.js +261 -0
- package/dist/alerts/createAlertController.js.map +1 -0
- package/dist/alerts/index.d.ts +5 -0
- package/dist/alerts/index.d.ts.map +1 -0
- package/dist/alerts/index.js +4 -0
- package/dist/alerts/index.js.map +1 -0
- package/dist/alerts/predicates.d.ts +28 -0
- package/dist/alerts/predicates.d.ts.map +1 -0
- package/dist/alerts/predicates.js +211 -0
- package/dist/alerts/predicates.js.map +1 -0
- package/dist/alerts/rollingVolume.d.ts +15 -0
- package/dist/alerts/rollingVolume.d.ts.map +1 -0
- package/dist/alerts/rollingVolume.js +42 -0
- package/dist/alerts/rollingVolume.js.map +1 -0
- package/dist/alerts/ruleSchema.d.ts +42 -0
- package/dist/alerts/ruleSchema.d.ts.map +1 -0
- package/dist/alerts/ruleSchema.js +240 -0
- package/dist/alerts/ruleSchema.js.map +1 -0
- package/dist/alerts/types.d.ts +169 -0
- package/dist/alerts/types.d.ts.map +1 -0
- package/dist/alerts/types.js +24 -0
- package/dist/alerts/types.js.map +1 -0
- package/dist/chartTypes/heikinAshi.d.ts +49 -0
- package/dist/chartTypes/heikinAshi.d.ts.map +1 -0
- package/dist/chartTypes/heikinAshi.js +94 -0
- package/dist/chartTypes/heikinAshi.js.map +1 -0
- package/dist/chartTypes/index.d.ts +6 -0
- package/dist/chartTypes/index.d.ts.map +1 -0
- package/dist/chartTypes/index.js +5 -0
- package/dist/chartTypes/index.js.map +1 -0
- package/dist/chartTypes/pointAndFigure.d.ts +83 -0
- package/dist/chartTypes/pointAndFigure.d.ts.map +1 -0
- package/dist/chartTypes/pointAndFigure.js +159 -0
- package/dist/chartTypes/pointAndFigure.js.map +1 -0
- package/dist/chartTypes/rangeBars.d.ts +61 -0
- package/dist/chartTypes/rangeBars.d.ts.map +1 -0
- package/dist/chartTypes/rangeBars.js +181 -0
- package/dist/chartTypes/rangeBars.js.map +1 -0
- package/dist/chartTypes/renko.d.ts +94 -0
- package/dist/chartTypes/renko.d.ts.map +1 -0
- package/dist/chartTypes/renko.js +207 -0
- package/dist/chartTypes/renko.js.map +1 -0
- package/dist/chartTypes/types.d.ts +97 -0
- package/dist/chartTypes/types.d.ts.map +1 -0
- package/dist/chartTypes/types.js +39 -0
- package/dist/chartTypes/types.js.map +1 -0
- package/dist/components/anchoredVwap/computeAnchoredVwap.d.ts +76 -0
- package/dist/components/anchoredVwap/computeAnchoredVwap.d.ts.map +1 -0
- package/dist/components/anchoredVwap/computeAnchoredVwap.js +155 -0
- package/dist/components/anchoredVwap/computeAnchoredVwap.js.map +1 -0
- package/dist/components/anchoredVwap/createAnchoredVwapController.d.ts +28 -0
- package/dist/components/anchoredVwap/createAnchoredVwapController.d.ts.map +1 -0
- package/dist/components/anchoredVwap/createAnchoredVwapController.js +282 -0
- package/dist/components/anchoredVwap/createAnchoredVwapController.js.map +1 -0
- package/dist/components/anchoredVwap/index.d.ts +11 -0
- package/dist/components/anchoredVwap/index.d.ts.map +1 -0
- package/dist/components/anchoredVwap/index.js +10 -0
- package/dist/components/anchoredVwap/index.js.map +1 -0
- package/dist/components/anchoredVwap/types.d.ts +171 -0
- package/dist/components/anchoredVwap/types.d.ts.map +1 -0
- package/dist/components/anchoredVwap/types.js +25 -0
- package/dist/components/anchoredVwap/types.js.map +1 -0
- package/dist/components/crosshairSync/createCrosshairSync.d.ts +94 -0
- package/dist/components/crosshairSync/createCrosshairSync.d.ts.map +1 -0
- package/dist/components/crosshairSync/createCrosshairSync.js +118 -0
- package/dist/components/crosshairSync/createCrosshairSync.js.map +1 -0
- package/dist/components/crosshairSync/index.d.ts +2 -0
- package/dist/components/crosshairSync/index.d.ts.map +1 -0
- package/dist/components/crosshairSync/index.js +2 -0
- package/dist/components/crosshairSync/index.js.map +1 -0
- package/dist/components/footprint/aggressor.d.ts +89 -0
- package/dist/components/footprint/aggressor.d.ts.map +1 -0
- package/dist/components/footprint/aggressor.js +106 -0
- package/dist/components/footprint/aggressor.js.map +1 -0
- package/dist/components/footprint/createFootprintController.d.ts +29 -0
- package/dist/components/footprint/createFootprintController.d.ts.map +1 -0
- package/dist/components/footprint/createFootprintController.js +264 -0
- package/dist/components/footprint/createFootprintController.js.map +1 -0
- package/dist/components/footprint/index.d.ts +7 -0
- package/dist/components/footprint/index.d.ts.map +1 -0
- package/dist/components/footprint/index.js +4 -0
- package/dist/components/footprint/index.js.map +1 -0
- package/dist/components/footprint/perBarStats.d.ts +63 -0
- package/dist/components/footprint/perBarStats.d.ts.map +1 -0
- package/dist/components/footprint/perBarStats.js +123 -0
- package/dist/components/footprint/perBarStats.js.map +1 -0
- package/dist/components/footprint/types.d.ts +197 -0
- package/dist/components/footprint/types.d.ts.map +1 -0
- package/dist/components/footprint/types.js +23 -0
- package/dist/components/footprint/types.js.map +1 -0
- package/dist/components/mtfOverlay/alignToBaseIndex.d.ts +45 -0
- package/dist/components/mtfOverlay/alignToBaseIndex.d.ts.map +1 -0
- package/dist/components/mtfOverlay/alignToBaseIndex.js +92 -0
- package/dist/components/mtfOverlay/alignToBaseIndex.js.map +1 -0
- package/dist/components/mtfOverlay/createMtfController.d.ts +7 -0
- package/dist/components/mtfOverlay/createMtfController.d.ts.map +1 -0
- package/dist/components/mtfOverlay/createMtfController.js +134 -0
- package/dist/components/mtfOverlay/createMtfController.js.map +1 -0
- package/dist/components/mtfOverlay/index.d.ts +19 -0
- package/dist/components/mtfOverlay/index.d.ts.map +1 -0
- package/dist/components/mtfOverlay/index.js +18 -0
- package/dist/components/mtfOverlay/index.js.map +1 -0
- package/dist/components/mtfOverlay/resampleBars.d.ts +37 -0
- package/dist/components/mtfOverlay/resampleBars.d.ts.map +1 -0
- package/dist/components/mtfOverlay/resampleBars.js +93 -0
- package/dist/components/mtfOverlay/resampleBars.js.map +1 -0
- package/dist/components/mtfOverlay/types.d.ts +132 -0
- package/dist/components/mtfOverlay/types.d.ts.map +1 -0
- package/dist/components/mtfOverlay/types.js +22 -0
- package/dist/components/mtfOverlay/types.js.map +1 -0
- package/dist/components/orderBookHeatmap/createHeatmapController.d.ts +21 -0
- package/dist/components/orderBookHeatmap/createHeatmapController.d.ts.map +1 -0
- package/dist/components/orderBookHeatmap/createHeatmapController.js +234 -0
- package/dist/components/orderBookHeatmap/createHeatmapController.js.map +1 -0
- package/dist/components/orderBookHeatmap/createOrderBookState.d.ts +18 -0
- package/dist/components/orderBookHeatmap/createOrderBookState.d.ts.map +1 -0
- package/dist/components/orderBookHeatmap/createOrderBookState.js +102 -0
- package/dist/components/orderBookHeatmap/createOrderBookState.js.map +1 -0
- package/dist/components/orderBookHeatmap/deltaArchive.d.ts +25 -0
- package/dist/components/orderBookHeatmap/deltaArchive.d.ts.map +1 -0
- package/dist/components/orderBookHeatmap/deltaArchive.js +106 -0
- package/dist/components/orderBookHeatmap/deltaArchive.js.map +1 -0
- package/dist/components/orderBookHeatmap/index.d.ts +13 -0
- package/dist/components/orderBookHeatmap/index.d.ts.map +1 -0
- package/dist/components/orderBookHeatmap/index.js +12 -0
- package/dist/components/orderBookHeatmap/index.js.map +1 -0
- package/dist/components/orderBookHeatmap/logColorScale.d.ts +20 -0
- package/dist/components/orderBookHeatmap/logColorScale.d.ts.map +1 -0
- package/dist/components/orderBookHeatmap/logColorScale.js +71 -0
- package/dist/components/orderBookHeatmap/logColorScale.js.map +1 -0
- package/dist/components/orderBookHeatmap/snapshotRing.d.ts +16 -0
- package/dist/components/orderBookHeatmap/snapshotRing.d.ts.map +1 -0
- package/dist/components/orderBookHeatmap/snapshotRing.js +61 -0
- package/dist/components/orderBookHeatmap/snapshotRing.js.map +1 -0
- package/dist/components/orderBookHeatmap/types.d.ts +128 -0
- package/dist/components/orderBookHeatmap/types.d.ts.map +1 -0
- package/dist/components/orderBookHeatmap/types.js +16 -0
- package/dist/components/orderBookHeatmap/types.js.map +1 -0
- package/dist/components/volumeProfile/binning.d.ts +54 -0
- package/dist/components/volumeProfile/binning.d.ts.map +1 -0
- package/dist/components/volumeProfile/binning.js +123 -0
- package/dist/components/volumeProfile/binning.js.map +1 -0
- package/dist/components/volumeProfile/createVolumeProfileController.d.ts +31 -0
- package/dist/components/volumeProfile/createVolumeProfileController.d.ts.map +1 -0
- package/dist/components/volumeProfile/createVolumeProfileController.js +179 -0
- package/dist/components/volumeProfile/createVolumeProfileController.js.map +1 -0
- package/dist/components/volumeProfile/index.d.ts +6 -0
- package/dist/components/volumeProfile/index.d.ts.map +1 -0
- package/dist/components/volumeProfile/index.js +5 -0
- package/dist/components/volumeProfile/index.js.map +1 -0
- package/dist/components/volumeProfile/poc.d.ts +35 -0
- package/dist/components/volumeProfile/poc.d.ts.map +1 -0
- package/dist/components/volumeProfile/poc.js +51 -0
- package/dist/components/volumeProfile/poc.js.map +1 -0
- package/dist/components/volumeProfile/types.d.ts +138 -0
- package/dist/components/volumeProfile/types.d.ts.map +1 -0
- package/dist/components/volumeProfile/types.js +19 -0
- package/dist/components/volumeProfile/types.js.map +1 -0
- package/dist/components/volumeProfile/valueArea.d.ts +58 -0
- package/dist/components/volumeProfile/valueArea.d.ts.map +1 -0
- package/dist/components/volumeProfile/valueArea.js +172 -0
- package/dist/components/volumeProfile/valueArea.js.map +1 -0
- package/dist/controllers/createChartController.d.ts.map +1 -1
- package/dist/controllers/createChartController.js +22 -11
- package/dist/controllers/createChartController.js.map +1 -1
- package/dist/controllers/types.d.ts +3 -1
- package/dist/controllers/types.d.ts.map +1 -1
- package/dist/data-fetchers/baostock.d.ts.map +1 -1
- package/dist/data-fetchers/baostock.js +2 -1
- package/dist/data-fetchers/baostock.js.map +1 -1
- package/dist/data-fetchers/dataBuffer.effects.d.ts.map +1 -1
- package/dist/data-fetchers/dataBuffer.effects.js +2 -1
- package/dist/data-fetchers/dataBuffer.effects.js.map +1 -1
- package/dist/data-fetchers/fetcherDefinitionRegistry.d.ts.map +1 -1
- package/dist/data-fetchers/fetcherDefinitionRegistry.js +2 -1
- package/dist/data-fetchers/fetcherDefinitionRegistry.js.map +1 -1
- package/dist/data-fetchers/gotdx.js +4 -3
- package/dist/data-fetchers/gotdx.js.map +1 -1
- package/dist/data-fetchers/router.d.ts.map +1 -1
- package/dist/data-fetchers/router.js +4 -3
- package/dist/data-fetchers/router.js.map +1 -1
- package/dist/data-fetchers/tradingview.js +3 -2
- package/dist/data-fetchers/tradingview.js.map +1 -1
- package/dist/engine/chart.d.ts +13 -0
- package/dist/engine/chart.d.ts.map +1 -1
- package/dist/engine/chart.js +109 -0
- package/dist/engine/chart.js.map +1 -1
- package/dist/engine/data/chartDataManager.d.ts +1 -0
- package/dist/engine/data/chartDataManager.d.ts.map +1 -1
- package/dist/engine/data/chartDataManager.js +27 -4
- package/dist/engine/data/chartDataManager.js.map +1 -1
- package/dist/engine/drawing/toolConfig.d.ts.map +1 -1
- package/dist/engine/drawing/toolConfig.js +2 -1
- package/dist/engine/drawing/toolConfig.js.map +1 -1
- package/dist/engine/indicators/chartIndicatorManager.d.ts.map +1 -1
- package/dist/engine/indicators/chartIndicatorManager.js +2 -1
- package/dist/engine/indicators/chartIndicatorManager.js.map +1 -1
- package/dist/engine/indicators/indicatorDefinitionRegistry.d.ts.map +1 -1
- package/dist/engine/indicators/indicatorDefinitionRegistry.js +2 -1
- package/dist/engine/indicators/indicatorDefinitionRegistry.js.map +1 -1
- package/dist/engine/indicators/indicatorMetadata.d.ts.map +1 -1
- package/dist/engine/indicators/indicatorMetadata.js +2 -1
- package/dist/engine/indicators/indicatorMetadata.js.map +1 -1
- package/dist/engine/indicators/indicatorRegistry.d.ts.map +1 -1
- package/dist/engine/indicators/indicatorRegistry.js +6 -5
- package/dist/engine/indicators/indicatorRegistry.js.map +1 -1
- package/dist/engine/indicators/registerBuiltins.d.ts.map +1 -1
- package/dist/engine/indicators/registerBuiltins.js +2 -1
- package/dist/engine/indicators/registerBuiltins.js.map +1 -1
- package/dist/engine/indicators/scheduler.d.ts +6 -0
- package/dist/engine/indicators/scheduler.d.ts.map +1 -1
- package/dist/engine/indicators/scheduler.js +12 -0
- package/dist/engine/indicators/scheduler.js.map +1 -1
- package/dist/engine/indicators/soa.d.ts.map +1 -1
- package/dist/engine/indicators/soa.js +2 -1
- package/dist/engine/indicators/soa.js.map +1 -1
- package/dist/engine/indicators/stateComposer.d.ts.map +1 -1
- package/dist/engine/indicators/stateComposer.js +2 -1
- package/dist/engine/indicators/stateComposer.js.map +1 -1
- package/dist/engine/subPaneManager.d.ts.map +1 -1
- package/dist/engine/subPaneManager.js +2 -1
- package/dist/engine/subPaneManager.js.map +1 -1
- package/dist/engine/utils/chartZoomController.d.ts +2 -0
- package/dist/engine/utils/chartZoomController.d.ts.map +1 -1
- package/dist/engine/utils/chartZoomController.js +5 -1
- package/dist/engine/utils/chartZoomController.js.map +1 -1
- package/dist/errors-help.d.ts +72 -0
- package/dist/errors-help.d.ts.map +1 -0
- package/dist/errors-help.js +149 -0
- package/dist/errors-help.js.map +1 -0
- package/dist/errors.d.ts +64 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +61 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +22 -0
- package/dist/index.js.map +1 -1
- package/dist/indicators/alma.d.ts +27 -0
- package/dist/indicators/alma.d.ts.map +1 -0
- package/dist/indicators/alma.js +36 -0
- package/dist/indicators/alma.js.map +1 -0
- package/dist/indicators/awesomeOscillator.d.ts +19 -0
- package/dist/indicators/awesomeOscillator.d.ts.map +1 -0
- package/dist/indicators/awesomeOscillator.js +36 -0
- package/dist/indicators/awesomeOscillator.js.map +1 -0
- package/dist/indicators/dpo.d.ts +17 -0
- package/dist/indicators/dpo.d.ts.map +1 -0
- package/dist/indicators/dpo.js +24 -0
- package/dist/indicators/dpo.js.map +1 -0
- package/dist/indicators/fisherTransform.d.ts +26 -0
- package/dist/indicators/fisherTransform.d.ts.map +1 -0
- package/dist/indicators/fisherTransform.js +44 -0
- package/dist/indicators/fisherTransform.js.map +1 -0
- package/dist/indicators/frama.d.ts +25 -0
- package/dist/indicators/frama.d.ts.map +1 -0
- package/dist/indicators/frama.js +61 -0
- package/dist/indicators/frama.js.map +1 -0
- package/dist/indicators/index.d.ts +24 -0
- package/dist/indicators/index.d.ts.map +1 -0
- package/dist/indicators/index.js +26 -0
- package/dist/indicators/index.js.map +1 -0
- package/dist/indicators/lsma.d.ts +21 -0
- package/dist/indicators/lsma.d.ts.map +1 -0
- package/dist/indicators/lsma.js +37 -0
- package/dist/indicators/lsma.js.map +1 -0
- package/dist/indicators/schaffTrendCycle.d.ts +24 -0
- package/dist/indicators/schaffTrendCycle.d.ts.map +1 -0
- package/dist/indicators/schaffTrendCycle.js +70 -0
- package/dist/indicators/schaffTrendCycle.js.map +1 -0
- package/dist/indicators/stochRSI.d.ts +24 -0
- package/dist/indicators/stochRSI.d.ts.map +1 -0
- package/dist/indicators/stochRSI.js +86 -0
- package/dist/indicators/stochRSI.js.map +1 -0
- package/dist/indicators/t3.d.ts +31 -0
- package/dist/indicators/t3.d.ts.map +1 -0
- package/dist/indicators/t3.js +63 -0
- package/dist/indicators/t3.js.map +1 -0
- package/dist/indicators/ultimateOscillator.d.ts +26 -0
- package/dist/indicators/ultimateOscillator.d.ts.map +1 -0
- package/dist/indicators/ultimateOscillator.js +59 -0
- package/dist/indicators/ultimateOscillator.js.map +1 -0
- package/dist/indicators/vidya.d.ts +24 -0
- package/dist/indicators/vidya.d.ts.map +1 -0
- package/dist/indicators/vidya.js +54 -0
- package/dist/indicators/vidya.js.map +1 -0
- package/dist/indicators/zlema.d.ts +16 -0
- package/dist/indicators/zlema.d.ts.map +1 -0
- package/dist/indicators/zlema.js +26 -0
- package/dist/indicators/zlema.js.map +1 -0
- package/dist/input/gesture.d.ts +125 -0
- package/dist/input/gesture.d.ts.map +1 -0
- package/dist/input/gesture.js +249 -0
- package/dist/input/gesture.js.map +1 -0
- package/dist/input/index.d.ts +9 -0
- package/dist/input/index.d.ts.map +1 -0
- package/dist/input/index.js +9 -0
- package/dist/input/index.js.map +1 -0
- package/dist/input/keyboard.d.ts +140 -0
- package/dist/input/keyboard.d.ts.map +1 -0
- package/dist/input/keyboard.js +260 -0
- package/dist/input/keyboard.js.map +1 -0
- package/dist/mcp/chartBridge.d.ts +2 -2
- package/dist/mcp/chartBridge.d.ts.map +1 -1
- package/dist/mcp/chartBridge.js +27 -21
- package/dist/mcp/chartBridge.js.map +1 -1
- package/dist/plugin/PluginHost.d.ts +0 -3
- package/dist/plugin/PluginHost.d.ts.map +1 -1
- package/dist/plugin/PluginHost.js +7 -3
- package/dist/plugin/PluginHost.js.map +1 -1
- package/dist/plugin/PluginRegistry.d.ts +0 -3
- package/dist/plugin/PluginRegistry.d.ts.map +1 -1
- package/dist/plugin/PluginRegistry.js +5 -1
- package/dist/plugin/PluginRegistry.js.map +1 -1
- package/dist/render/Renderer.d.ts +116 -0
- package/dist/render/Renderer.d.ts.map +1 -0
- package/dist/render/Renderer.js +31 -0
- package/dist/render/Renderer.js.map +1 -0
- package/dist/render/SurfaceBackend.d.ts +83 -0
- package/dist/render/SurfaceBackend.d.ts.map +1 -0
- package/dist/render/SurfaceBackend.js +27 -0
- package/dist/render/SurfaceBackend.js.map +1 -0
- package/dist/render/index.d.ts +12 -0
- package/dist/render/index.d.ts.map +1 -0
- package/dist/render/index.js +11 -0
- package/dist/render/index.js.map +1 -0
- package/dist/renderer-tier/detectRendererTier.d.ts +57 -0
- package/dist/renderer-tier/detectRendererTier.d.ts.map +1 -0
- package/dist/renderer-tier/detectRendererTier.js +143 -0
- package/dist/renderer-tier/detectRendererTier.js.map +1 -0
- package/dist/renderer-tier/index.d.ts +12 -0
- package/dist/renderer-tier/index.d.ts.map +1 -0
- package/dist/renderer-tier/index.js +12 -0
- package/dist/renderer-tier/index.js.map +1 -0
- package/dist/renderer-tier/selectBackend.d.ts +106 -0
- package/dist/renderer-tier/selectBackend.d.ts.map +1 -0
- package/dist/renderer-tier/selectBackend.js +113 -0
- package/dist/renderer-tier/selectBackend.js.map +1 -0
- package/dist/renderer-tier/types.d.ts +50 -0
- package/dist/renderer-tier/types.d.ts.map +1 -0
- package/dist/renderer-tier/types.js +24 -0
- package/dist/renderer-tier/types.js.map +1 -0
- package/dist/replay/createReplayController.d.ts +3 -0
- package/dist/replay/createReplayController.d.ts.map +1 -0
- package/dist/replay/createReplayController.js +251 -0
- package/dist/replay/createReplayController.js.map +1 -0
- package/dist/replay/index.d.ts +5 -0
- package/dist/replay/index.d.ts.map +1 -0
- package/dist/replay/index.js +3 -0
- package/dist/replay/index.js.map +1 -0
- package/dist/replay/timeline.d.ts +50 -0
- package/dist/replay/timeline.d.ts.map +1 -0
- package/dist/replay/timeline.js +104 -0
- package/dist/replay/timeline.js.map +1 -0
- package/dist/replay/types.d.ts +94 -0
- package/dist/replay/types.d.ts.map +1 -0
- package/dist/replay/types.js +21 -0
- package/dist/replay/types.js.map +1 -0
- package/dist/scale/anchoredZoom.d.ts +64 -0
- package/dist/scale/anchoredZoom.d.ts.map +1 -0
- package/dist/scale/anchoredZoom.js +67 -0
- package/dist/scale/anchoredZoom.js.map +1 -0
- package/dist/scale/createPriceScale.d.ts +49 -0
- package/dist/scale/createPriceScale.d.ts.map +1 -0
- package/dist/scale/createPriceScale.js +175 -0
- package/dist/scale/createPriceScale.js.map +1 -0
- package/dist/scale/createTimeScale.d.ts +27 -0
- package/dist/scale/createTimeScale.d.ts.map +1 -0
- package/dist/scale/createTimeScale.js +139 -0
- package/dist/scale/createTimeScale.js.map +1 -0
- package/dist/scale/index.d.ts +6 -0
- package/dist/scale/index.d.ts.map +1 -0
- package/dist/scale/index.js +5 -0
- package/dist/scale/index.js.map +1 -0
- package/dist/scale/originShift.d.ts +69 -0
- package/dist/scale/originShift.d.ts.map +1 -0
- package/dist/scale/originShift.js +41 -0
- package/dist/scale/originShift.js.map +1 -0
- package/dist/scale/types.d.ts +90 -0
- package/dist/scale/types.d.ts.map +1 -0
- package/dist/scale/types.js +17 -0
- package/dist/scale/types.js.map +1 -0
- package/dist/scene/createScene.d.ts +22 -0
- package/dist/scene/createScene.d.ts.map +1 -0
- package/dist/scene/createScene.js +114 -0
- package/dist/scene/createScene.js.map +1 -0
- package/dist/scene/index.d.ts +13 -0
- package/dist/scene/index.d.ts.map +1 -0
- package/dist/scene/index.js +11 -0
- package/dist/scene/index.js.map +1 -0
- package/dist/scene/layerRegistry.d.ts +83 -0
- package/dist/scene/layerRegistry.d.ts.map +1 -0
- package/dist/scene/layerRegistry.js +43 -0
- package/dist/scene/layerRegistry.js.map +1 -0
- package/dist/scene/types.d.ts +128 -0
- package/dist/scene/types.d.ts.map +1 -0
- package/dist/scene/types.js +21 -0
- package/dist/scene/types.js.map +1 -0
- package/dist/scheduler/createFrameBudget.d.ts +91 -0
- package/dist/scheduler/createFrameBudget.d.ts.map +1 -0
- package/dist/scheduler/createFrameBudget.js +232 -0
- package/dist/scheduler/createFrameBudget.js.map +1 -0
- package/dist/scheduler/index.d.ts +2 -0
- package/dist/scheduler/index.d.ts.map +1 -0
- package/dist/scheduler/index.js +2 -0
- package/dist/scheduler/index.js.map +1 -0
- package/dist/tokens/themeToCssVars.d.ts.map +1 -1
- package/dist/tokens/themeToCssVars.js +2 -28
- package/dist/tokens/themeToCssVars.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.d.ts.map +1 -1
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/package.json +1 -1
- package/src/__bench__/indicators.bench.ts +215 -0
- package/src/__bench__/orderBookHeatmap.bench.ts +68 -0
- package/src/__bench__/scale.bench.ts +80 -0
- package/src/__bench__/signal.bench.ts +41 -0
- package/src/__bench__/volumeProfile.bench.ts +66 -0
- package/src/__tests__/errors-help.test.ts +184 -0
- package/src/__tests__/errors.test.ts +187 -0
- package/src/alerts/__tests__/controller.test.ts +231 -0
- package/src/alerts/__tests__/predicates.test.ts +374 -0
- package/src/alerts/__tests__/ruleSchema.test.ts +180 -0
- package/src/alerts/createAlertController.ts +312 -0
- package/src/alerts/index.ts +18 -0
- package/src/alerts/predicates.ts +231 -0
- package/src/alerts/rollingVolume.ts +51 -0
- package/src/alerts/ruleSchema.ts +278 -0
- package/src/alerts/types.ts +177 -0
- package/src/chartTypes/__tests__/heikinAshi.test.ts +122 -0
- package/src/chartTypes/__tests__/pointAndFigure.test.ts +167 -0
- package/src/chartTypes/__tests__/rangeBars.test.ts +146 -0
- package/src/chartTypes/__tests__/renko.test.ts +160 -0
- package/src/chartTypes/heikinAshi.ts +116 -0
- package/src/chartTypes/index.ts +5 -0
- package/src/chartTypes/pointAndFigure.ts +278 -0
- package/src/chartTypes/rangeBars.ts +303 -0
- package/src/chartTypes/renko.ts +311 -0
- package/src/chartTypes/types.ts +99 -0
- package/src/components/anchoredVwap/__tests__/computeAnchoredVwap.test.ts +331 -0
- package/src/components/anchoredVwap/__tests__/controller.test.ts +430 -0
- package/src/components/anchoredVwap/computeAnchoredVwap.ts +174 -0
- package/src/components/anchoredVwap/createAnchoredVwapController.ts +358 -0
- package/src/components/anchoredVwap/index.ts +17 -0
- package/src/components/anchoredVwap/types.ts +187 -0
- package/src/components/crosshairSync/__tests__/crosshairSync.test.ts +261 -0
- package/src/components/crosshairSync/createCrosshairSync.ts +187 -0
- package/src/components/crosshairSync/index.ts +5 -0
- package/src/components/footprint/__tests__/aggressor.test.ts +127 -0
- package/src/components/footprint/__tests__/controller.test.ts +130 -0
- package/src/components/footprint/__tests__/perBarStats.test.ts +114 -0
- package/src/components/footprint/aggressor.ts +165 -0
- package/src/components/footprint/createFootprintController.ts +338 -0
- package/src/components/footprint/index.ts +21 -0
- package/src/components/footprint/perBarStats.ts +137 -0
- package/src/components/footprint/types.ts +232 -0
- package/src/components/mtfOverlay/__tests__/alignToBaseIndex.test.ts +103 -0
- package/src/components/mtfOverlay/__tests__/controller.test.ts +172 -0
- package/src/components/mtfOverlay/__tests__/resampleBars.test.ts +106 -0
- package/src/components/mtfOverlay/alignToBaseIndex.ts +108 -0
- package/src/components/mtfOverlay/createMtfController.ts +180 -0
- package/src/components/mtfOverlay/index.ts +26 -0
- package/src/components/mtfOverlay/resampleBars.ts +134 -0
- package/src/components/mtfOverlay/types.ts +148 -0
- package/src/components/orderBookHeatmap/__tests__/controller.test.ts +237 -0
- package/src/components/orderBookHeatmap/__tests__/deltaArchive.test.ts +88 -0
- package/src/components/orderBookHeatmap/__tests__/logColorScale.test.ts +69 -0
- package/src/components/orderBookHeatmap/__tests__/orderBookState.test.ts +113 -0
- package/src/components/orderBookHeatmap/__tests__/snapshotRing.test.ts +53 -0
- package/src/components/orderBookHeatmap/computeShader.wgsl.md +130 -0
- package/src/components/orderBookHeatmap/createHeatmapController.ts +273 -0
- package/src/components/orderBookHeatmap/createOrderBookState.ts +116 -0
- package/src/components/orderBookHeatmap/deltaArchive.ts +113 -0
- package/src/components/orderBookHeatmap/index.ts +25 -0
- package/src/components/orderBookHeatmap/logColorScale.ts +77 -0
- package/src/components/orderBookHeatmap/snapshotRing.ts +65 -0
- package/src/components/orderBookHeatmap/types.ts +168 -0
- package/src/components/volumeProfile/__tests__/binning.test.ts +133 -0
- package/src/components/volumeProfile/__tests__/poc.test.ts +44 -0
- package/src/components/volumeProfile/__tests__/valueArea.test.ts +177 -0
- package/src/components/volumeProfile/binning.ts +133 -0
- package/src/components/volumeProfile/createVolumeProfileController.ts +213 -0
- package/src/components/volumeProfile/index.ts +12 -0
- package/src/components/volumeProfile/poc.ts +53 -0
- package/src/components/volumeProfile/types.ts +148 -0
- package/src/components/volumeProfile/valueArea.ts +187 -0
- package/src/controllers/createChartController.ts +23 -10
- package/src/controllers/types.ts +5 -1
- package/src/data-fetchers/baostock.ts +2 -1
- package/src/data-fetchers/dataBuffer.effects.ts +3 -1
- package/src/data-fetchers/fetcherDefinitionRegistry.ts +2 -1
- package/src/data-fetchers/gotdx.ts +4 -3
- package/src/data-fetchers/router.ts +6 -3
- package/src/data-fetchers/tradingview.ts +3 -2
- package/src/engine/chart.ts +126 -3
- package/src/engine/data/chartDataManager.ts +26 -4
- package/src/engine/drawing/toolConfig.ts +2 -1
- package/src/engine/indicators/chartIndicatorManager.ts +2 -1
- package/src/engine/indicators/indicatorDefinitionRegistry.ts +2 -1
- package/src/engine/indicators/indicatorMetadata.ts +2 -1
- package/src/engine/indicators/indicatorRegistry.ts +6 -5
- package/src/engine/indicators/registerBuiltins.ts +2 -1
- package/src/engine/indicators/scheduler.ts +15 -0
- package/src/engine/indicators/soa.ts +2 -1
- package/src/engine/indicators/stateComposer.ts +2 -1
- package/src/engine/subPaneManager.ts +2 -1
- package/src/engine/utils/chartZoomController.ts +7 -1
- package/src/errors-help.ts +218 -0
- package/src/errors.ts +128 -0
- package/src/index.ts +37 -0
- package/src/indicators/__tests__/maFamily.test.ts +159 -0
- package/src/indicators/__tests__/oscillators.test.ts +150 -0
- package/src/indicators/alma.ts +61 -0
- package/src/indicators/awesomeOscillator.ts +54 -0
- package/src/indicators/dpo.ts +37 -0
- package/src/indicators/fisherTransform.ts +63 -0
- package/src/indicators/frama.ts +87 -0
- package/src/indicators/index.ts +39 -0
- package/src/indicators/lsma.ts +58 -0
- package/src/indicators/schaffTrendCycle.ts +92 -0
- package/src/indicators/stochRSI.ts +108 -0
- package/src/indicators/t3.ts +96 -0
- package/src/indicators/ultimateOscillator.ts +83 -0
- package/src/indicators/vidya.ts +80 -0
- package/src/indicators/zlema.ts +41 -0
- package/src/input/__tests__/gesture.test.ts +271 -0
- package/src/input/__tests__/keyboard.test.ts +317 -0
- package/src/input/gesture.ts +357 -0
- package/src/input/index.ts +26 -0
- package/src/input/keyboard.ts +373 -0
- package/src/mcp/chartBridge.ts +98 -72
- package/src/plugin/PluginHost.ts +4 -3
- package/src/plugin/PluginRegistry.ts +2 -1
- package/src/render/Renderer.ts +127 -0
- package/src/render/SurfaceBackend.ts +94 -0
- package/src/render/__tests__/contract.test.ts +176 -0
- package/src/render/index.ts +27 -0
- package/src/renderer-tier/__tests__/detectRendererTier.test.ts +180 -0
- package/src/renderer-tier/__tests__/selectBackend.test.ts +253 -0
- package/src/renderer-tier/detectRendererTier.ts +168 -0
- package/src/renderer-tier/index.ts +30 -0
- package/src/renderer-tier/selectBackend.ts +201 -0
- package/src/renderer-tier/types.ts +59 -0
- package/src/replay/__tests__/controller.test.ts +309 -0
- package/src/replay/__tests__/timeline.test.ts +99 -0
- package/src/replay/createReplayController.ts +302 -0
- package/src/replay/index.ts +15 -0
- package/src/replay/timeline.ts +106 -0
- package/src/replay/types.ts +107 -0
- package/src/scale/__tests__/anchoredZoom.test.ts +125 -0
- package/src/scale/__tests__/originShift.test.ts +97 -0
- package/src/scale/__tests__/priceScale.test.ts +219 -0
- package/src/scale/__tests__/timeScale.test.ts +119 -0
- package/src/scale/anchoredZoom.ts +104 -0
- package/src/scale/createPriceScale.ts +226 -0
- package/src/scale/createTimeScale.ts +150 -0
- package/src/scale/index.ts +9 -0
- package/src/scale/originShift.ts +111 -0
- package/src/scale/types.ts +100 -0
- package/src/scene/__tests__/layerRegistry.test.ts +207 -0
- package/src/scene/__tests__/scene.test.ts +411 -0
- package/src/scene/createScene.ts +117 -0
- package/src/scene/index.ts +29 -0
- package/src/scene/layerRegistry.ts +117 -0
- package/src/scene/types.ts +143 -0
- package/src/scheduler/__tests__/createFrameBudget.test.ts +315 -0
- package/src/scheduler/createFrameBudget.ts +316 -0
- package/src/scheduler/index.ts +7 -0
- package/src/tokens/themeToCssVars.ts +3 -1
- package/src/version.ts +1 -1
- package/dist/data-fetchers/gotdx/gotdx.d.ts +0 -7
- package/dist/data-fetchers/gotdx/gotdx.d.ts.map +0 -1
- package/dist/data-fetchers/gotdx/gotdx.js +0 -7
- package/dist/data-fetchers/gotdx/gotdx.js.map +0 -1
- package/src/data-fetchers/gotdx/gotdx.ts +0 -6
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Timeline — bar-index ↔ timestamp navigation.
|
|
3
|
+
*
|
|
4
|
+
* A `BarCalendar` is the authoritative list of bar open-times in
|
|
5
|
+
* milliseconds. Real markets aren't uniformly spaced: there are weekend
|
|
6
|
+
* gaps, half-day holiday closes, exchange maintenance windows, etc. The
|
|
7
|
+
* timeline functions must honor those gaps exactly — bar N and bar N+1 can
|
|
8
|
+
* be 60 seconds apart on a Tuesday and three days apart Friday→Monday.
|
|
9
|
+
*
|
|
10
|
+
* Both functions are pure and total: out-of-range inputs return `null`
|
|
11
|
+
* instead of throwing. Callers (e.g. the replay controller, the crosshair
|
|
12
|
+
* tooltip) should treat `null` as "no data at that position".
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* Look up the timestamp for an integer bar index.
|
|
16
|
+
*
|
|
17
|
+
* Fractional `barIndex` is floored — the timestamp returned is the
|
|
18
|
+
* open-time of the containing bar. (Callers that want intra-bar
|
|
19
|
+
* interpolation should do it themselves.)
|
|
20
|
+
*
|
|
21
|
+
* Returns `null` if the calendar is empty or the index is out of range.
|
|
22
|
+
*/
|
|
23
|
+
export function barIndexToTimestamp(calendar, barIndex) {
|
|
24
|
+
if (calendar.length === 0)
|
|
25
|
+
return null;
|
|
26
|
+
if (!Number.isFinite(barIndex))
|
|
27
|
+
return null;
|
|
28
|
+
const idx = Math.floor(barIndex);
|
|
29
|
+
if (idx < 0 || idx >= calendar.length)
|
|
30
|
+
return null;
|
|
31
|
+
// We've bounds-checked the index, so this access is safe.
|
|
32
|
+
return calendar[idx];
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Look up the bar index that contains a given timestamp.
|
|
36
|
+
*
|
|
37
|
+
* Uses binary search; cost is O(log n). The returned index is the bar
|
|
38
|
+
* whose open-time is the largest value `<= ts`. This means a timestamp
|
|
39
|
+
* that falls inside a non-trading gap (e.g. Saturday) resolves to the
|
|
40
|
+
* last bar before the gap (Friday's close), which is the intuitive
|
|
41
|
+
* behavior for "scrub to this wall-clock time".
|
|
42
|
+
*
|
|
43
|
+
* Returns `null` if the calendar is empty or `ts` precedes the first bar.
|
|
44
|
+
*/
|
|
45
|
+
export function timestampToBarIndex(calendar, ts) {
|
|
46
|
+
if (calendar.length === 0)
|
|
47
|
+
return null;
|
|
48
|
+
if (!Number.isFinite(ts))
|
|
49
|
+
return null;
|
|
50
|
+
const first = calendar[0];
|
|
51
|
+
if (ts < first)
|
|
52
|
+
return null;
|
|
53
|
+
const last = calendar[calendar.length - 1];
|
|
54
|
+
if (ts >= last)
|
|
55
|
+
return calendar.length - 1;
|
|
56
|
+
// Binary search for the largest index `i` such that calendar[i] <= ts.
|
|
57
|
+
let lo = 0;
|
|
58
|
+
let hi = calendar.length - 1;
|
|
59
|
+
while (lo < hi) {
|
|
60
|
+
// Bias the midpoint up so `lo` converges to the upper bound.
|
|
61
|
+
const mid = (lo + hi + 1) >>> 1;
|
|
62
|
+
const v = calendar[mid];
|
|
63
|
+
if (v <= ts) {
|
|
64
|
+
lo = mid;
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
hi = mid - 1;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return lo;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Compute the dominant bar interval (in ms) from a calendar.
|
|
74
|
+
*
|
|
75
|
+
* Uses the median delta between successive bars, which is robust to
|
|
76
|
+
* weekend and holiday gaps that would skew a simple mean. Returns
|
|
77
|
+
* `null` if the calendar has fewer than two bars.
|
|
78
|
+
*
|
|
79
|
+
* The replay controller uses this when `barIntervalMs` is not configured
|
|
80
|
+
* but a calendar is available, so wall-clock pacing self-calibrates.
|
|
81
|
+
*/
|
|
82
|
+
export function inferBarIntervalMs(calendar) {
|
|
83
|
+
if (calendar.length < 2)
|
|
84
|
+
return null;
|
|
85
|
+
const deltas = [];
|
|
86
|
+
for (let i = 1; i < calendar.length; i++) {
|
|
87
|
+
const a = calendar[i - 1];
|
|
88
|
+
const b = calendar[i];
|
|
89
|
+
const d = b - a;
|
|
90
|
+
if (d > 0)
|
|
91
|
+
deltas.push(d);
|
|
92
|
+
}
|
|
93
|
+
if (deltas.length === 0)
|
|
94
|
+
return null;
|
|
95
|
+
deltas.sort((a, b) => a - b);
|
|
96
|
+
const mid = deltas.length >>> 1;
|
|
97
|
+
if (deltas.length % 2 === 1) {
|
|
98
|
+
return deltas[mid];
|
|
99
|
+
}
|
|
100
|
+
const lo = deltas[mid - 1];
|
|
101
|
+
const hi = deltas[mid];
|
|
102
|
+
return (lo + hi) / 2;
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=timeline.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"timeline.js","sourceRoot":"","sources":["../../src/replay/timeline.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bar Replay — public types.
|
|
3
|
+
*
|
|
4
|
+
* The replay subsystem models a playhead that scrubs through a finite bar
|
|
5
|
+
* series. Three pacing strategies are supported:
|
|
6
|
+
*
|
|
7
|
+
* - `bar` step-by-bar; `tick()` is a no-op, callers drive position
|
|
8
|
+
* via `stepForward` / `stepBackward` (keyboard-driven).
|
|
9
|
+
* - `wallclock` real-time playback; `tick(deltaMs)` advances by
|
|
10
|
+
* `(deltaMs / msPerBar) * speed` bars. `speed` is a
|
|
11
|
+
* multiplier (1 = realtime, 10 = 10x).
|
|
12
|
+
* - `tick` synthetic tick replay; `tick(deltaMs)` advances by
|
|
13
|
+
* `(deltaMs / 100) * speed` bars (100ms per nominal step).
|
|
14
|
+
*
|
|
15
|
+
* Why this matters: TradingView's Bar Replay is wall-clock only and hides its
|
|
16
|
+
* state. Ours is observable via the `state` signal — any backtest engine,
|
|
17
|
+
* recording session, or sibling controller can subscribe and react to
|
|
18
|
+
* playhead changes deterministically.
|
|
19
|
+
*/
|
|
20
|
+
import type { Signal } from '../reactivity/signal';
|
|
21
|
+
export type ReplayMode = 'paused' | 'playing';
|
|
22
|
+
export type ReplayPacing = 'bar' | 'wallclock' | 'tick';
|
|
23
|
+
export interface ReplayState {
|
|
24
|
+
/** Position in the full data series; fractional values are allowed and
|
|
25
|
+
* represent sub-bar progress for wall-clock / tick pacing. Callers that
|
|
26
|
+
* need an integer bar index should `Math.floor(position)`. */
|
|
27
|
+
position: number;
|
|
28
|
+
/** Inclusive lower bound of the playhead (clamp floor). */
|
|
29
|
+
start: number;
|
|
30
|
+
/** Inclusive upper bound of the playhead (clamp ceiling). Typically
|
|
31
|
+
* `totalBars - 1`. */
|
|
32
|
+
end: number;
|
|
33
|
+
mode: ReplayMode;
|
|
34
|
+
pacing: ReplayPacing;
|
|
35
|
+
/** Pacing-dependent rate:
|
|
36
|
+
* - `wallclock`: multiplier (1.0 = realtime).
|
|
37
|
+
* - `bar`: reserved; ignored by `tick()`.
|
|
38
|
+
* - `tick`: multiplier (1.0 = 1 bar per 100ms). */
|
|
39
|
+
speed: number;
|
|
40
|
+
}
|
|
41
|
+
export interface ReplayControllerInit {
|
|
42
|
+
start?: number;
|
|
43
|
+
end?: number;
|
|
44
|
+
pacing?: ReplayPacing;
|
|
45
|
+
speed?: number;
|
|
46
|
+
/** Bar interval in milliseconds. Used by wall-clock pacing to compute
|
|
47
|
+
* how many bars one wall-second represents. Defaults to 60_000 (1m). */
|
|
48
|
+
barIntervalMs?: number;
|
|
49
|
+
}
|
|
50
|
+
export interface ReplayController {
|
|
51
|
+
/** Reactive view of the entire replay state. Subscribers fire after any
|
|
52
|
+
* mutation that changes the state object (Object.is equality). */
|
|
53
|
+
readonly state: Signal<ReplayState>;
|
|
54
|
+
/** Set the inclusive `[start, end]` range. The current position is
|
|
55
|
+
* re-clamped into the new range. Throws if `end < start`. */
|
|
56
|
+
setRange(start: number, end: number): void;
|
|
57
|
+
/** Seek the playhead to an absolute position; clamped to `[start, end]`. */
|
|
58
|
+
seekTo(position: number): void;
|
|
59
|
+
/** Seek by a relative delta; clamped to `[start, end]`. */
|
|
60
|
+
seekBy(delta: number): void;
|
|
61
|
+
/** Advance exactly one bar (`position += 1`), clamped to `end`. If the
|
|
62
|
+
* step lands on `end`, mode transitions to `paused`. */
|
|
63
|
+
stepForward(): void;
|
|
64
|
+
/** Retreat exactly one bar (`position -= 1`), clamped to `start`. */
|
|
65
|
+
stepBackward(): void;
|
|
66
|
+
/** Begin playback from the current position using the configured
|
|
67
|
+
* pacing/speed. If already at `end`, this is a no-op. */
|
|
68
|
+
play(): void;
|
|
69
|
+
pause(): void;
|
|
70
|
+
/** Toggle between `playing` and `paused`. */
|
|
71
|
+
toggle(): void;
|
|
72
|
+
setPacing(p: ReplayPacing): void;
|
|
73
|
+
/** Set the speed multiplier. Throws on `speed <= 0` (reverse play not
|
|
74
|
+
* supported in v1 — see Open Question in the controller header). */
|
|
75
|
+
setSpeed(s: number): void;
|
|
76
|
+
/** Frame-loop hook. The chart's render loop calls this with the elapsed
|
|
77
|
+
* wall-clock time since the last frame; the controller decides whether
|
|
78
|
+
* to advance `position` based on `mode`, `pacing`, and `speed`.
|
|
79
|
+
*
|
|
80
|
+
* Returns `true` if `position` (and therefore `state`) changed, so the
|
|
81
|
+
* caller can request a re-render. Returns `false` for no-op frames
|
|
82
|
+
* (paused, bar-pacing, or sub-bar accumulation that didn't cross a
|
|
83
|
+
* whole-bar boundary — though in this v1 we keep `tick()` stateless and
|
|
84
|
+
* always commit the fractional advance, so any non-zero advance returns
|
|
85
|
+
* `true`). */
|
|
86
|
+
tick(deltaMs: number): boolean;
|
|
87
|
+
/** Tear down. After `dispose()`, all mutators become silent no-ops and
|
|
88
|
+
* the `state` signal stops emitting. */
|
|
89
|
+
dispose(): void;
|
|
90
|
+
}
|
|
91
|
+
/** Factory shape — matches the exported function. Re-stated here so callers
|
|
92
|
+
* importing only the types file can type-check controller construction. */
|
|
93
|
+
export type CreateReplayController = (init?: ReplayControllerInit) => ReplayController;
|
|
94
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/replay/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAA;AAElD,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,SAAS,CAAA;AAC7C,MAAM,MAAM,YAAY,GAAG,KAAK,GAAG,WAAW,GAAG,MAAM,CAAA;AAEvD,MAAM,WAAW,WAAW;IACxB;;mEAE+D;IAC/D,QAAQ,EAAE,MAAM,CAAA;IAChB,2DAA2D;IAC3D,KAAK,EAAE,MAAM,CAAA;IACb;2BACuB;IACvB,GAAG,EAAE,MAAM,CAAA;IACX,IAAI,EAAE,UAAU,CAAA;IAChB,MAAM,EAAE,YAAY,CAAA;IACpB;;;6DAGyD;IACzD,KAAK,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,oBAAoB;IACjC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,MAAM,CAAC,EAAE,YAAY,CAAA;IACrB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd;6EACyE;IACzE,aAAa,CAAC,EAAE,MAAM,CAAA;CACzB;AAED,MAAM,WAAW,gBAAgB;IAC7B;uEACmE;IACnE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,WAAW,CAAC,CAAA;IAEnC;kEAC8D;IAC9D,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;IAE1C,4EAA4E;IAC5E,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;IAC9B,2DAA2D;IAC3D,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B;6DACyD;IACzD,WAAW,IAAI,IAAI,CAAA;IACnB,qEAAqE;IACrE,YAAY,IAAI,IAAI,CAAA;IAEpB;8DAC0D;IAC1D,IAAI,IAAI,IAAI,CAAA;IACZ,KAAK,IAAI,IAAI,CAAA;IACb,6CAA6C;IAC7C,MAAM,IAAI,IAAI,CAAA;IAEd,SAAS,CAAC,CAAC,EAAE,YAAY,GAAG,IAAI,CAAA;IAChC;yEACqE;IACrE,QAAQ,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAEzB;;;;;;;;;mBASe;IACf,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAA;IAE9B;6CACyC;IACzC,OAAO,IAAI,IAAI,CAAA;CAClB;AAED;4EAC4E;AAC5E,MAAM,MAAM,sBAAsB,GAAG,CACjC,IAAI,CAAC,EAAE,oBAAoB,KAC1B,gBAAgB,CAAA"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bar Replay — public types.
|
|
3
|
+
*
|
|
4
|
+
* The replay subsystem models a playhead that scrubs through a finite bar
|
|
5
|
+
* series. Three pacing strategies are supported:
|
|
6
|
+
*
|
|
7
|
+
* - `bar` step-by-bar; `tick()` is a no-op, callers drive position
|
|
8
|
+
* via `stepForward` / `stepBackward` (keyboard-driven).
|
|
9
|
+
* - `wallclock` real-time playback; `tick(deltaMs)` advances by
|
|
10
|
+
* `(deltaMs / msPerBar) * speed` bars. `speed` is a
|
|
11
|
+
* multiplier (1 = realtime, 10 = 10x).
|
|
12
|
+
* - `tick` synthetic tick replay; `tick(deltaMs)` advances by
|
|
13
|
+
* `(deltaMs / 100) * speed` bars (100ms per nominal step).
|
|
14
|
+
*
|
|
15
|
+
* Why this matters: TradingView's Bar Replay is wall-clock only and hides its
|
|
16
|
+
* state. Ours is observable via the `state` signal — any backtest engine,
|
|
17
|
+
* recording session, or sibling controller can subscribe and react to
|
|
18
|
+
* playhead changes deterministically.
|
|
19
|
+
*/
|
|
20
|
+
export {};
|
|
21
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/replay/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Anchored zoom — ROADMAP §1.3.
|
|
3
|
+
*
|
|
4
|
+
* Why this exists in its own file: the "data point under the mouse stays under
|
|
5
|
+
* the mouse" guarantee is the single most-felt detail of chart UX. Getting it
|
|
6
|
+
* mathematically right (so the screen-pixel offset survives sequential zooms
|
|
7
|
+
* within sub-pixel error) is the only path to a feel that matches TradingView.
|
|
8
|
+
*
|
|
9
|
+
* Forward equation, before zoom:
|
|
10
|
+
*
|
|
11
|
+
* mouseX = (i_anchor - firstVisibleIndex) * barWidth + leftPadding
|
|
12
|
+
*
|
|
13
|
+
* Solve for `i_anchor` first (this is the bar index the user is pointing at):
|
|
14
|
+
*
|
|
15
|
+
* i_anchor = (mouseX - leftPadding) / barWidth + firstVisibleIndex
|
|
16
|
+
*
|
|
17
|
+
* Then pick the new bar width and solve the same equation for the new first
|
|
18
|
+
* visible index so that `mouseX` still maps to `i_anchor`:
|
|
19
|
+
*
|
|
20
|
+
* barWidth' = clamp(barWidth * zoomFactor, minBarWidth, maxBarWidth)
|
|
21
|
+
* firstVisibleIndex' = i_anchor - (mouseX - leftPadding) / barWidth'
|
|
22
|
+
*
|
|
23
|
+
* Two non-obvious cases worth flagging:
|
|
24
|
+
*
|
|
25
|
+
* 1. **zoomFactor === 1** is a true no-op; we short-circuit so floating-point
|
|
26
|
+
* round-trips don't sneak a sub-ULP drift into the state on every mouse-move.
|
|
27
|
+
*
|
|
28
|
+
* 2. **barWidth' got clamped** (user keeps wheeling at the min/max). Once the
|
|
29
|
+
* clamp engages we re-derive `firstVisibleIndex` from the clamped width.
|
|
30
|
+
* The anchor is preserved at the clamped width, which means the visible
|
|
31
|
+
* anchor point will *drift in screen X by the same amount the wheel tried
|
|
32
|
+
* to push the bar width past the clamp*. This is the expected behavior —
|
|
33
|
+
* it's how the user feels "the chart can't zoom any further" rather than
|
|
34
|
+
* watching the wheel become a silent dead-zone.
|
|
35
|
+
*/
|
|
36
|
+
export interface AnchoredZoomOptions {
|
|
37
|
+
/** Screen X (logical px) where the wheel event fired. */
|
|
38
|
+
mouseX: number;
|
|
39
|
+
/** Logical px on the left edge before bar 0. */
|
|
40
|
+
leftPadding: number;
|
|
41
|
+
/** Current `firstVisibleIndex` (fractional). */
|
|
42
|
+
firstVisibleIndex: number;
|
|
43
|
+
/** Current `barWidth` in logical px. */
|
|
44
|
+
barWidth: number;
|
|
45
|
+
/** > 1 zoom in (wheel up), < 1 zoom out, === 1 no-op. */
|
|
46
|
+
zoomFactor: number;
|
|
47
|
+
/** Lower clamp for the resulting bar width. Default 0.5 logical px. */
|
|
48
|
+
minBarWidth?: number;
|
|
49
|
+
/** Upper clamp for the resulting bar width. Default 200 logical px. */
|
|
50
|
+
maxBarWidth?: number;
|
|
51
|
+
}
|
|
52
|
+
export interface AnchoredZoomResult {
|
|
53
|
+
firstVisibleIndex: number;
|
|
54
|
+
barWidth: number;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* @internal — building block used by `createTimeScale / interaction handlers`. Reachable today
|
|
58
|
+
* via the top-level `@klinechart-quant/core` barrel but **NOT
|
|
59
|
+
* part of the supported public API**. typedoc / api-extractor
|
|
60
|
+
* hide it from generated docs. Prefer the controller factory
|
|
61
|
+
* for stable user code. Closes API audit BLOCKER-002.
|
|
62
|
+
*/
|
|
63
|
+
export declare function computeAnchoredZoom(opts: AnchoredZoomOptions): AnchoredZoomResult;
|
|
64
|
+
//# sourceMappingURL=anchoredZoom.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"anchoredZoom.d.ts","sourceRoot":"","sources":["../../src/scale/anchoredZoom.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAEH,MAAM,WAAW,mBAAmB;IAChC,yDAAyD;IACzD,MAAM,EAAE,MAAM,CAAA;IACd,gDAAgD;IAChD,WAAW,EAAE,MAAM,CAAA;IACnB,gDAAgD;IAChD,iBAAiB,EAAE,MAAM,CAAA;IACzB,wCAAwC;IACxC,QAAQ,EAAE,MAAM,CAAA;IAChB,yDAAyD;IACzD,UAAU,EAAE,MAAM,CAAA;IAClB,uEAAuE;IACvE,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,uEAAuE;IACvE,WAAW,CAAC,EAAE,MAAM,CAAA;CACvB;AAED,MAAM,WAAW,kBAAkB;IAC/B,iBAAiB,EAAE,MAAM,CAAA;IACzB,QAAQ,EAAE,MAAM,CAAA;CACnB;AAKD;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,mBAAmB,GAAG,kBAAkB,CAmCjF"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Anchored zoom — ROADMAP §1.3.
|
|
3
|
+
*
|
|
4
|
+
* Why this exists in its own file: the "data point under the mouse stays under
|
|
5
|
+
* the mouse" guarantee is the single most-felt detail of chart UX. Getting it
|
|
6
|
+
* mathematically right (so the screen-pixel offset survives sequential zooms
|
|
7
|
+
* within sub-pixel error) is the only path to a feel that matches TradingView.
|
|
8
|
+
*
|
|
9
|
+
* Forward equation, before zoom:
|
|
10
|
+
*
|
|
11
|
+
* mouseX = (i_anchor - firstVisibleIndex) * barWidth + leftPadding
|
|
12
|
+
*
|
|
13
|
+
* Solve for `i_anchor` first (this is the bar index the user is pointing at):
|
|
14
|
+
*
|
|
15
|
+
* i_anchor = (mouseX - leftPadding) / barWidth + firstVisibleIndex
|
|
16
|
+
*
|
|
17
|
+
* Then pick the new bar width and solve the same equation for the new first
|
|
18
|
+
* visible index so that `mouseX` still maps to `i_anchor`:
|
|
19
|
+
*
|
|
20
|
+
* barWidth' = clamp(barWidth * zoomFactor, minBarWidth, maxBarWidth)
|
|
21
|
+
* firstVisibleIndex' = i_anchor - (mouseX - leftPadding) / barWidth'
|
|
22
|
+
*
|
|
23
|
+
* Two non-obvious cases worth flagging:
|
|
24
|
+
*
|
|
25
|
+
* 1. **zoomFactor === 1** is a true no-op; we short-circuit so floating-point
|
|
26
|
+
* round-trips don't sneak a sub-ULP drift into the state on every mouse-move.
|
|
27
|
+
*
|
|
28
|
+
* 2. **barWidth' got clamped** (user keeps wheeling at the min/max). Once the
|
|
29
|
+
* clamp engages we re-derive `firstVisibleIndex` from the clamped width.
|
|
30
|
+
* The anchor is preserved at the clamped width, which means the visible
|
|
31
|
+
* anchor point will *drift in screen X by the same amount the wheel tried
|
|
32
|
+
* to push the bar width past the clamp*. This is the expected behavior —
|
|
33
|
+
* it's how the user feels "the chart can't zoom any further" rather than
|
|
34
|
+
* watching the wheel become a silent dead-zone.
|
|
35
|
+
*/
|
|
36
|
+
const DEFAULT_MIN_BAR_WIDTH = 0.5;
|
|
37
|
+
const DEFAULT_MAX_BAR_WIDTH = 200;
|
|
38
|
+
/**
|
|
39
|
+
* @internal — building block used by `createTimeScale / interaction handlers`. Reachable today
|
|
40
|
+
* via the top-level `@klinechart-quant/core` barrel but **NOT
|
|
41
|
+
* part of the supported public API**. typedoc / api-extractor
|
|
42
|
+
* hide it from generated docs. Prefer the controller factory
|
|
43
|
+
* for stable user code. Closes API audit BLOCKER-002.
|
|
44
|
+
*/
|
|
45
|
+
export function computeAnchoredZoom(opts) {
|
|
46
|
+
const { mouseX, leftPadding, firstVisibleIndex, barWidth, zoomFactor, minBarWidth = DEFAULT_MIN_BAR_WIDTH, maxBarWidth = DEFAULT_MAX_BAR_WIDTH, } = opts;
|
|
47
|
+
// No-op short-circuit — avoid round-trip rounding when not zooming.
|
|
48
|
+
if (zoomFactor === 1) {
|
|
49
|
+
return { firstVisibleIndex, barWidth };
|
|
50
|
+
}
|
|
51
|
+
// Defensive: a non-positive or non-finite current barWidth would blow up the
|
|
52
|
+
// inverse formula. The TimeScale itself never lets barWidth reach 0, but we
|
|
53
|
+
// belt-and-brace it here so the function is total.
|
|
54
|
+
if (!Number.isFinite(barWidth) || barWidth <= 0) {
|
|
55
|
+
return { firstVisibleIndex, barWidth };
|
|
56
|
+
}
|
|
57
|
+
const dx = mouseX - leftPadding;
|
|
58
|
+
const iAnchor = dx / barWidth + firstVisibleIndex;
|
|
59
|
+
const rawNewBarWidth = barWidth * zoomFactor;
|
|
60
|
+
const newBarWidth = Math.min(Math.max(rawNewBarWidth, minBarWidth), maxBarWidth);
|
|
61
|
+
const newFirstVisibleIndex = iAnchor - dx / newBarWidth;
|
|
62
|
+
return {
|
|
63
|
+
firstVisibleIndex: newFirstVisibleIndex,
|
|
64
|
+
barWidth: newBarWidth,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=anchoredZoom.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"anchoredZoom.js","sourceRoot":"","sources":["../../src/scale/anchoredZoom.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAwBH,MAAM,qBAAqB,GAAG,GAAG,CAAA;AACjC,MAAM,qBAAqB,GAAG,GAAG,CAAA;AAEjC;;;;;;GAMG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAAyB;IACzD,MAAM,EACF,MAAM,EACN,WAAW,EACX,iBAAiB,EACjB,QAAQ,EACR,UAAU,EACV,WAAW,GAAG,qBAAqB,EACnC,WAAW,GAAG,qBAAqB,GACtC,GAAG,IAAI,CAAA;IAER,oEAAoE;IACpE,IAAI,UAAU,KAAK,CAAC,EAAE,CAAC;QACnB,OAAO,EAAE,iBAAiB,EAAE,QAAQ,EAAE,CAAA;IAC1C,CAAC;IAED,6EAA6E;IAC7E,4EAA4E;IAC5E,mDAAmD;IACnD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,QAAQ,IAAI,CAAC,EAAE,CAAC;QAC9C,OAAO,EAAE,iBAAiB,EAAE,QAAQ,EAAE,CAAA;IAC1C,CAAC;IAED,MAAM,EAAE,GAAG,MAAM,GAAG,WAAW,CAAA;IAC/B,MAAM,OAAO,GAAG,EAAE,GAAG,QAAQ,GAAG,iBAAiB,CAAA;IAEjD,MAAM,cAAc,GAAG,QAAQ,GAAG,UAAU,CAAA;IAC5C,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,cAAc,EAAE,WAAW,CAAC,EAAE,WAAW,CAAC,CAAA;IAEhF,MAAM,oBAAoB,GAAG,OAAO,GAAG,EAAE,GAAG,WAAW,CAAA;IAEvD,OAAO;QACH,iBAAiB,EAAE,oBAAoB;QACvC,QAAQ,EAAE,WAAW;KACxB,CAAA;AACL,CAAC"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PriceScale factory — price ↔ screen Y (ROADMAP §1.2) + origin-shift policy
|
|
3
|
+
* (ROADMAP §2.5).
|
|
4
|
+
*
|
|
5
|
+
* Linear mapping (top-origin, Y grows downward):
|
|
6
|
+
*
|
|
7
|
+
* t = (p - visibleMin) / (visibleMax - visibleMin)
|
|
8
|
+
* y = height - t * height
|
|
9
|
+
* inverse: p = visibleMin + (1 - y / height) * (visibleMax - visibleMin)
|
|
10
|
+
*
|
|
11
|
+
* Log mapping (only valid for strictly positive ranges):
|
|
12
|
+
*
|
|
13
|
+
* t = (ln(p) - ln(visibleMin)) / (ln(visibleMax) - ln(visibleMin))
|
|
14
|
+
* y = height - t * height
|
|
15
|
+
* inverse: p = exp(ln(visibleMin) + (1 - y / height) * (ln(visibleMax) - ln(visibleMin)))
|
|
16
|
+
*
|
|
17
|
+
* Origin-shift policy: lives inside this scale and is consulted on every
|
|
18
|
+
* `setVisibleRange`. It is intentionally in **linear-price space**, applied
|
|
19
|
+
* *before* the log transform — that matches the existing engine and keeps the
|
|
20
|
+
* "shift is just a translation" mental model clean. (Log-space shift is also
|
|
21
|
+
* mathematically valid; it would compose better with sub-cent log-axis zoom on
|
|
22
|
+
* astronomically high prices, but we have no such use case and this keeps
|
|
23
|
+
* parity with the legacy renderer.)
|
|
24
|
+
*
|
|
25
|
+
* Degenerate range handling: when `visibleMin === visibleMax`, `priceToY` and
|
|
26
|
+
* `yToPrice` would divide by zero. We pin the output to `height / 2` (the
|
|
27
|
+
* geometric center) and document that the caller should treat this as
|
|
28
|
+
* "everything at the same price"; this is preferred over throwing because
|
|
29
|
+
* mid-frame `setVisibleRange(p, p)` is reachable from external data feeds and
|
|
30
|
+
* we don't want one bad row to crash the chart.
|
|
31
|
+
*/
|
|
32
|
+
import type { PriceScale, ScaleMode } from './types';
|
|
33
|
+
export interface PriceScaleConfig {
|
|
34
|
+
/** Initial mode. Default `'linear'`. */
|
|
35
|
+
initialMode?: ScaleMode;
|
|
36
|
+
/** Initial visibleMin. Default 0. (Must be > 0 if initialMode === 'log'.) */
|
|
37
|
+
initialVisibleMin?: number;
|
|
38
|
+
/** Initial visibleMax. Default 100. */
|
|
39
|
+
initialVisibleMax?: number;
|
|
40
|
+
/** Initial canvas height in logical px. Default 480. */
|
|
41
|
+
initialHeight?: number;
|
|
42
|
+
/**
|
|
43
|
+
* Threshold for the origin-shift rebaseline policy. Default 0.01 (1% of
|
|
44
|
+
* visible range). See `originShift.ts` for the rationale.
|
|
45
|
+
*/
|
|
46
|
+
originShiftThreshold?: number;
|
|
47
|
+
}
|
|
48
|
+
export declare function createPriceScale(config?: PriceScaleConfig): PriceScale;
|
|
49
|
+
//# sourceMappingURL=createPriceScale.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createPriceScale.d.ts","sourceRoot":"","sources":["../../src/scale/createPriceScale.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAMH,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AAEpD,MAAM,WAAW,gBAAgB;IAC7B,wCAAwC;IACxC,WAAW,CAAC,EAAE,SAAS,CAAA;IACvB,6EAA6E;IAC7E,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,uCAAuC;IACvC,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,wDAAwD;IACxD,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB;;;OAGG;IACH,oBAAoB,CAAC,EAAE,MAAM,CAAA;CAChC;AAED,wBAAgB,gBAAgB,CAAC,MAAM,GAAE,gBAAqB,GAAG,UAAU,CA2K1E"}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PriceScale factory — price ↔ screen Y (ROADMAP §1.2) + origin-shift policy
|
|
3
|
+
* (ROADMAP §2.5).
|
|
4
|
+
*
|
|
5
|
+
* Linear mapping (top-origin, Y grows downward):
|
|
6
|
+
*
|
|
7
|
+
* t = (p - visibleMin) / (visibleMax - visibleMin)
|
|
8
|
+
* y = height - t * height
|
|
9
|
+
* inverse: p = visibleMin + (1 - y / height) * (visibleMax - visibleMin)
|
|
10
|
+
*
|
|
11
|
+
* Log mapping (only valid for strictly positive ranges):
|
|
12
|
+
*
|
|
13
|
+
* t = (ln(p) - ln(visibleMin)) / (ln(visibleMax) - ln(visibleMin))
|
|
14
|
+
* y = height - t * height
|
|
15
|
+
* inverse: p = exp(ln(visibleMin) + (1 - y / height) * (ln(visibleMax) - ln(visibleMin)))
|
|
16
|
+
*
|
|
17
|
+
* Origin-shift policy: lives inside this scale and is consulted on every
|
|
18
|
+
* `setVisibleRange`. It is intentionally in **linear-price space**, applied
|
|
19
|
+
* *before* the log transform — that matches the existing engine and keeps the
|
|
20
|
+
* "shift is just a translation" mental model clean. (Log-space shift is also
|
|
21
|
+
* mathematically valid; it would compose better with sub-cent log-axis zoom on
|
|
22
|
+
* astronomically high prices, but we have no such use case and this keeps
|
|
23
|
+
* parity with the legacy renderer.)
|
|
24
|
+
*
|
|
25
|
+
* Degenerate range handling: when `visibleMin === visibleMax`, `priceToY` and
|
|
26
|
+
* `yToPrice` would divide by zero. We pin the output to `height / 2` (the
|
|
27
|
+
* geometric center) and document that the caller should treat this as
|
|
28
|
+
* "everything at the same price"; this is preferred over throwing because
|
|
29
|
+
* mid-frame `setVisibleRange(p, p)` is reachable from external data feeds and
|
|
30
|
+
* we don't want one bad row to crash the chart.
|
|
31
|
+
*/
|
|
32
|
+
import { createSignal } from '../reactivity/signal';
|
|
33
|
+
import { KLineChartError } from '../errors';
|
|
34
|
+
import { createOriginShiftPolicy } from './originShift';
|
|
35
|
+
export function createPriceScale(config = {}) {
|
|
36
|
+
const initialMode = config.initialMode ?? 'linear';
|
|
37
|
+
const initialVisibleMin = config.initialVisibleMin ?? 0;
|
|
38
|
+
const initialVisibleMax = config.initialVisibleMax ?? 100;
|
|
39
|
+
const initialHeight = config.initialHeight ?? 480;
|
|
40
|
+
if (!(initialVisibleMax >= initialVisibleMin)) {
|
|
41
|
+
throw new KLineChartError('SCALE_RANGE_INVALID', `createPriceScale: initialVisibleMax (${initialVisibleMax}) must be >= initialVisibleMin (${initialVisibleMin})`);
|
|
42
|
+
}
|
|
43
|
+
if (initialMode === 'log' && !(initialVisibleMin > 0)) {
|
|
44
|
+
throw new KLineChartError('SCALE_LOG_REQUIRES_POSITIVE', `createPriceScale: log mode requires visibleMin > 0, got ${initialVisibleMin}`);
|
|
45
|
+
}
|
|
46
|
+
if (!(initialHeight > 0)) {
|
|
47
|
+
throw new KLineChartError('SCALE_HEIGHT_INVALID', `createPriceScale: initialHeight must be > 0, got ${initialHeight}`);
|
|
48
|
+
}
|
|
49
|
+
const mode = createSignal(initialMode);
|
|
50
|
+
const visibleMin = createSignal(initialVisibleMin);
|
|
51
|
+
const visibleMax = createSignal(initialVisibleMax);
|
|
52
|
+
const height = createSignal(initialHeight);
|
|
53
|
+
const initialRef = (initialVisibleMin + initialVisibleMax) / 2;
|
|
54
|
+
const policy = createOriginShiftPolicy(initialRef, config.originShiftThreshold);
|
|
55
|
+
const originShiftRef = createSignal(policy.ref);
|
|
56
|
+
let disposed = false;
|
|
57
|
+
/**
|
|
58
|
+
* Post-dispose: mutator calls become silent no-ops. See createTimeScale.ts
|
|
59
|
+
* for the rationale + API audit BLOCKER-004 reference. Returns `true` when
|
|
60
|
+
* the operation should proceed.
|
|
61
|
+
*/
|
|
62
|
+
const guard = () => !disposed;
|
|
63
|
+
/**
|
|
64
|
+
* Run `policy.maybeRebaseline` with the latest visible range and, if it
|
|
65
|
+
* rebased, mirror the new value into the reactive `originShiftRef` signal
|
|
66
|
+
* so subscribers (uniform updaters, GPU buffer uploaders) can pick it up.
|
|
67
|
+
*/
|
|
68
|
+
const syncOriginShift = () => {
|
|
69
|
+
const min = visibleMin.peek();
|
|
70
|
+
const max = visibleMax.peek();
|
|
71
|
+
const range = max - min;
|
|
72
|
+
const mid = (min + max) / 2;
|
|
73
|
+
if (policy.maybeRebaseline(mid, range)) {
|
|
74
|
+
originShiftRef.set(policy.ref);
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
const priceToYLinear = (p) => {
|
|
78
|
+
const min = visibleMin.peek();
|
|
79
|
+
const max = visibleMax.peek();
|
|
80
|
+
const h = height.peek();
|
|
81
|
+
const span = max - min;
|
|
82
|
+
if (span <= 0)
|
|
83
|
+
return h / 2;
|
|
84
|
+
const t = (p - min) / span;
|
|
85
|
+
return h - t * h;
|
|
86
|
+
};
|
|
87
|
+
const priceToYLog = (p) => {
|
|
88
|
+
const min = visibleMin.peek();
|
|
89
|
+
const max = visibleMax.peek();
|
|
90
|
+
const h = height.peek();
|
|
91
|
+
// Defensive — setMode('log') already rejects bad ranges, but we keep
|
|
92
|
+
// priceToY total so a stray p<=0 doesn't NaN out the whole chart.
|
|
93
|
+
if (p <= 0 || min <= 0 || max <= 0 || max <= min)
|
|
94
|
+
return h / 2;
|
|
95
|
+
const t = (Math.log(p) - Math.log(min)) / (Math.log(max) - Math.log(min));
|
|
96
|
+
return h - t * h;
|
|
97
|
+
};
|
|
98
|
+
const yToPriceLinear = (y) => {
|
|
99
|
+
const min = visibleMin.peek();
|
|
100
|
+
const max = visibleMax.peek();
|
|
101
|
+
const h = height.peek();
|
|
102
|
+
const span = max - min;
|
|
103
|
+
if (span <= 0)
|
|
104
|
+
return min;
|
|
105
|
+
return min + (1 - y / h) * span;
|
|
106
|
+
};
|
|
107
|
+
const yToPriceLog = (y) => {
|
|
108
|
+
const min = visibleMin.peek();
|
|
109
|
+
const max = visibleMax.peek();
|
|
110
|
+
const h = height.peek();
|
|
111
|
+
if (min <= 0 || max <= 0 || max <= min)
|
|
112
|
+
return min;
|
|
113
|
+
const lmin = Math.log(min);
|
|
114
|
+
const lmax = Math.log(max);
|
|
115
|
+
const ly = lmin + (1 - y / h) * (lmax - lmin);
|
|
116
|
+
return Math.exp(ly);
|
|
117
|
+
};
|
|
118
|
+
const scale = {
|
|
119
|
+
mode,
|
|
120
|
+
visibleMin,
|
|
121
|
+
visibleMax,
|
|
122
|
+
height,
|
|
123
|
+
originShiftRef: originShiftRef,
|
|
124
|
+
priceToY(p) {
|
|
125
|
+
return mode.peek() === 'log' ? priceToYLog(p) : priceToYLinear(p);
|
|
126
|
+
},
|
|
127
|
+
yToPrice(y) {
|
|
128
|
+
return mode.peek() === 'log' ? yToPriceLog(y) : yToPriceLinear(y);
|
|
129
|
+
},
|
|
130
|
+
setMode(next) {
|
|
131
|
+
if (!guard())
|
|
132
|
+
return;
|
|
133
|
+
if (next === 'log') {
|
|
134
|
+
const min = visibleMin.peek();
|
|
135
|
+
const max = visibleMax.peek();
|
|
136
|
+
if (!(min > 0) || !(max > 0)) {
|
|
137
|
+
throw new KLineChartError('SCALE_LOG_REQUIRES_POSITIVE', `PriceScale.setMode('log'): requires visibleMin > 0 and visibleMax > 0, got min=${min}, max=${max}`);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
mode.set(next);
|
|
141
|
+
},
|
|
142
|
+
setVisibleRange(min, max) {
|
|
143
|
+
if (!guard())
|
|
144
|
+
return;
|
|
145
|
+
if (!Number.isFinite(min) || !Number.isFinite(max)) {
|
|
146
|
+
throw new KLineChartError('SCALE_RANGE_INVALID', `PriceScale.setVisibleRange: both bounds must be finite, got min=${min}, max=${max}`);
|
|
147
|
+
}
|
|
148
|
+
if (max < min) {
|
|
149
|
+
throw new KLineChartError('SCALE_RANGE_INVALID', `PriceScale.setVisibleRange: max (${max}) must be >= min (${min})`);
|
|
150
|
+
}
|
|
151
|
+
if (mode.peek() === 'log' && !(min > 0)) {
|
|
152
|
+
throw new KLineChartError('SCALE_LOG_REQUIRES_POSITIVE', `PriceScale.setVisibleRange: log mode requires min > 0, got ${min}`);
|
|
153
|
+
}
|
|
154
|
+
visibleMin.set(min);
|
|
155
|
+
visibleMax.set(max);
|
|
156
|
+
syncOriginShift();
|
|
157
|
+
},
|
|
158
|
+
setHeight(h) {
|
|
159
|
+
if (!guard())
|
|
160
|
+
return;
|
|
161
|
+
if (!(h > 0)) {
|
|
162
|
+
throw new KLineChartError('SCALE_HEIGHT_INVALID', `PriceScale.setHeight: height must be > 0, got ${h}`);
|
|
163
|
+
}
|
|
164
|
+
height.set(h);
|
|
165
|
+
},
|
|
166
|
+
toShiftedFp32(p) {
|
|
167
|
+
return policy.shift(p);
|
|
168
|
+
},
|
|
169
|
+
dispose() {
|
|
170
|
+
disposed = true;
|
|
171
|
+
},
|
|
172
|
+
};
|
|
173
|
+
return scale;
|
|
174
|
+
}
|
|
175
|
+
//# sourceMappingURL=createPriceScale.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createPriceScale.js","sourceRoot":"","sources":["../../src/scale/createPriceScale.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TimeScale factory — discrete bar-index ↔ screen X mapping (ROADMAP §1.1).
|
|
3
|
+
*
|
|
4
|
+
* The math is one-line in each direction; the value of this factory is the
|
|
5
|
+
* reactive plumbing (signals so adapters can subscribe) and the optional
|
|
6
|
+
* wall-clock calendar that maps bar indices ↔ timestamps.
|
|
7
|
+
*
|
|
8
|
+
* forward: x(i) = (i - firstVisibleIndex) * barWidth + leftPadding
|
|
9
|
+
* inverse: i(x) = (x - leftPadding) / barWidth + firstVisibleIndex
|
|
10
|
+
*
|
|
11
|
+
* Calendar semantics: when the user attaches a `barTimestamps` array, we treat
|
|
12
|
+
* bar index `i` as the array index. Integer indices map directly; fractional
|
|
13
|
+
* indices linearly interpolate between neighboring timestamps. Anything
|
|
14
|
+
* outside `[0, N-1]` returns `null` — the caller decides whether to clamp,
|
|
15
|
+
* extrapolate, or display a "—" label.
|
|
16
|
+
*/
|
|
17
|
+
import type { TimeScale } from './types';
|
|
18
|
+
export interface TimeScaleConfig {
|
|
19
|
+
/** Default firstVisibleIndex. Fractional/negative allowed. Default 0. */
|
|
20
|
+
initialFirstVisibleIndex?: number;
|
|
21
|
+
/** Default barWidth in logical px. Must be > 0. Default 8. */
|
|
22
|
+
initialBarWidth?: number;
|
|
23
|
+
/** Default leftPadding in logical px. Default 0. */
|
|
24
|
+
initialLeftPadding?: number;
|
|
25
|
+
}
|
|
26
|
+
export declare function createTimeScale(config?: TimeScaleConfig): TimeScale;
|
|
27
|
+
//# sourceMappingURL=createTimeScale.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createTimeScale.d.ts","sourceRoot":"","sources":["../../src/scale/createTimeScale.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAIH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AAExC,MAAM,WAAW,eAAe;IAC5B,yEAAyE;IACzE,wBAAwB,CAAC,EAAE,MAAM,CAAA;IACjC,8DAA8D;IAC9D,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,oDAAoD;IACpD,kBAAkB,CAAC,EAAE,MAAM,CAAA;CAC9B;AAED,wBAAgB,eAAe,CAAC,MAAM,GAAE,eAAoB,GAAG,SAAS,CAuHvE"}
|