@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,338 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FootprintController — framework-agnostic, signal-based.
|
|
3
|
+
*
|
|
4
|
+
* Streams trades in, materialises a `FootprintBar[]` out. Composes:
|
|
5
|
+
*
|
|
6
|
+
* - `classifyExplicit` (try exchange flag first)
|
|
7
|
+
* - `classifyTickRule` / `classifyLeeReady` (fallback per config)
|
|
8
|
+
* - `computeDelta`, `computeDiagonalImbalances`, `computeCumulativeDelta`
|
|
9
|
+
*
|
|
10
|
+
* Internal storage is hot-path-friendly:
|
|
11
|
+
*
|
|
12
|
+
* buckets: Map<barIndex, Map<priceTickKey, { askVol, bidVol }>>
|
|
13
|
+
*
|
|
14
|
+
* Materialisation (sorting + array build) is deferred to `bars` / `cumulativeDelta`
|
|
15
|
+
* signal reads. A `dirty` flag invalidates the cache on every `ingestTrade`.
|
|
16
|
+
*
|
|
17
|
+
* Classifier state carry-over: the `TickRuleState` / `LeeReadyState` records
|
|
18
|
+
* are MAINTAINED ACROSS BAR BOUNDARIES — i.e. the last trade's price/side of
|
|
19
|
+
* bar N is used as the prior for the first trade of bar N+1. This is the
|
|
20
|
+
* documented choice (see ROADMAP §3.3): per-bar reset would flag every bar's
|
|
21
|
+
* first trade as `unknown`, which inflates dropped volume and breaks the
|
|
22
|
+
* Lee-Ready zero-tick fallback at every minute boundary. The tested behaviour
|
|
23
|
+
* relies on this carry-over.
|
|
24
|
+
*
|
|
25
|
+
* Dispose-guard pattern mirrors `createIndicatorSelectorController.ts`.
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
import { createSignal, type Signal } from '../../reactivity'
|
|
29
|
+
import { KLineChartError } from '../../errors'
|
|
30
|
+
import {
|
|
31
|
+
classifyExplicit,
|
|
32
|
+
classifyLeeReady,
|
|
33
|
+
classifyTickRule,
|
|
34
|
+
type AggressorResult,
|
|
35
|
+
type LeeReadyState,
|
|
36
|
+
type TickRuleState,
|
|
37
|
+
} from './aggressor'
|
|
38
|
+
import {
|
|
39
|
+
computeCumulativeDelta,
|
|
40
|
+
computeDelta,
|
|
41
|
+
computeDiagonalImbalances,
|
|
42
|
+
} from './perBarStats'
|
|
43
|
+
import type {
|
|
44
|
+
FootprintBar,
|
|
45
|
+
FootprintBarCell,
|
|
46
|
+
FootprintConfig,
|
|
47
|
+
FootprintController,
|
|
48
|
+
FootprintImbalance,
|
|
49
|
+
TradeWithFlag,
|
|
50
|
+
} from './types'
|
|
51
|
+
|
|
52
|
+
// ---------------------------------------------------------------------------
|
|
53
|
+
// Defaults & validation
|
|
54
|
+
// ---------------------------------------------------------------------------
|
|
55
|
+
|
|
56
|
+
const DEFAULT_CONFIG: FootprintConfig = {
|
|
57
|
+
tickSize: 0.01,
|
|
58
|
+
barIntervalMs: 60_000,
|
|
59
|
+
imbalanceRatio: 3,
|
|
60
|
+
fallbackClassifier: 'tick-rule',
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function validateConfig(c: FootprintConfig): void {
|
|
64
|
+
if (!(c.tickSize > 0)) {
|
|
65
|
+
throw new KLineChartError('FOOTPRINT_TICKSIZE_INVALID', 'FootprintController: tickSize must be > 0')
|
|
66
|
+
}
|
|
67
|
+
if (!(c.barIntervalMs > 0) || !Number.isFinite(c.barIntervalMs)) {
|
|
68
|
+
throw new KLineChartError('FOOTPRINT_BAR_INTERVAL_INVALID', 'FootprintController: barIntervalMs must be > 0')
|
|
69
|
+
}
|
|
70
|
+
if (!(c.imbalanceRatio > 0)) {
|
|
71
|
+
throw new KLineChartError('FOOTPRINT_RATIO_INVALID', 'FootprintController: imbalanceRatio must be > 0')
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// ---------------------------------------------------------------------------
|
|
76
|
+
// Internal cell shape (mutable counterpart of the readonly public cell)
|
|
77
|
+
// ---------------------------------------------------------------------------
|
|
78
|
+
|
|
79
|
+
interface MutableCell {
|
|
80
|
+
askVol: number
|
|
81
|
+
bidVol: number
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// ---------------------------------------------------------------------------
|
|
85
|
+
// Factory
|
|
86
|
+
// ---------------------------------------------------------------------------
|
|
87
|
+
|
|
88
|
+
export function createFootprintController(
|
|
89
|
+
init: Partial<FootprintConfig>,
|
|
90
|
+
): FootprintController {
|
|
91
|
+
const initialConfig: FootprintConfig = { ...DEFAULT_CONFIG, ...init }
|
|
92
|
+
validateConfig(initialConfig)
|
|
93
|
+
|
|
94
|
+
const config: Signal<FootprintConfig> = createSignal(initialConfig)
|
|
95
|
+
const bars: Signal<ReadonlyArray<FootprintBar>> = createSignal<
|
|
96
|
+
ReadonlyArray<FootprintBar>
|
|
97
|
+
>([])
|
|
98
|
+
const cumulativeDelta: Signal<ReadonlyArray<number>> = createSignal<
|
|
99
|
+
ReadonlyArray<number>
|
|
100
|
+
>([])
|
|
101
|
+
|
|
102
|
+
// ---- Internal state ------------------------------------------------
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* barIndex → (priceTickKey → mutable cell).
|
|
106
|
+
*
|
|
107
|
+
* We use Maps so insertion order is preserved per-bar (for debug-time
|
|
108
|
+
* inspection); the public materialisation sorts deterministically.
|
|
109
|
+
*/
|
|
110
|
+
let buckets: Map<number, Map<number, MutableCell>> = new Map()
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Classifier carry-over. One record shared by tick rule and Lee-Ready —
|
|
114
|
+
* they have the same field surface. NEVER reset on bar boundary
|
|
115
|
+
* (see header comment).
|
|
116
|
+
*/
|
|
117
|
+
const tickState: TickRuleState & LeeReadyState = {
|
|
118
|
+
prevPrice: null,
|
|
119
|
+
prevSide: null,
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/** Set to true on every successful `ingestTrade`; cleared on materialise. */
|
|
123
|
+
let dirty = false
|
|
124
|
+
/** Disposal guard. */
|
|
125
|
+
let disposed = false
|
|
126
|
+
|
|
127
|
+
// ---- Helpers -------------------------------------------------------
|
|
128
|
+
|
|
129
|
+
function classify(
|
|
130
|
+
trade: TradeWithFlag,
|
|
131
|
+
bid: number | undefined,
|
|
132
|
+
ask: number | undefined,
|
|
133
|
+
): AggressorResult {
|
|
134
|
+
// 1. Try the explicit exchange flag first (zero error).
|
|
135
|
+
const explicit = classifyExplicit(trade)
|
|
136
|
+
if (explicit !== null) {
|
|
137
|
+
// Even when we don't consume the heuristic, advance the
|
|
138
|
+
// carry-over so a later fallback-classified trade still has a
|
|
139
|
+
// useful prevPrice/prevSide. We commit prevSide only for known
|
|
140
|
+
// explicit sides.
|
|
141
|
+
tickState.prevPrice = trade.price
|
|
142
|
+
tickState.prevSide = explicit.side === 'unknown' ? null : explicit.side
|
|
143
|
+
return explicit
|
|
144
|
+
}
|
|
145
|
+
// 2. Fall back to the configured heuristic.
|
|
146
|
+
const mode = config.peek().fallbackClassifier
|
|
147
|
+
if (mode === 'lee-ready') {
|
|
148
|
+
// If quotes are missing, classifyLeeReady will degrade to the
|
|
149
|
+
// tick rule itself — same state record.
|
|
150
|
+
const b = bid ?? Number.NaN
|
|
151
|
+
const a = ask ?? Number.NaN
|
|
152
|
+
return classifyLeeReady(tickState, trade, b, a)
|
|
153
|
+
}
|
|
154
|
+
return classifyTickRule(tickState, trade)
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
function bucketFor(barIndex: number): Map<number, MutableCell> {
|
|
158
|
+
let bar = buckets.get(barIndex)
|
|
159
|
+
if (bar === undefined) {
|
|
160
|
+
bar = new Map()
|
|
161
|
+
buckets.set(barIndex, bar)
|
|
162
|
+
}
|
|
163
|
+
return bar
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
function cellFor(
|
|
167
|
+
bar: Map<number, MutableCell>,
|
|
168
|
+
priceTickKey: number,
|
|
169
|
+
): MutableCell {
|
|
170
|
+
let cell = bar.get(priceTickKey)
|
|
171
|
+
if (cell === undefined) {
|
|
172
|
+
cell = { askVol: 0, bidVol: 0 }
|
|
173
|
+
bar.set(priceTickKey, cell)
|
|
174
|
+
}
|
|
175
|
+
return cell
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Build the materialised view from `buckets`. Sorts bars ascending by
|
|
180
|
+
* barIndex; within each bar, sorts cells ascending by price.
|
|
181
|
+
*/
|
|
182
|
+
function materialise(): {
|
|
183
|
+
bars: FootprintBar[]
|
|
184
|
+
cumulative: number[]
|
|
185
|
+
} {
|
|
186
|
+
const cfg = config.peek()
|
|
187
|
+
const sortedBarIndices = [...buckets.keys()].sort((a, b) => a - b)
|
|
188
|
+
|
|
189
|
+
const outBars: FootprintBar[] = []
|
|
190
|
+
const perBarDeltas: number[] = []
|
|
191
|
+
|
|
192
|
+
for (const barIndex of sortedBarIndices) {
|
|
193
|
+
const internal = buckets.get(barIndex)
|
|
194
|
+
if (internal === undefined) continue
|
|
195
|
+
|
|
196
|
+
const sortedKeys = [...internal.keys()].sort((a, b) => a - b)
|
|
197
|
+
const cells: FootprintBarCell[] = sortedKeys.map((k) => {
|
|
198
|
+
const c = internal.get(k) as MutableCell
|
|
199
|
+
return {
|
|
200
|
+
price: k * cfg.tickSize,
|
|
201
|
+
askVol: c.askVol,
|
|
202
|
+
bidVol: c.bidVol,
|
|
203
|
+
}
|
|
204
|
+
})
|
|
205
|
+
|
|
206
|
+
const delta = computeDelta(cells)
|
|
207
|
+
let totalVolume = 0
|
|
208
|
+
for (let i = 0; i < cells.length; i++) {
|
|
209
|
+
const cell = cells[i]
|
|
210
|
+
if (cell === undefined) continue
|
|
211
|
+
totalVolume += cell.askVol + cell.bidVol
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
const imbalances: ReadonlyArray<FootprintImbalance> =
|
|
215
|
+
computeDiagonalImbalances(cells, cfg.imbalanceRatio)
|
|
216
|
+
|
|
217
|
+
const startTime = barIndex * cfg.barIntervalMs
|
|
218
|
+
const endTime = startTime + cfg.barIntervalMs - 1
|
|
219
|
+
|
|
220
|
+
outBars.push({
|
|
221
|
+
barIndex,
|
|
222
|
+
startTime,
|
|
223
|
+
endTime,
|
|
224
|
+
cells,
|
|
225
|
+
delta,
|
|
226
|
+
totalVolume,
|
|
227
|
+
imbalances,
|
|
228
|
+
})
|
|
229
|
+
perBarDeltas.push(delta)
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
return { bars: outBars, cumulative: computeCumulativeDelta(perBarDeltas) }
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
function publishIfDirty(): void {
|
|
236
|
+
if (!dirty) return
|
|
237
|
+
const { bars: nextBars, cumulative } = materialise()
|
|
238
|
+
bars.set(nextBars)
|
|
239
|
+
cumulativeDelta.set(cumulative)
|
|
240
|
+
dirty = false
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// ---- Mutators ------------------------------------------------------
|
|
244
|
+
|
|
245
|
+
function ingestTrade(
|
|
246
|
+
trade: TradeWithFlag,
|
|
247
|
+
bid?: number,
|
|
248
|
+
ask?: number,
|
|
249
|
+
): void {
|
|
250
|
+
if (disposed) return
|
|
251
|
+
// Defensive: reject malformed trades. We do not throw — a single bad
|
|
252
|
+
// print should not poison the live stream.
|
|
253
|
+
if (!Number.isFinite(trade.price) || !Number.isFinite(trade.size)) {
|
|
254
|
+
return
|
|
255
|
+
}
|
|
256
|
+
if (!Number.isFinite(trade.timestamp)) return
|
|
257
|
+
if (trade.size <= 0) return
|
|
258
|
+
|
|
259
|
+
const result = classify(trade, bid, ask)
|
|
260
|
+
if (result.side === 'unknown') {
|
|
261
|
+
// Drop from the aggregate (the documented contract). We've still
|
|
262
|
+
// updated tickState inside `classify` so the next trade has
|
|
263
|
+
// context.
|
|
264
|
+
return
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
const cfg = config.peek()
|
|
268
|
+
const barIndex = Math.floor(trade.timestamp / cfg.barIntervalMs)
|
|
269
|
+
const priceTickKey = Math.round(trade.price / cfg.tickSize)
|
|
270
|
+
|
|
271
|
+
const bar = bucketFor(barIndex)
|
|
272
|
+
const cell = cellFor(bar, priceTickKey)
|
|
273
|
+
if (result.side === 'buy') {
|
|
274
|
+
cell.askVol += trade.size
|
|
275
|
+
} else {
|
|
276
|
+
cell.bidVol += trade.size
|
|
277
|
+
}
|
|
278
|
+
dirty = true
|
|
279
|
+
publishIfDirty()
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
function setConfig(next: Partial<FootprintConfig>): void {
|
|
283
|
+
if (disposed) return
|
|
284
|
+
const cur = config.peek()
|
|
285
|
+
const merged: FootprintConfig = { ...cur, ...next }
|
|
286
|
+
validateConfig(merged)
|
|
287
|
+
|
|
288
|
+
// Changing tickSize or barIntervalMs invalidates the buckets — the
|
|
289
|
+
// priceTickKey and barIndex of every accumulated cell would be wrong
|
|
290
|
+
// under the new partitioning. Clear them and let the caller re-feed
|
|
291
|
+
// history if needed.
|
|
292
|
+
const partitionChanged =
|
|
293
|
+
merged.tickSize !== cur.tickSize ||
|
|
294
|
+
merged.barIntervalMs !== cur.barIntervalMs
|
|
295
|
+
if (partitionChanged) {
|
|
296
|
+
buckets = new Map()
|
|
297
|
+
// We do NOT reset tickState — the next trade's carry-over is
|
|
298
|
+
// still valid because the classifier only depends on price
|
|
299
|
+
// history, not on the bucket partitioning.
|
|
300
|
+
}
|
|
301
|
+
config.set(merged)
|
|
302
|
+
// Re-materialise. If partition changed, bars/cumulative now empty.
|
|
303
|
+
// If only imbalanceRatio changed, we still want to re-flag.
|
|
304
|
+
dirty = true
|
|
305
|
+
publishIfDirty()
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
function reset(): void {
|
|
309
|
+
if (disposed) return
|
|
310
|
+
buckets = new Map()
|
|
311
|
+
tickState.prevPrice = null
|
|
312
|
+
tickState.prevSide = null
|
|
313
|
+
bars.set([])
|
|
314
|
+
cumulativeDelta.set([])
|
|
315
|
+
dirty = false
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
function dispose(): void {
|
|
319
|
+
if (disposed) return
|
|
320
|
+
disposed = true
|
|
321
|
+
// Mutators check `disposed` so no further writes will fire — existing
|
|
322
|
+
// subscribers receive no further notifications.
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
return {
|
|
326
|
+
config,
|
|
327
|
+
bars,
|
|
328
|
+
cumulativeDelta,
|
|
329
|
+
// Canonical verb (API audit BLOCKER-001 harmonisation across
|
|
330
|
+
// VolumeProfile / OrderBookHeatmap / Footprint). Wired to the same
|
|
331
|
+
// implementation as `ingestTrade` so existing consumers keep working.
|
|
332
|
+
ingest: ingestTrade,
|
|
333
|
+
ingestTrade,
|
|
334
|
+
setConfig,
|
|
335
|
+
reset,
|
|
336
|
+
dispose,
|
|
337
|
+
}
|
|
338
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export type {
|
|
2
|
+
AggressorSide,
|
|
3
|
+
Trade,
|
|
4
|
+
TradeWithFlag,
|
|
5
|
+
FootprintBar,
|
|
6
|
+
FootprintConfig,
|
|
7
|
+
FootprintController,
|
|
8
|
+
} from './types'
|
|
9
|
+
export type { AggressorResult, TickRuleState, LeeReadyState } from './aggressor'
|
|
10
|
+
export {
|
|
11
|
+
classifyExplicit,
|
|
12
|
+
classifyTickRule,
|
|
13
|
+
classifyLeeReady,
|
|
14
|
+
} from './aggressor'
|
|
15
|
+
export type { FootprintBarCell, FootprintImbalance } from './perBarStats'
|
|
16
|
+
export {
|
|
17
|
+
computeDelta,
|
|
18
|
+
computeCumulativeDelta,
|
|
19
|
+
computeDiagonalImbalances,
|
|
20
|
+
} from './perBarStats'
|
|
21
|
+
export { createFootprintController } from './createFootprintController'
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-bar derived statistics for the footprint data model.
|
|
3
|
+
*
|
|
4
|
+
* - `computeDelta` — Σ(askVol − bidVol) across a bar's cells
|
|
5
|
+
* - `computeCumulativeDelta` — running sum of per-bar deltas
|
|
6
|
+
* - `computeDiagonalImbalances` — Bookmap/Sierra-style 3× diagonal flags
|
|
7
|
+
*
|
|
8
|
+
* These are the lightweight CPU-side helpers. The compute-shader path
|
|
9
|
+
* (`computeShader.wgsl.md`) parallelises them per-bar in a single dispatch
|
|
10
|
+
* for the heavy historical scan; the values produced here are byte-identical
|
|
11
|
+
* to that GPU path's eventual output.
|
|
12
|
+
*
|
|
13
|
+
* See `docs/ROADMAP.md` §3.3 for the diagonal-imbalance rationale.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import type { FootprintBarCell, FootprintImbalance } from './types'
|
|
17
|
+
|
|
18
|
+
export type { FootprintBarCell, FootprintImbalance }
|
|
19
|
+
|
|
20
|
+
// ---------------------------------------------------------------------------
|
|
21
|
+
// Delta and cumulative delta
|
|
22
|
+
// ---------------------------------------------------------------------------
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Net buy-vs-sell volume for one bar. Positive values are buyer-dominated.
|
|
26
|
+
*
|
|
27
|
+
* Iterates the cells once; the order of cells does not affect the result.
|
|
28
|
+
* An empty cell list yields 0 (the additive identity, sensible for a no-trade
|
|
29
|
+
* bar so it does not break the running cumulative sum downstream).
|
|
30
|
+
*/
|
|
31
|
+
export function computeDelta(cells: ReadonlyArray<FootprintBarCell>): number {
|
|
32
|
+
let sum = 0
|
|
33
|
+
for (let i = 0; i < cells.length; i++) {
|
|
34
|
+
const c = cells[i]
|
|
35
|
+
if (c === undefined) continue
|
|
36
|
+
sum += c.askVol - c.bidVol
|
|
37
|
+
}
|
|
38
|
+
return sum
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Running sum of per-bar deltas. `result[i] = Σ deltas[0..i]`.
|
|
43
|
+
*
|
|
44
|
+
* Empty input yields an empty array. We allocate a fresh array (not a typed
|
|
45
|
+
* array) so consumers can splice/copy cheaply at the controller boundary.
|
|
46
|
+
*/
|
|
47
|
+
export function computeCumulativeDelta(
|
|
48
|
+
perBarDeltas: ReadonlyArray<number>,
|
|
49
|
+
): number[] {
|
|
50
|
+
const out: number[] = new Array(perBarDeltas.length)
|
|
51
|
+
let running = 0
|
|
52
|
+
for (let i = 0; i < perBarDeltas.length; i++) {
|
|
53
|
+
running += perBarDeltas[i] ?? 0
|
|
54
|
+
out[i] = running
|
|
55
|
+
}
|
|
56
|
+
return out
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// ---------------------------------------------------------------------------
|
|
60
|
+
// Diagonal imbalance
|
|
61
|
+
// ---------------------------------------------------------------------------
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Diagonal imbalance detection.
|
|
65
|
+
*
|
|
66
|
+
* Aggressive buyers eat the ASK at a price they cross — the ASK at price
|
|
67
|
+
* p is filled by buyers who were willing to pay p, and conversely, sellers
|
|
68
|
+
* who hit the BID at price p-1 (one tick below) were also "leaning"
|
|
69
|
+
* against that same level. So the right comparison is *diagonal*:
|
|
70
|
+
*
|
|
71
|
+
* buy-imbalance at cell i:
|
|
72
|
+
* cell[i].askVol >= ratio * cell[i-1].bidVol AND cell[i-1].bidVol > 0
|
|
73
|
+
*
|
|
74
|
+
* sell-imbalance at cell i:
|
|
75
|
+
* cell[i].bidVol >= ratio * cell[i+1].askVol AND cell[i+1].askVol > 0
|
|
76
|
+
*
|
|
77
|
+
* Edge handling: a buy-imbalance at i=0 has no `i-1` so it is never reported;
|
|
78
|
+
* a sell-imbalance at the last index has no `i+1` so it is never reported.
|
|
79
|
+
*
|
|
80
|
+
* The `priceIndex` in the result is the index of the *dominant* cell — the
|
|
81
|
+
* one carrying the heavy volume — not its diagonal counterpart.
|
|
82
|
+
*
|
|
83
|
+
* `ratio` is `dominant / weaker`, capped at `Number.POSITIVE_INFINITY` when
|
|
84
|
+
* the weaker side is zero (caller can choose to render that as "∞").
|
|
85
|
+
*
|
|
86
|
+
* Default threshold: 3.0 (Bookmap / Sierra Chart convention). Pass any
|
|
87
|
+
* positive ratio. A ratio of 1.0 would degenerate to "every diagonal pair
|
|
88
|
+
* with non-zero asymmetry is an imbalance" — usually too noisy for display.
|
|
89
|
+
*
|
|
90
|
+
* @param cells bar cells, ascending by price
|
|
91
|
+
* @param ratioThreshold minimum dominant/weaker ratio to flag
|
|
92
|
+
*/
|
|
93
|
+
export function computeDiagonalImbalances(
|
|
94
|
+
cells: ReadonlyArray<FootprintBarCell>,
|
|
95
|
+
ratioThreshold: number,
|
|
96
|
+
): ReadonlyArray<FootprintImbalance> {
|
|
97
|
+
const out: FootprintImbalance[] = []
|
|
98
|
+
const n = cells.length
|
|
99
|
+
if (n === 0) return out
|
|
100
|
+
|
|
101
|
+
for (let i = 0; i < n; i++) {
|
|
102
|
+
const c = cells[i]
|
|
103
|
+
if (c === undefined) continue
|
|
104
|
+
|
|
105
|
+
// Buy imbalance: compare ask at i to bid at i-1 (the diagonal below).
|
|
106
|
+
if (i > 0) {
|
|
107
|
+
const below = cells[i - 1]
|
|
108
|
+
if (below !== undefined && below.bidVol > 0) {
|
|
109
|
+
const ratio = c.askVol / below.bidVol
|
|
110
|
+
if (ratio >= ratioThreshold) {
|
|
111
|
+
out.push({
|
|
112
|
+
priceIndex: i,
|
|
113
|
+
direction: 'buy-imbalance',
|
|
114
|
+
ratio,
|
|
115
|
+
})
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Sell imbalance: compare bid at i to ask at i+1 (the diagonal above).
|
|
121
|
+
if (i < n - 1) {
|
|
122
|
+
const above = cells[i + 1]
|
|
123
|
+
if (above !== undefined && above.askVol > 0) {
|
|
124
|
+
const ratio = c.bidVol / above.askVol
|
|
125
|
+
if (ratio >= ratioThreshold) {
|
|
126
|
+
out.push({
|
|
127
|
+
priceIndex: i,
|
|
128
|
+
direction: 'sell-imbalance',
|
|
129
|
+
ratio,
|
|
130
|
+
})
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return out
|
|
137
|
+
}
|