@363045841yyt/klinechart-core 0.7.3
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/README.md +201 -0
- package/README.zh-CN.md +201 -0
- package/dist/config/chartSettings.d.ts +70 -0
- package/dist/config/chartSettings.d.ts.map +1 -0
- package/dist/config/chartSettings.js +50 -0
- package/dist/config/chartSettings.js.map +1 -0
- package/dist/controllers/createChartController.d.ts +16 -0
- package/dist/controllers/createChartController.d.ts.map +1 -0
- package/dist/controllers/createChartController.js +525 -0
- package/dist/controllers/createChartController.js.map +1 -0
- package/dist/controllers/createDrawingController.d.ts +25 -0
- package/dist/controllers/createDrawingController.d.ts.map +1 -0
- package/dist/controllers/createDrawingController.js +77 -0
- package/dist/controllers/createDrawingController.js.map +1 -0
- package/dist/controllers/createIndicatorSelectorController.d.ts +19 -0
- package/dist/controllers/createIndicatorSelectorController.d.ts.map +1 -0
- package/dist/controllers/createIndicatorSelectorController.js +256 -0
- package/dist/controllers/createIndicatorSelectorController.js.map +1 -0
- package/dist/controllers/createToolbarController.d.ts +28 -0
- package/dist/controllers/createToolbarController.d.ts.map +1 -0
- package/dist/controllers/createToolbarController.js +121 -0
- package/dist/controllers/createToolbarController.js.map +1 -0
- package/dist/controllers/index.d.ts +3 -0
- package/dist/controllers/index.d.ts.map +1 -0
- package/dist/controllers/index.js +2 -0
- package/dist/controllers/index.js.map +1 -0
- package/dist/controllers/types.d.ts +218 -0
- package/dist/controllers/types.d.ts.map +1 -0
- package/dist/controllers/types.js +11 -0
- package/dist/controllers/types.js.map +1 -0
- package/dist/engine/chart-store.d.ts +75 -0
- package/dist/engine/chart-store.d.ts.map +1 -0
- package/dist/engine/chart-store.js +88 -0
- package/dist/engine/chart-store.js.map +1 -0
- package/dist/engine/chart.d.ts +618 -0
- package/dist/engine/chart.d.ts.map +1 -0
- package/dist/engine/chart.js +2285 -0
- package/dist/engine/chart.js.map +1 -0
- package/dist/engine/controller/interaction.d.ts +168 -0
- package/dist/engine/controller/interaction.d.ts.map +1 -0
- package/dist/engine/controller/interaction.js +612 -0
- package/dist/engine/controller/interaction.js.map +1 -0
- package/dist/engine/controller/markerInteraction.d.ts +29 -0
- package/dist/engine/controller/markerInteraction.d.ts.map +1 -0
- package/dist/engine/controller/markerInteraction.js +111 -0
- package/dist/engine/controller/markerInteraction.js.map +1 -0
- package/dist/engine/controller/pinchTracker.d.ts +19 -0
- package/dist/engine/controller/pinchTracker.d.ts.map +1 -0
- package/dist/engine/controller/pinchTracker.js +72 -0
- package/dist/engine/controller/pinchTracker.js.map +1 -0
- package/dist/engine/controller/tooltipPosition.d.ts +22 -0
- package/dist/engine/controller/tooltipPosition.d.ts.map +1 -0
- package/dist/engine/controller/tooltipPosition.js +31 -0
- package/dist/engine/controller/tooltipPosition.js.map +1 -0
- package/dist/engine/draw/pixelAlign.d.ts +115 -0
- package/dist/engine/draw/pixelAlign.d.ts.map +1 -0
- package/dist/engine/draw/pixelAlign.js +185 -0
- package/dist/engine/draw/pixelAlign.js.map +1 -0
- package/dist/engine/drawing/index.d.ts +48 -0
- package/dist/engine/drawing/index.d.ts.map +1 -0
- package/dist/engine/drawing/index.js +561 -0
- package/dist/engine/drawing/index.js.map +1 -0
- package/dist/engine/drawing/interaction.d.ts +76 -0
- package/dist/engine/drawing/interaction.d.ts.map +1 -0
- package/dist/engine/drawing/interaction.js +702 -0
- package/dist/engine/drawing/interaction.js.map +1 -0
- package/dist/engine/drawing/plugin.d.ts +29 -0
- package/dist/engine/drawing/plugin.d.ts.map +1 -0
- package/dist/engine/drawing/plugin.js +292 -0
- package/dist/engine/drawing/plugin.js.map +1 -0
- package/dist/engine/indicators/atrState.d.ts +17 -0
- package/dist/engine/indicators/atrState.d.ts.map +1 -0
- package/dist/engine/indicators/atrState.js +13 -0
- package/dist/engine/indicators/atrState.js.map +1 -0
- package/dist/engine/indicators/bollState.d.ts +35 -0
- package/dist/engine/indicators/bollState.d.ts.map +1 -0
- package/dist/engine/indicators/bollState.js +25 -0
- package/dist/engine/indicators/bollState.js.map +1 -0
- package/dist/engine/indicators/calculators.d.ts +466 -0
- package/dist/engine/indicators/calculators.d.ts.map +1 -0
- package/dist/engine/indicators/calculators.js +1882 -0
- package/dist/engine/indicators/calculators.js.map +1 -0
- package/dist/engine/indicators/cciState.d.ts +16 -0
- package/dist/engine/indicators/cciState.d.ts.map +1 -0
- package/dist/engine/indicators/cciState.js +12 -0
- package/dist/engine/indicators/cciState.js.map +1 -0
- package/dist/engine/indicators/chaikinVolState.d.ts +19 -0
- package/dist/engine/indicators/chaikinVolState.d.ts.map +1 -0
- package/dist/engine/indicators/chaikinVolState.js +18 -0
- package/dist/engine/indicators/chaikinVolState.js.map +1 -0
- package/dist/engine/indicators/cmfState.d.ts +17 -0
- package/dist/engine/indicators/cmfState.d.ts.map +1 -0
- package/dist/engine/indicators/cmfState.js +13 -0
- package/dist/engine/indicators/cmfState.js.map +1 -0
- package/dist/engine/indicators/demaState.d.ts +17 -0
- package/dist/engine/indicators/demaState.d.ts.map +1 -0
- package/dist/engine/indicators/demaState.js +13 -0
- package/dist/engine/indicators/demaState.js.map +1 -0
- package/dist/engine/indicators/donchianState.d.ts +24 -0
- package/dist/engine/indicators/donchianState.d.ts.map +1 -0
- package/dist/engine/indicators/donchianState.js +18 -0
- package/dist/engine/indicators/donchianState.js.map +1 -0
- package/dist/engine/indicators/eneState.d.ts +31 -0
- package/dist/engine/indicators/eneState.d.ts.map +1 -0
- package/dist/engine/indicators/eneState.js +21 -0
- package/dist/engine/indicators/eneState.js.map +1 -0
- package/dist/engine/indicators/expmaState.d.ts +31 -0
- package/dist/engine/indicators/expmaState.d.ts.map +1 -0
- package/dist/engine/indicators/expmaState.js +21 -0
- package/dist/engine/indicators/expmaState.js.map +1 -0
- package/dist/engine/indicators/fastkState.d.ts +16 -0
- package/dist/engine/indicators/fastkState.d.ts.map +1 -0
- package/dist/engine/indicators/fastkState.js +12 -0
- package/dist/engine/indicators/fastkState.js.map +1 -0
- package/dist/engine/indicators/fibState.d.ts +27 -0
- package/dist/engine/indicators/fibState.d.ts.map +1 -0
- package/dist/engine/indicators/fibState.js +13 -0
- package/dist/engine/indicators/fibState.js.map +1 -0
- package/dist/engine/indicators/hmaState.d.ts +17 -0
- package/dist/engine/indicators/hmaState.d.ts.map +1 -0
- package/dist/engine/indicators/hmaState.js +13 -0
- package/dist/engine/indicators/hmaState.js.map +1 -0
- package/dist/engine/indicators/hvState.d.ts +19 -0
- package/dist/engine/indicators/hvState.d.ts.map +1 -0
- package/dist/engine/indicators/hvState.js +14 -0
- package/dist/engine/indicators/hvState.js.map +1 -0
- package/dist/engine/indicators/ichimokuState.d.ts +45 -0
- package/dist/engine/indicators/ichimokuState.d.ts.map +1 -0
- package/dist/engine/indicators/ichimokuState.js +27 -0
- package/dist/engine/indicators/ichimokuState.js.map +1 -0
- package/dist/engine/indicators/indicator.worker.d.ts +6 -0
- package/dist/engine/indicators/indicator.worker.d.ts.map +1 -0
- package/dist/engine/indicators/indicator.worker.js +144 -0
- package/dist/engine/indicators/indicator.worker.js.map +1 -0
- package/dist/engine/indicators/indicatorDefinitionRegistry.d.ts +31 -0
- package/dist/engine/indicators/indicatorDefinitionRegistry.d.ts.map +1 -0
- package/dist/engine/indicators/indicatorDefinitionRegistry.js +38 -0
- package/dist/engine/indicators/indicatorDefinitionRegistry.js.map +1 -0
- package/dist/engine/indicators/indicatorMetadata.d.ts +88 -0
- package/dist/engine/indicators/indicatorMetadata.d.ts.map +1 -0
- package/dist/engine/indicators/indicatorMetadata.js +22 -0
- package/dist/engine/indicators/indicatorMetadata.js.map +1 -0
- package/dist/engine/indicators/indicatorRegistry.d.ts +58 -0
- package/dist/engine/indicators/indicatorRegistry.d.ts.map +1 -0
- package/dist/engine/indicators/indicatorRegistry.js +91 -0
- package/dist/engine/indicators/indicatorRegistry.js.map +1 -0
- package/dist/engine/indicators/indicatorRuntime.d.ts +132 -0
- package/dist/engine/indicators/indicatorRuntime.d.ts.map +1 -0
- package/dist/engine/indicators/indicatorRuntime.js +1354 -0
- package/dist/engine/indicators/indicatorRuntime.js.map +1 -0
- package/dist/engine/indicators/kamaState.d.ts +21 -0
- package/dist/engine/indicators/kamaState.d.ts.map +1 -0
- package/dist/engine/indicators/kamaState.js +20 -0
- package/dist/engine/indicators/kamaState.js.map +1 -0
- package/dist/engine/indicators/keltnerState.d.ts +28 -0
- package/dist/engine/indicators/keltnerState.d.ts.map +1 -0
- package/dist/engine/indicators/keltnerState.js +22 -0
- package/dist/engine/indicators/keltnerState.js.map +1 -0
- package/dist/engine/indicators/kstState.d.ts +22 -0
- package/dist/engine/indicators/kstState.d.ts.map +1 -0
- package/dist/engine/indicators/kstState.js +20 -0
- package/dist/engine/indicators/kstState.js.map +1 -0
- package/dist/engine/indicators/maState.d.ts +27 -0
- package/dist/engine/indicators/maState.d.ts.map +1 -0
- package/dist/engine/indicators/maState.js +18 -0
- package/dist/engine/indicators/maState.js.map +1 -0
- package/dist/engine/indicators/macdState.d.ts +59 -0
- package/dist/engine/indicators/macdState.d.ts.map +1 -0
- package/dist/engine/indicators/macdState.js +33 -0
- package/dist/engine/indicators/macdState.js.map +1 -0
- package/dist/engine/indicators/mfiState.d.ts +17 -0
- package/dist/engine/indicators/mfiState.d.ts.map +1 -0
- package/dist/engine/indicators/mfiState.js +13 -0
- package/dist/engine/indicators/mfiState.js.map +1 -0
- package/dist/engine/indicators/momState.d.ts +16 -0
- package/dist/engine/indicators/momState.d.ts.map +1 -0
- package/dist/engine/indicators/momState.js +12 -0
- package/dist/engine/indicators/momState.js.map +1 -0
- package/dist/engine/indicators/obvState.d.ts +15 -0
- package/dist/engine/indicators/obvState.d.ts.map +1 -0
- package/dist/engine/indicators/obvState.js +12 -0
- package/dist/engine/indicators/obvState.js.map +1 -0
- package/dist/engine/indicators/parkinsonState.d.ts +19 -0
- package/dist/engine/indicators/parkinsonState.d.ts.map +1 -0
- package/dist/engine/indicators/parkinsonState.js +14 -0
- package/dist/engine/indicators/parkinsonState.js.map +1 -0
- package/dist/engine/indicators/pivotState.d.ts +30 -0
- package/dist/engine/indicators/pivotState.d.ts.map +1 -0
- package/dist/engine/indicators/pivotState.js +20 -0
- package/dist/engine/indicators/pivotState.js.map +1 -0
- package/dist/engine/indicators/pvtState.d.ts +15 -0
- package/dist/engine/indicators/pvtState.d.ts.map +1 -0
- package/dist/engine/indicators/pvtState.js +12 -0
- package/dist/engine/indicators/pvtState.js.map +1 -0
- package/dist/engine/indicators/rocState.d.ts +17 -0
- package/dist/engine/indicators/rocState.d.ts.map +1 -0
- package/dist/engine/indicators/rocState.js +13 -0
- package/dist/engine/indicators/rocState.js.map +1 -0
- package/dist/engine/indicators/rsiState.d.ts +44 -0
- package/dist/engine/indicators/rsiState.d.ts.map +1 -0
- package/dist/engine/indicators/rsiState.js +32 -0
- package/dist/engine/indicators/rsiState.js.map +1 -0
- package/dist/engine/indicators/sarState.d.ts +27 -0
- package/dist/engine/indicators/sarState.d.ts.map +1 -0
- package/dist/engine/indicators/sarState.js +18 -0
- package/dist/engine/indicators/sarState.js.map +1 -0
- package/dist/engine/indicators/scheduler.d.ts +277 -0
- package/dist/engine/indicators/scheduler.d.ts.map +1 -0
- package/dist/engine/indicators/scheduler.js +1012 -0
- package/dist/engine/indicators/scheduler.js.map +1 -0
- package/dist/engine/indicators/soa.d.ts +116 -0
- package/dist/engine/indicators/soa.d.ts.map +1 -0
- package/dist/engine/indicators/soa.js +242 -0
- package/dist/engine/indicators/soa.js.map +1 -0
- package/dist/engine/indicators/stateComposer.d.ts +151 -0
- package/dist/engine/indicators/stateComposer.d.ts.map +1 -0
- package/dist/engine/indicators/stateComposer.js +1018 -0
- package/dist/engine/indicators/stateComposer.js.map +1 -0
- package/dist/engine/indicators/stochState.d.ts +19 -0
- package/dist/engine/indicators/stochState.d.ts.map +1 -0
- package/dist/engine/indicators/stochState.js +12 -0
- package/dist/engine/indicators/stochState.js.map +1 -0
- package/dist/engine/indicators/structureState.d.ts +44 -0
- package/dist/engine/indicators/structureState.d.ts.map +1 -0
- package/dist/engine/indicators/structureState.js +22 -0
- package/dist/engine/indicators/structureState.js.map +1 -0
- package/dist/engine/indicators/supertrendState.d.ts +23 -0
- package/dist/engine/indicators/supertrendState.d.ts.map +1 -0
- package/dist/engine/indicators/supertrendState.js +18 -0
- package/dist/engine/indicators/supertrendState.js.map +1 -0
- package/dist/engine/indicators/temaState.d.ts +17 -0
- package/dist/engine/indicators/temaState.d.ts.map +1 -0
- package/dist/engine/indicators/temaState.js +13 -0
- package/dist/engine/indicators/temaState.js.map +1 -0
- package/dist/engine/indicators/trixState.d.ts +21 -0
- package/dist/engine/indicators/trixState.d.ts.map +1 -0
- package/dist/engine/indicators/trixState.js +20 -0
- package/dist/engine/indicators/trixState.js.map +1 -0
- package/dist/engine/indicators/vmaState.d.ts +17 -0
- package/dist/engine/indicators/vmaState.d.ts.map +1 -0
- package/dist/engine/indicators/vmaState.js +13 -0
- package/dist/engine/indicators/vmaState.js.map +1 -0
- package/dist/engine/indicators/volumeProfileState.d.ts +35 -0
- package/dist/engine/indicators/volumeProfileState.d.ts.map +1 -0
- package/dist/engine/indicators/volumeProfileState.js +28 -0
- package/dist/engine/indicators/volumeProfileState.js.map +1 -0
- package/dist/engine/indicators/vwapState.d.ts +17 -0
- package/dist/engine/indicators/vwapState.d.ts.map +1 -0
- package/dist/engine/indicators/vwapState.js +15 -0
- package/dist/engine/indicators/vwapState.js.map +1 -0
- package/dist/engine/indicators/wmaState.d.ts +17 -0
- package/dist/engine/indicators/wmaState.d.ts.map +1 -0
- package/dist/engine/indicators/wmaState.js +13 -0
- package/dist/engine/indicators/wmaState.js.map +1 -0
- package/dist/engine/indicators/wmsrState.d.ts +16 -0
- package/dist/engine/indicators/wmsrState.d.ts.map +1 -0
- package/dist/engine/indicators/wmsrState.js +12 -0
- package/dist/engine/indicators/wmsrState.js.map +1 -0
- package/dist/engine/indicators/workerProtocol.d.ts +501 -0
- package/dist/engine/indicators/workerProtocol.d.ts.map +1 -0
- package/dist/engine/indicators/workerProtocol.js +20 -0
- package/dist/engine/indicators/workerProtocol.js.map +1 -0
- package/dist/engine/indicators/zonesState.d.ts +27 -0
- package/dist/engine/indicators/zonesState.d.ts.map +1 -0
- package/dist/engine/indicators/zonesState.js +18 -0
- package/dist/engine/indicators/zonesState.js.map +1 -0
- package/dist/engine/layout/pane.d.ts +104 -0
- package/dist/engine/layout/pane.d.ts.map +1 -0
- package/dist/engine/layout/pane.js +107 -0
- package/dist/engine/layout/pane.js.map +1 -0
- package/dist/engine/marker/registry.d.ts +175 -0
- package/dist/engine/marker/registry.d.ts.map +1 -0
- package/dist/engine/marker/registry.js +171 -0
- package/dist/engine/marker/registry.js.map +1 -0
- package/dist/engine/paneRenderer.d.ts +46 -0
- package/dist/engine/paneRenderer.d.ts.map +1 -0
- package/dist/engine/paneRenderer.js +121 -0
- package/dist/engine/paneRenderer.js.map +1 -0
- package/dist/engine/renderers/Indicator/atr.d.ts +18 -0
- package/dist/engine/renderers/Indicator/atr.d.ts.map +1 -0
- package/dist/engine/renderers/Indicator/atr.js +237 -0
- package/dist/engine/renderers/Indicator/atr.js.map +1 -0
- package/dist/engine/renderers/Indicator/boll.d.ts +3 -0
- package/dist/engine/renderers/Indicator/boll.d.ts.map +1 -0
- package/dist/engine/renderers/Indicator/boll.js +312 -0
- package/dist/engine/renderers/Indicator/boll.js.map +1 -0
- package/dist/engine/renderers/Indicator/cci.d.ts +23 -0
- package/dist/engine/renderers/Indicator/cci.d.ts.map +1 -0
- package/dist/engine/renderers/Indicator/cci.js +266 -0
- package/dist/engine/renderers/Indicator/cci.js.map +1 -0
- package/dist/engine/renderers/Indicator/chaikinVol.d.ts +5 -0
- package/dist/engine/renderers/Indicator/chaikinVol.d.ts.map +1 -0
- package/dist/engine/renderers/Indicator/chaikinVol.js +175 -0
- package/dist/engine/renderers/Indicator/chaikinVol.js.map +1 -0
- package/dist/engine/renderers/Indicator/cmf.d.ts +5 -0
- package/dist/engine/renderers/Indicator/cmf.d.ts.map +1 -0
- package/dist/engine/renderers/Indicator/cmf.js +175 -0
- package/dist/engine/renderers/Indicator/cmf.js.map +1 -0
- package/dist/engine/renderers/Indicator/dema.d.ts +6 -0
- package/dist/engine/renderers/Indicator/dema.d.ts.map +1 -0
- package/dist/engine/renderers/Indicator/dema.js +164 -0
- package/dist/engine/renderers/Indicator/dema.js.map +1 -0
- package/dist/engine/renderers/Indicator/donchian.d.ts +6 -0
- package/dist/engine/renderers/Indicator/donchian.d.ts.map +1 -0
- package/dist/engine/renderers/Indicator/donchian.js +181 -0
- package/dist/engine/renderers/Indicator/donchian.js.map +1 -0
- package/dist/engine/renderers/Indicator/ene.d.ts +3 -0
- package/dist/engine/renderers/Indicator/ene.d.ts.map +1 -0
- package/dist/engine/renderers/Indicator/ene.js +280 -0
- package/dist/engine/renderers/Indicator/ene.js.map +1 -0
- package/dist/engine/renderers/Indicator/expma.d.ts +3 -0
- package/dist/engine/renderers/Indicator/expma.d.ts.map +1 -0
- package/dist/engine/renderers/Indicator/expma.js +216 -0
- package/dist/engine/renderers/Indicator/expma.js.map +1 -0
- package/dist/engine/renderers/Indicator/fastk.d.ts +23 -0
- package/dist/engine/renderers/Indicator/fastk.d.ts.map +1 -0
- package/dist/engine/renderers/Indicator/fastk.js +289 -0
- package/dist/engine/renderers/Indicator/fastk.js.map +1 -0
- package/dist/engine/renderers/Indicator/fib.d.ts +5 -0
- package/dist/engine/renderers/Indicator/fib.d.ts.map +1 -0
- package/dist/engine/renderers/Indicator/fib.js +182 -0
- package/dist/engine/renderers/Indicator/fib.js.map +1 -0
- package/dist/engine/renderers/Indicator/hma.d.ts +6 -0
- package/dist/engine/renderers/Indicator/hma.d.ts.map +1 -0
- package/dist/engine/renderers/Indicator/hma.js +164 -0
- package/dist/engine/renderers/Indicator/hma.js.map +1 -0
- package/dist/engine/renderers/Indicator/hv.d.ts +5 -0
- package/dist/engine/renderers/Indicator/hv.d.ts.map +1 -0
- package/dist/engine/renderers/Indicator/hv.js +162 -0
- package/dist/engine/renderers/Indicator/hv.js.map +1 -0
- package/dist/engine/renderers/Indicator/ichimoku.d.ts +6 -0
- package/dist/engine/renderers/Indicator/ichimoku.d.ts.map +1 -0
- package/dist/engine/renderers/Indicator/ichimoku.js +220 -0
- package/dist/engine/renderers/Indicator/ichimoku.js.map +1 -0
- package/dist/engine/renderers/Indicator/index.d.ts +63 -0
- package/dist/engine/renderers/Indicator/index.d.ts.map +1 -0
- package/dist/engine/renderers/Indicator/index.js +204 -0
- package/dist/engine/renderers/Indicator/index.js.map +1 -0
- package/dist/engine/renderers/Indicator/indicatorData.d.ts +23 -0
- package/dist/engine/renderers/Indicator/indicatorData.d.ts.map +1 -0
- package/dist/engine/renderers/Indicator/indicatorData.js +617 -0
- package/dist/engine/renderers/Indicator/indicatorData.js.map +1 -0
- package/dist/engine/renderers/Indicator/kama.d.ts +6 -0
- package/dist/engine/renderers/Indicator/kama.d.ts.map +1 -0
- package/dist/engine/renderers/Indicator/kama.js +164 -0
- package/dist/engine/renderers/Indicator/kama.js.map +1 -0
- package/dist/engine/renderers/Indicator/keltner.d.ts +6 -0
- package/dist/engine/renderers/Indicator/keltner.d.ts.map +1 -0
- package/dist/engine/renderers/Indicator/keltner.js +181 -0
- package/dist/engine/renderers/Indicator/keltner.js.map +1 -0
- package/dist/engine/renderers/Indicator/kst.d.ts +23 -0
- package/dist/engine/renderers/Indicator/kst.d.ts.map +1 -0
- package/dist/engine/renderers/Indicator/kst.js +290 -0
- package/dist/engine/renderers/Indicator/kst.js.map +1 -0
- package/dist/engine/renderers/Indicator/ma.d.ts +4 -0
- package/dist/engine/renderers/Indicator/ma.d.ts.map +1 -0
- package/dist/engine/renderers/Indicator/ma.js +218 -0
- package/dist/engine/renderers/Indicator/ma.js.map +1 -0
- package/dist/engine/renderers/Indicator/macd.d.ts +51 -0
- package/dist/engine/renderers/Indicator/macd.d.ts.map +1 -0
- package/dist/engine/renderers/Indicator/macd.js +432 -0
- package/dist/engine/renderers/Indicator/macd.js.map +1 -0
- package/dist/engine/renderers/Indicator/macdLegend.d.ts +13 -0
- package/dist/engine/renderers/Indicator/macdLegend.d.ts.map +1 -0
- package/dist/engine/renderers/Indicator/macdLegend.js +116 -0
- package/dist/engine/renderers/Indicator/macdLegend.js.map +1 -0
- package/dist/engine/renderers/Indicator/mainIndicatorLegend.d.ts +11 -0
- package/dist/engine/renderers/Indicator/mainIndicatorLegend.d.ts.map +1 -0
- package/dist/engine/renderers/Indicator/mainIndicatorLegend.js +220 -0
- package/dist/engine/renderers/Indicator/mainIndicatorLegend.js.map +1 -0
- package/dist/engine/renderers/Indicator/mfi.d.ts +5 -0
- package/dist/engine/renderers/Indicator/mfi.d.ts.map +1 -0
- package/dist/engine/renderers/Indicator/mfi.js +180 -0
- package/dist/engine/renderers/Indicator/mfi.js.map +1 -0
- package/dist/engine/renderers/Indicator/mom.d.ts +23 -0
- package/dist/engine/renderers/Indicator/mom.d.ts.map +1 -0
- package/dist/engine/renderers/Indicator/mom.js +285 -0
- package/dist/engine/renderers/Indicator/mom.js.map +1 -0
- package/dist/engine/renderers/Indicator/obv.d.ts +5 -0
- package/dist/engine/renderers/Indicator/obv.d.ts.map +1 -0
- package/dist/engine/renderers/Indicator/obv.js +162 -0
- package/dist/engine/renderers/Indicator/obv.js.map +1 -0
- package/dist/engine/renderers/Indicator/parkinson.d.ts +5 -0
- package/dist/engine/renderers/Indicator/parkinson.d.ts.map +1 -0
- package/dist/engine/renderers/Indicator/parkinson.js +162 -0
- package/dist/engine/renderers/Indicator/parkinson.js.map +1 -0
- package/dist/engine/renderers/Indicator/pivot.d.ts +5 -0
- package/dist/engine/renderers/Indicator/pivot.d.ts.map +1 -0
- package/dist/engine/renderers/Indicator/pivot.js +181 -0
- package/dist/engine/renderers/Indicator/pivot.js.map +1 -0
- package/dist/engine/renderers/Indicator/pvt.d.ts +5 -0
- package/dist/engine/renderers/Indicator/pvt.d.ts.map +1 -0
- package/dist/engine/renderers/Indicator/pvt.js +162 -0
- package/dist/engine/renderers/Indicator/pvt.js.map +1 -0
- package/dist/engine/renderers/Indicator/roc.d.ts +6 -0
- package/dist/engine/renderers/Indicator/roc.d.ts.map +1 -0
- package/dist/engine/renderers/Indicator/roc.js +175 -0
- package/dist/engine/renderers/Indicator/roc.js.map +1 -0
- package/dist/engine/renderers/Indicator/rsi.d.ts +34 -0
- package/dist/engine/renderers/Indicator/rsi.d.ts.map +1 -0
- package/dist/engine/renderers/Indicator/rsi.js +351 -0
- package/dist/engine/renderers/Indicator/rsi.js.map +1 -0
- package/dist/engine/renderers/Indicator/sar.d.ts +6 -0
- package/dist/engine/renderers/Indicator/sar.d.ts.map +1 -0
- package/dist/engine/renderers/Indicator/sar.js +146 -0
- package/dist/engine/renderers/Indicator/sar.js.map +1 -0
- package/dist/engine/renderers/Indicator/scale/atr_scale.d.ts +12 -0
- package/dist/engine/renderers/Indicator/scale/atr_scale.d.ts.map +1 -0
- package/dist/engine/renderers/Indicator/scale/atr_scale.js +13 -0
- package/dist/engine/renderers/Indicator/scale/atr_scale.js.map +1 -0
- package/dist/engine/renderers/Indicator/scale/cci_scale.d.ts +12 -0
- package/dist/engine/renderers/Indicator/scale/cci_scale.d.ts.map +1 -0
- package/dist/engine/renderers/Indicator/scale/cci_scale.js +13 -0
- package/dist/engine/renderers/Indicator/scale/cci_scale.js.map +1 -0
- package/dist/engine/renderers/Indicator/scale/fastk_scale.d.ts +12 -0
- package/dist/engine/renderers/Indicator/scale/fastk_scale.d.ts.map +1 -0
- package/dist/engine/renderers/Indicator/scale/fastk_scale.js +13 -0
- package/dist/engine/renderers/Indicator/scale/fastk_scale.js.map +1 -0
- package/dist/engine/renderers/Indicator/scale/indicator_scale.d.ts +39 -0
- package/dist/engine/renderers/Indicator/scale/indicator_scale.d.ts.map +1 -0
- package/dist/engine/renderers/Indicator/scale/indicator_scale.js +120 -0
- package/dist/engine/renderers/Indicator/scale/indicator_scale.js.map +1 -0
- package/dist/engine/renderers/Indicator/scale/kst_scale.d.ts +12 -0
- package/dist/engine/renderers/Indicator/scale/kst_scale.d.ts.map +1 -0
- package/dist/engine/renderers/Indicator/scale/kst_scale.js +13 -0
- package/dist/engine/renderers/Indicator/scale/kst_scale.js.map +1 -0
- package/dist/engine/renderers/Indicator/scale/macd_scale.d.ts +15 -0
- package/dist/engine/renderers/Indicator/scale/macd_scale.d.ts.map +1 -0
- package/dist/engine/renderers/Indicator/scale/macd_scale.js +16 -0
- package/dist/engine/renderers/Indicator/scale/macd_scale.js.map +1 -0
- package/dist/engine/renderers/Indicator/scale/mom_scale.d.ts +12 -0
- package/dist/engine/renderers/Indicator/scale/mom_scale.d.ts.map +1 -0
- package/dist/engine/renderers/Indicator/scale/mom_scale.js +13 -0
- package/dist/engine/renderers/Indicator/scale/mom_scale.js.map +1 -0
- package/dist/engine/renderers/Indicator/scale/rsi_scale.d.ts +12 -0
- package/dist/engine/renderers/Indicator/scale/rsi_scale.d.ts.map +1 -0
- package/dist/engine/renderers/Indicator/scale/rsi_scale.js +13 -0
- package/dist/engine/renderers/Indicator/scale/rsi_scale.js.map +1 -0
- package/dist/engine/renderers/Indicator/scale/stoch_scale.d.ts +12 -0
- package/dist/engine/renderers/Indicator/scale/stoch_scale.d.ts.map +1 -0
- package/dist/engine/renderers/Indicator/scale/stoch_scale.js +13 -0
- package/dist/engine/renderers/Indicator/scale/stoch_scale.js.map +1 -0
- package/dist/engine/renderers/Indicator/scale/volume_scale.d.ts +15 -0
- package/dist/engine/renderers/Indicator/scale/volume_scale.d.ts.map +1 -0
- package/dist/engine/renderers/Indicator/scale/volume_scale.js +19 -0
- package/dist/engine/renderers/Indicator/scale/volume_scale.js.map +1 -0
- package/dist/engine/renderers/Indicator/scale/wmsr_scale.d.ts +12 -0
- package/dist/engine/renderers/Indicator/scale/wmsr_scale.d.ts.map +1 -0
- package/dist/engine/renderers/Indicator/scale/wmsr_scale.js +13 -0
- package/dist/engine/renderers/Indicator/scale/wmsr_scale.js.map +1 -0
- package/dist/engine/renderers/Indicator/stoch.d.ts +23 -0
- package/dist/engine/renderers/Indicator/stoch.d.ts.map +1 -0
- package/dist/engine/renderers/Indicator/stoch.js +329 -0
- package/dist/engine/renderers/Indicator/stoch.js.map +1 -0
- package/dist/engine/renderers/Indicator/structure.d.ts +5 -0
- package/dist/engine/renderers/Indicator/structure.d.ts.map +1 -0
- package/dist/engine/renderers/Indicator/structure.js +176 -0
- package/dist/engine/renderers/Indicator/structure.js.map +1 -0
- package/dist/engine/renderers/Indicator/subPaneConfig.d.ts +16 -0
- package/dist/engine/renderers/Indicator/subPaneConfig.d.ts.map +1 -0
- package/dist/engine/renderers/Indicator/subPaneConfig.js +194 -0
- package/dist/engine/renderers/Indicator/subPaneConfig.js.map +1 -0
- package/dist/engine/renderers/Indicator/supertrend.d.ts +6 -0
- package/dist/engine/renderers/Indicator/supertrend.d.ts.map +1 -0
- package/dist/engine/renderers/Indicator/supertrend.js +149 -0
- package/dist/engine/renderers/Indicator/supertrend.js.map +1 -0
- package/dist/engine/renderers/Indicator/tema.d.ts +6 -0
- package/dist/engine/renderers/Indicator/tema.d.ts.map +1 -0
- package/dist/engine/renderers/Indicator/tema.js +164 -0
- package/dist/engine/renderers/Indicator/tema.js.map +1 -0
- package/dist/engine/renderers/Indicator/trix.d.ts +6 -0
- package/dist/engine/renderers/Indicator/trix.d.ts.map +1 -0
- package/dist/engine/renderers/Indicator/trix.js +197 -0
- package/dist/engine/renderers/Indicator/trix.js.map +1 -0
- package/dist/engine/renderers/Indicator/vma.d.ts +5 -0
- package/dist/engine/renderers/Indicator/vma.d.ts.map +1 -0
- package/dist/engine/renderers/Indicator/vma.js +162 -0
- package/dist/engine/renderers/Indicator/vma.js.map +1 -0
- package/dist/engine/renderers/Indicator/volumeProfile.d.ts +5 -0
- package/dist/engine/renderers/Indicator/volumeProfile.d.ts.map +1 -0
- package/dist/engine/renderers/Indicator/volumeProfile.js +165 -0
- package/dist/engine/renderers/Indicator/volumeProfile.js.map +1 -0
- package/dist/engine/renderers/Indicator/vwap.d.ts +5 -0
- package/dist/engine/renderers/Indicator/vwap.d.ts.map +1 -0
- package/dist/engine/renderers/Indicator/vwap.js +162 -0
- package/dist/engine/renderers/Indicator/vwap.js.map +1 -0
- package/dist/engine/renderers/Indicator/wma.d.ts +6 -0
- package/dist/engine/renderers/Indicator/wma.d.ts.map +1 -0
- package/dist/engine/renderers/Indicator/wma.js +164 -0
- package/dist/engine/renderers/Indicator/wma.js.map +1 -0
- package/dist/engine/renderers/Indicator/wmsr.d.ts +23 -0
- package/dist/engine/renderers/Indicator/wmsr.d.ts.map +1 -0
- package/dist/engine/renderers/Indicator/wmsr.js +298 -0
- package/dist/engine/renderers/Indicator/wmsr.js.map +1 -0
- package/dist/engine/renderers/Indicator/zones.d.ts +5 -0
- package/dist/engine/renderers/Indicator/zones.d.ts.map +1 -0
- package/dist/engine/renderers/Indicator/zones.js +151 -0
- package/dist/engine/renderers/Indicator/zones.js.map +1 -0
- package/dist/engine/renderers/candle.d.ts +22 -0
- package/dist/engine/renderers/candle.d.ts.map +1 -0
- package/dist/engine/renderers/candle.js +356 -0
- package/dist/engine/renderers/candle.js.map +1 -0
- package/dist/engine/renderers/crosshair.d.ts +18 -0
- package/dist/engine/renderers/crosshair.d.ts.map +1 -0
- package/dist/engine/renderers/crosshair.js +54 -0
- package/dist/engine/renderers/crosshair.js.map +1 -0
- package/dist/engine/renderers/customMarkers.d.ts +7 -0
- package/dist/engine/renderers/customMarkers.d.ts.map +1 -0
- package/dist/engine/renderers/customMarkers.js +145 -0
- package/dist/engine/renderers/customMarkers.js.map +1 -0
- package/dist/engine/renderers/extremaMarkers.d.ts +6 -0
- package/dist/engine/renderers/extremaMarkers.d.ts.map +1 -0
- package/dist/engine/renderers/extremaMarkers.js +181 -0
- package/dist/engine/renderers/extremaMarkers.js.map +1 -0
- package/dist/engine/renderers/gridLines.d.ts +8 -0
- package/dist/engine/renderers/gridLines.d.ts.map +1 -0
- package/dist/engine/renderers/gridLines.js +84 -0
- package/dist/engine/renderers/gridLines.js.map +1 -0
- package/dist/engine/renderers/lastPrice.d.ts +10 -0
- package/dist/engine/renderers/lastPrice.d.ts.map +1 -0
- package/dist/engine/renderers/lastPrice.js +87 -0
- package/dist/engine/renderers/lastPrice.js.map +1 -0
- package/dist/engine/renderers/paneTitle.d.ts +41 -0
- package/dist/engine/renderers/paneTitle.d.ts.map +1 -0
- package/dist/engine/renderers/paneTitle.js +86 -0
- package/dist/engine/renderers/paneTitle.js.map +1 -0
- package/dist/engine/renderers/subVolume.d.ts +14 -0
- package/dist/engine/renderers/subVolume.d.ts.map +1 -0
- package/dist/engine/renderers/subVolume.js +247 -0
- package/dist/engine/renderers/subVolume.js.map +1 -0
- package/dist/engine/renderers/timeAxis.d.ts +15 -0
- package/dist/engine/renderers/timeAxis.d.ts.map +1 -0
- package/dist/engine/renderers/timeAxis.js +107 -0
- package/dist/engine/renderers/timeAxis.js.map +1 -0
- package/dist/engine/renderers/webgl/candleSurface.d.ts +81 -0
- package/dist/engine/renderers/webgl/candleSurface.d.ts.map +1 -0
- package/dist/engine/renderers/webgl/candleSurface.js +811 -0
- package/dist/engine/renderers/webgl/candleSurface.js.map +1 -0
- package/dist/engine/renderers/webgl/sharedWebGLSurface.d.ts +34 -0
- package/dist/engine/renderers/webgl/sharedWebGLSurface.d.ts.map +1 -0
- package/dist/engine/renderers/webgl/sharedWebGLSurface.js +102 -0
- package/dist/engine/renderers/webgl/sharedWebGLSurface.js.map +1 -0
- package/dist/engine/renderers/yAxis.d.ts +15 -0
- package/dist/engine/renderers/yAxis.d.ts.map +1 -0
- package/dist/engine/renderers/yAxis.js +93 -0
- package/dist/engine/renderers/yAxis.js.map +1 -0
- package/dist/engine/scale/logFormula.d.ts +67 -0
- package/dist/engine/scale/logFormula.d.ts.map +1 -0
- package/dist/engine/scale/logFormula.js +107 -0
- package/dist/engine/scale/logFormula.js.map +1 -0
- package/dist/engine/scale/price.d.ts +12 -0
- package/dist/engine/scale/price.d.ts.map +1 -0
- package/dist/engine/scale/price.js +20 -0
- package/dist/engine/scale/price.js.map +1 -0
- package/dist/engine/scale/priceScale.d.ts +88 -0
- package/dist/engine/scale/priceScale.d.ts.map +1 -0
- package/dist/engine/scale/priceScale.js +227 -0
- package/dist/engine/scale/priceScale.js.map +1 -0
- package/dist/engine/subPaneManager.d.ts +23 -0
- package/dist/engine/subPaneManager.d.ts.map +1 -0
- package/dist/engine/subPaneManager.js +342 -0
- package/dist/engine/subPaneManager.js.map +1 -0
- package/dist/engine/theme/colors.d.ts +223 -0
- package/dist/engine/theme/colors.d.ts.map +1 -0
- package/dist/engine/theme/colors.js +375 -0
- package/dist/engine/theme/colors.js.map +1 -0
- package/dist/engine/theme/fonts.d.ts +13 -0
- package/dist/engine/theme/fonts.d.ts.map +1 -0
- package/dist/engine/theme/fonts.js +18 -0
- package/dist/engine/theme/fonts.js.map +1 -0
- package/dist/engine/utils/klineConfig.d.ts +29 -0
- package/dist/engine/utils/klineConfig.d.ts.map +1 -0
- package/dist/engine/utils/klineConfig.js +46 -0
- package/dist/engine/utils/klineConfig.js.map +1 -0
- package/dist/engine/utils/tickCount.d.ts +9 -0
- package/dist/engine/utils/tickCount.d.ts.map +1 -0
- package/dist/engine/utils/tickCount.js +12 -0
- package/dist/engine/utils/tickCount.js.map +1 -0
- package/dist/engine/utils/tickPosition.d.ts +25 -0
- package/dist/engine/utils/tickPosition.d.ts.map +1 -0
- package/dist/engine/utils/tickPosition.js +141 -0
- package/dist/engine/utils/tickPosition.js.map +1 -0
- package/dist/engine/utils/zoom.d.ts +31 -0
- package/dist/engine/utils/zoom.d.ts.map +1 -0
- package/dist/engine/utils/zoom.js +43 -0
- package/dist/engine/utils/zoom.js.map +1 -0
- package/dist/engine/viewport/viewport.d.ts +32 -0
- package/dist/engine/viewport/viewport.d.ts.map +1 -0
- package/dist/engine/viewport/viewport.js +54 -0
- package/dist/engine/viewport/viewport.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/plugin/ConfigManager.d.ts +32 -0
- package/dist/plugin/ConfigManager.d.ts.map +1 -0
- package/dist/plugin/ConfigManager.js +81 -0
- package/dist/plugin/ConfigManager.js.map +1 -0
- package/dist/plugin/EventBus.d.ts +38 -0
- package/dist/plugin/EventBus.d.ts.map +1 -0
- package/dist/plugin/EventBus.js +66 -0
- package/dist/plugin/EventBus.js.map +1 -0
- package/dist/plugin/HookSystem.d.ts +32 -0
- package/dist/plugin/HookSystem.d.ts.map +1 -0
- package/dist/plugin/HookSystem.js +86 -0
- package/dist/plugin/HookSystem.js.map +1 -0
- package/dist/plugin/PluginHost.d.ts +61 -0
- package/dist/plugin/PluginHost.d.ts.map +1 -0
- package/dist/plugin/PluginHost.js +196 -0
- package/dist/plugin/PluginHost.js.map +1 -0
- package/dist/plugin/PluginRegistry.d.ts +44 -0
- package/dist/plugin/PluginRegistry.d.ts.map +1 -0
- package/dist/plugin/PluginRegistry.js +77 -0
- package/dist/plugin/PluginRegistry.js.map +1 -0
- package/dist/plugin/StateStore.d.ts +42 -0
- package/dist/plugin/StateStore.d.ts.map +1 -0
- package/dist/plugin/StateStore.js +63 -0
- package/dist/plugin/StateStore.js.map +1 -0
- package/dist/plugin/index.d.ts +12 -0
- package/dist/plugin/index.d.ts.map +1 -0
- package/dist/plugin/index.js +15 -0
- package/dist/plugin/index.js.map +1 -0
- package/dist/plugin/rendererPluginManager.d.ts +81 -0
- package/dist/plugin/rendererPluginManager.d.ts.map +1 -0
- package/dist/plugin/rendererPluginManager.js +309 -0
- package/dist/plugin/rendererPluginManager.js.map +1 -0
- package/dist/plugin/stateKeys.d.ts +7 -0
- package/dist/plugin/stateKeys.d.ts.map +1 -0
- package/dist/plugin/stateKeys.js +7 -0
- package/dist/plugin/stateKeys.js.map +1 -0
- package/dist/plugin/types.d.ts +449 -0
- package/dist/plugin/types.d.ts.map +1 -0
- package/dist/plugin/types.js +63 -0
- package/dist/plugin/types.js.map +1 -0
- package/dist/reactivity/index.d.ts +3 -0
- package/dist/reactivity/index.d.ts.map +1 -0
- package/dist/reactivity/index.js +2 -0
- package/dist/reactivity/index.js.map +1 -0
- package/dist/reactivity/signal.d.ts +40 -0
- package/dist/reactivity/signal.d.ts.map +1 -0
- package/dist/reactivity/signal.js +92 -0
- package/dist/reactivity/signal.js.map +1 -0
- package/dist/semantic/controller.d.ts +41 -0
- package/dist/semantic/controller.d.ts.map +1 -0
- package/dist/semantic/controller.js +189 -0
- package/dist/semantic/controller.js.map +1 -0
- package/dist/semantic/drawShape.d.ts +19 -0
- package/dist/semantic/drawShape.d.ts.map +1 -0
- package/dist/semantic/drawShape.js +209 -0
- package/dist/semantic/drawShape.js.map +1 -0
- package/dist/semantic/index.d.ts +6 -0
- package/dist/semantic/index.d.ts.map +1 -0
- package/dist/semantic/index.js +4 -0
- package/dist/semantic/index.js.map +1 -0
- package/dist/semantic/schema.json +256 -0
- package/dist/semantic/types.d.ts +299 -0
- package/dist/semantic/types.d.ts.map +1 -0
- package/dist/semantic/types.js +6 -0
- package/dist/semantic/types.js.map +1 -0
- package/dist/semantic/validator.d.ts +48 -0
- package/dist/semantic/validator.d.ts.map +1 -0
- package/dist/semantic/validator.js +288 -0
- package/dist/semantic/validator.js.map +1 -0
- package/dist/types/kLine.d.ts +4 -0
- package/dist/types/kLine.d.ts.map +1 -0
- package/dist/types/kLine.js +12 -0
- package/dist/types/kLine.js.map +1 -0
- package/dist/types/price.d.ts +32 -0
- package/dist/types/price.d.ts.map +1 -0
- package/dist/types/price.js +19 -0
- package/dist/types/price.js.map +1 -0
- package/dist/types/volumePrice.d.ts +27 -0
- package/dist/types/volumePrice.d.ts.map +1 -0
- package/dist/types/volumePrice.js +23 -0
- package/dist/types/volumePrice.js.map +1 -0
- package/dist/utils/dateFormat.d.ts +84 -0
- package/dist/utils/dateFormat.d.ts.map +1 -0
- package/dist/utils/dateFormat.js +193 -0
- package/dist/utils/dateFormat.js.map +1 -0
- package/dist/utils/kLineDraw/axis.d.ts +151 -0
- package/dist/utils/kLineDraw/axis.d.ts.map +1 -0
- package/dist/utils/kLineDraw/axis.js +243 -0
- package/dist/utils/kLineDraw/axis.js.map +1 -0
- package/dist/utils/priceToY.d.ts +8 -0
- package/dist/utils/priceToY.d.ts.map +1 -0
- package/dist/utils/priceToY.js +19 -0
- package/dist/utils/priceToY.js.map +1 -0
- package/dist/utils/volumePrice.d.ts +55 -0
- package/dist/utils/volumePrice.d.ts.map +1 -0
- package/dist/utils/volumePrice.js +170 -0
- package/dist/utils/volumePrice.js.map +1 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +3 -0
- package/dist/version.js.map +1 -0
- package/package.json +122 -0
- package/src/__tests__/signal.test.ts +124 -0
- package/src/config/chartSettings.ts +66 -0
- package/src/controllers/__tests__/drawing.test.ts +214 -0
- package/src/controllers/__tests__/indicatorSelector.test.ts +481 -0
- package/src/controllers/__tests__/toolbar.test.ts +225 -0
- package/src/controllers/createChartController.ts +665 -0
- package/src/controllers/createDrawingController.ts +96 -0
- package/src/controllers/createIndicatorSelectorController.ts +307 -0
- package/src/controllers/createToolbarController.ts +146 -0
- package/src/controllers/index.ts +19 -0
- package/src/controllers/types.ts +284 -0
- package/src/engine/__tests__/chart.dpr.test.ts +401 -0
- package/src/engine/__tests__/paneRenderer.resize.test.ts +92 -0
- package/src/engine/chart-store.ts +121 -0
- package/src/engine/chart.d.ts +618 -0
- package/src/engine/chart.ts +2815 -0
- package/src/engine/controller/__tests__/interaction.dpr.test.ts +259 -0
- package/src/engine/controller/interaction.ts +722 -0
- package/src/engine/controller/markerInteraction.ts +130 -0
- package/src/engine/controller/pinchTracker.ts +82 -0
- package/src/engine/controller/tooltipPosition.ts +48 -0
- package/src/engine/draw/__tests__/pixelAlign.spec.ts +177 -0
- package/src/engine/draw/pixelAlign.ts +260 -0
- package/src/engine/drawing/index.ts +655 -0
- package/src/engine/drawing/interaction.ts +842 -0
- package/src/engine/drawing/plugin.ts +343 -0
- package/src/engine/indicators/__tests__/__fixtures__/golden/atr.json +38 -0
- package/src/engine/indicators/__tests__/__fixtures__/golden/dema.json +14 -0
- package/src/engine/indicators/__tests__/__fixtures__/golden/hma.json +14 -0
- package/src/engine/indicators/__tests__/__fixtures__/golden/index.ts +55 -0
- package/src/engine/indicators/__tests__/__fixtures__/golden/kama.json +14 -0
- package/src/engine/indicators/__tests__/__fixtures__/golden/tema.json +14 -0
- package/src/engine/indicators/__tests__/__fixtures__/golden/wma.json +40 -0
- package/src/engine/indicators/__tests__/__fixtures__/synthetic.ts +65 -0
- package/src/engine/indicators/__tests__/_propertyAssertions.ts +76 -0
- package/src/engine/indicators/__tests__/atr.test.ts +153 -0
- package/src/engine/indicators/__tests__/calculators.test.ts +614 -0
- package/src/engine/indicators/__tests__/cmf-mfi.test.ts +100 -0
- package/src/engine/indicators/__tests__/dema.test.ts +73 -0
- package/src/engine/indicators/__tests__/donchian.test.ts +70 -0
- package/src/engine/indicators/__tests__/hma.test.ts +73 -0
- package/src/engine/indicators/__tests__/ichimoku.test.ts +105 -0
- package/src/engine/indicators/__tests__/kama.test.ts +80 -0
- package/src/engine/indicators/__tests__/keltner.test.ts +65 -0
- package/src/engine/indicators/__tests__/pivot-fib.test.ts +110 -0
- package/src/engine/indicators/__tests__/roc.test.ts +68 -0
- package/src/engine/indicators/__tests__/sar.test.ts +86 -0
- package/src/engine/indicators/__tests__/scheduler.test.ts +831 -0
- package/src/engine/indicators/__tests__/soa.test.ts +533 -0
- package/src/engine/indicators/__tests__/structure.test.ts +110 -0
- package/src/engine/indicators/__tests__/supertrend.test.ts +65 -0
- package/src/engine/indicators/__tests__/tema.test.ts +68 -0
- package/src/engine/indicators/__tests__/trix.test.ts +70 -0
- package/src/engine/indicators/__tests__/volatility.test.ts +117 -0
- package/src/engine/indicators/__tests__/volume.test.ts +115 -0
- package/src/engine/indicators/__tests__/volumeProfile.test.ts +74 -0
- package/src/engine/indicators/__tests__/vwap.test.ts +69 -0
- package/src/engine/indicators/__tests__/wma.test.ts +112 -0
- package/src/engine/indicators/__tests__/zones.test.ts +95 -0
- package/src/engine/indicators/atrState.ts +27 -0
- package/src/engine/indicators/bollState.ts +51 -0
- package/src/engine/indicators/calculators.ts +2593 -0
- package/src/engine/indicators/cciState.ts +25 -0
- package/src/engine/indicators/chaikinVolState.ts +32 -0
- package/src/engine/indicators/cmfState.ts +27 -0
- package/src/engine/indicators/demaState.ts +27 -0
- package/src/engine/indicators/donchianState.ts +43 -0
- package/src/engine/indicators/eneState.ts +43 -0
- package/src/engine/indicators/expmaState.ts +43 -0
- package/src/engine/indicators/fastkState.ts +25 -0
- package/src/engine/indicators/fibState.ts +41 -0
- package/src/engine/indicators/hmaState.ts +27 -0
- package/src/engine/indicators/hvState.ts +28 -0
- package/src/engine/indicators/ichimokuState.ts +70 -0
- package/src/engine/indicators/indicator.worker.ts +169 -0
- package/src/engine/indicators/indicatorDefinitionRegistry.ts +62 -0
- package/src/engine/indicators/indicatorMetadata.ts +110 -0
- package/src/engine/indicators/indicatorRegistry.ts +106 -0
- package/src/engine/indicators/indicatorRuntime.ts +1548 -0
- package/src/engine/indicators/kamaState.ts +34 -0
- package/src/engine/indicators/keltnerState.ts +49 -0
- package/src/engine/indicators/kstState.ts +42 -0
- package/src/engine/indicators/maState.ts +36 -0
- package/src/engine/indicators/macdState.ts +76 -0
- package/src/engine/indicators/mfiState.ts +27 -0
- package/src/engine/indicators/momState.ts +25 -0
- package/src/engine/indicators/obvState.ts +25 -0
- package/src/engine/indicators/parkinsonState.ts +28 -0
- package/src/engine/indicators/pivotState.ts +51 -0
- package/src/engine/indicators/pvtState.ts +25 -0
- package/src/engine/indicators/rocState.ts +27 -0
- package/src/engine/indicators/rsiState.ts +65 -0
- package/src/engine/indicators/sarState.ts +41 -0
- package/src/engine/indicators/scheduler.ts +1205 -0
- package/src/engine/indicators/soa.ts +352 -0
- package/src/engine/indicators/stateComposer.ts +1262 -0
- package/src/engine/indicators/stochState.ts +26 -0
- package/src/engine/indicators/structureState.ts +69 -0
- package/src/engine/indicators/supertrendState.ts +37 -0
- package/src/engine/indicators/temaState.ts +27 -0
- package/src/engine/indicators/trixState.ts +35 -0
- package/src/engine/indicators/vmaState.ts +27 -0
- package/src/engine/indicators/volumeProfileState.ts +63 -0
- package/src/engine/indicators/vwapState.ts +29 -0
- package/src/engine/indicators/wmaState.ts +27 -0
- package/src/engine/indicators/wmsrState.ts +25 -0
- package/src/engine/indicators/workerProtocol.ts +613 -0
- package/src/engine/indicators/zonesState.ts +47 -0
- package/src/engine/layout/pane.ts +161 -0
- package/src/engine/marker/registry.ts +266 -0
- package/src/engine/paneRenderer.ts +169 -0
- package/src/engine/renderers/Indicator/atr.ts +237 -0
- package/src/engine/renderers/Indicator/boll.ts +317 -0
- package/src/engine/renderers/Indicator/cci.ts +275 -0
- package/src/engine/renderers/Indicator/chaikinVol.ts +138 -0
- package/src/engine/renderers/Indicator/cmf.ts +137 -0
- package/src/engine/renderers/Indicator/dema.ts +136 -0
- package/src/engine/renderers/Indicator/donchian.ts +138 -0
- package/src/engine/renderers/Indicator/ene.ts +271 -0
- package/src/engine/renderers/Indicator/expma.ts +197 -0
- package/src/engine/renderers/Indicator/fastk.ts +316 -0
- package/src/engine/renderers/Indicator/fib.ts +141 -0
- package/src/engine/renderers/Indicator/hma.ts +136 -0
- package/src/engine/renderers/Indicator/hv.ts +124 -0
- package/src/engine/renderers/Indicator/ichimoku.ts +182 -0
- package/src/engine/renderers/Indicator/index.ts +241 -0
- package/src/engine/renderers/Indicator/indicatorData.ts +650 -0
- package/src/engine/renderers/Indicator/kama.ts +136 -0
- package/src/engine/renderers/Indicator/keltner.ts +138 -0
- package/src/engine/renderers/Indicator/kst.ts +302 -0
- package/src/engine/renderers/Indicator/ma.ts +200 -0
- package/src/engine/renderers/Indicator/macd.ts +477 -0
- package/src/engine/renderers/Indicator/macdLegend.ts +141 -0
- package/src/engine/renderers/Indicator/mainIndicatorLegend.ts +272 -0
- package/src/engine/renderers/Indicator/mfi.ts +142 -0
- package/src/engine/renderers/Indicator/mom.ts +311 -0
- package/src/engine/renderers/Indicator/obv.ts +123 -0
- package/src/engine/renderers/Indicator/parkinson.ts +124 -0
- package/src/engine/renderers/Indicator/pivot.ts +131 -0
- package/src/engine/renderers/Indicator/pvt.ts +123 -0
- package/src/engine/renderers/Indicator/roc.ts +143 -0
- package/src/engine/renderers/Indicator/rsi.ts +390 -0
- package/src/engine/renderers/Indicator/sar.ts +113 -0
- package/src/engine/renderers/Indicator/scale/atr_scale.ts +19 -0
- package/src/engine/renderers/Indicator/scale/cci_scale.ts +19 -0
- package/src/engine/renderers/Indicator/scale/fastk_scale.ts +19 -0
- package/src/engine/renderers/Indicator/scale/indicator_scale.ts +204 -0
- package/src/engine/renderers/Indicator/scale/kst_scale.ts +19 -0
- package/src/engine/renderers/Indicator/scale/macd_scale.ts +22 -0
- package/src/engine/renderers/Indicator/scale/mom_scale.ts +19 -0
- package/src/engine/renderers/Indicator/scale/rsi_scale.ts +19 -0
- package/src/engine/renderers/Indicator/scale/stoch_scale.ts +19 -0
- package/src/engine/renderers/Indicator/scale/volume_scale.ts +26 -0
- package/src/engine/renderers/Indicator/scale/wmsr_scale.ts +19 -0
- package/src/engine/renderers/Indicator/stoch.ts +359 -0
- package/src/engine/renderers/Indicator/structure.ts +126 -0
- package/src/engine/renderers/Indicator/subPaneConfig.ts +265 -0
- package/src/engine/renderers/Indicator/supertrend.ts +115 -0
- package/src/engine/renderers/Indicator/tema.ts +136 -0
- package/src/engine/renderers/Indicator/trix.ts +158 -0
- package/src/engine/renderers/Indicator/vma.ts +124 -0
- package/src/engine/renderers/Indicator/volumeProfile.ts +125 -0
- package/src/engine/renderers/Indicator/vwap.ts +123 -0
- package/src/engine/renderers/Indicator/wma.ts +136 -0
- package/src/engine/renderers/Indicator/wmsr.ts +328 -0
- package/src/engine/renderers/Indicator/zones.ts +105 -0
- package/src/engine/renderers/__tests__/boll.renderer.test.ts +314 -0
- package/src/engine/renderers/__tests__/ene.renderer.test.ts +305 -0
- package/src/engine/renderers/__tests__/expma.renderer.test.ts +279 -0
- package/src/engine/renderers/__tests__/ma.renderer.test.ts +426 -0
- package/src/engine/renderers/__tests__/mainIndicatorLegend.renderer.test.ts +502 -0
- package/src/engine/renderers/__tests__/yAxis.renderer.test.ts +173 -0
- package/src/engine/renderers/candle.ts +459 -0
- package/src/engine/renderers/crosshair.ts +69 -0
- package/src/engine/renderers/customMarkers.ts +162 -0
- package/src/engine/renderers/extremaMarkers.ts +246 -0
- package/src/engine/renderers/gridLines.ts +90 -0
- package/src/engine/renderers/lastPrice.ts +97 -0
- package/src/engine/renderers/paneTitle.ts +136 -0
- package/src/engine/renderers/subVolume.ts +236 -0
- package/src/engine/renderers/timeAxis.ts +121 -0
- package/src/engine/renderers/webgl/candleSurface.ts +955 -0
- package/src/engine/renderers/webgl/sharedWebGLSurface.ts +146 -0
- package/src/engine/renderers/yAxis.ts +105 -0
- package/src/engine/scale/__tests__/logFormula.spec.ts +148 -0
- package/src/engine/scale/logFormula.ts +130 -0
- package/src/engine/scale/price.ts +39 -0
- package/src/engine/scale/priceScale.ts +264 -0
- package/src/engine/subPaneManager.ts +427 -0
- package/src/engine/theme/colors.ts +642 -0
- package/src/engine/theme/fonts.ts +20 -0
- package/src/engine/utils/klineConfig.ts +49 -0
- package/src/engine/utils/tickCount.ts +11 -0
- package/src/engine/utils/tickPosition.ts +214 -0
- package/src/engine/utils/zoom.ts +83 -0
- package/src/engine/viewport/viewport.ts +67 -0
- package/src/index.ts +3 -0
- package/src/plugin/ConfigManager.ts +93 -0
- package/src/plugin/EventBus.ts +77 -0
- package/src/plugin/HookSystem.ts +106 -0
- package/src/plugin/PluginHost.ts +243 -0
- package/src/plugin/PluginRegistry.ts +92 -0
- package/src/plugin/StateStore.ts +73 -0
- package/src/plugin/index.ts +19 -0
- package/src/plugin/rendererPluginManager.ts +368 -0
- package/src/plugin/stateKeys.ts +8 -0
- package/src/plugin/types.ts +526 -0
- package/src/reactivity/index.ts +2 -0
- package/src/reactivity/signal.ts +119 -0
- package/src/semantic/controller.ts +251 -0
- package/src/semantic/drawShape.ts +260 -0
- package/src/semantic/index.ts +28 -0
- package/src/semantic/schema.json +256 -0
- package/src/semantic/types.ts +251 -0
- package/src/semantic/validator.ts +349 -0
- package/src/types/kLine.ts +13 -0
- package/src/types/price.ts +56 -0
- package/src/types/volumePrice.ts +33 -0
- package/src/utils/dateFormat.ts +208 -0
- package/src/utils/kLineDraw/axis.ts +562 -0
- package/src/utils/priceToY.ts +34 -0
- package/src/utils/volumePrice.ts +203 -0
- package/src/version.ts +1 -0
|
@@ -0,0 +1,1882 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 默认 MA 周期列表
|
|
3
|
+
*/
|
|
4
|
+
export const DEFAULT_MA_PERIODS = [5, 10, 20, 30, 60];
|
|
5
|
+
/**
|
|
6
|
+
* 默认 BOLL 参数
|
|
7
|
+
*/
|
|
8
|
+
export const DEFAULT_BOLL_PERIOD = 20;
|
|
9
|
+
export const DEFAULT_BOLL_MULTIPLIER = 2;
|
|
10
|
+
/**
|
|
11
|
+
* 计算 BOLL 数据(使用滑动窗口优化)
|
|
12
|
+
* @param data K线数据数组
|
|
13
|
+
* @param period 周期(默认20)
|
|
14
|
+
* @param multiplier 标准差倍数(默认2)
|
|
15
|
+
* @returns 每个索引对应的BOLL值,前 period-1 个为 undefined
|
|
16
|
+
*/
|
|
17
|
+
export function calcBOLLData(data, period, multiplier) {
|
|
18
|
+
const result = new Array(data.length);
|
|
19
|
+
if (data.length < period)
|
|
20
|
+
return result;
|
|
21
|
+
// 使用滑动窗口计算,避免重复求和
|
|
22
|
+
let sum = 0;
|
|
23
|
+
const window = [];
|
|
24
|
+
// 初始化第一个窗口
|
|
25
|
+
for (let i = 0; i < period; i++) {
|
|
26
|
+
const item = data[i];
|
|
27
|
+
if (!item)
|
|
28
|
+
return result;
|
|
29
|
+
const close = item.close;
|
|
30
|
+
window.push(close);
|
|
31
|
+
sum += close;
|
|
32
|
+
}
|
|
33
|
+
// 计算每个点的 BOLL
|
|
34
|
+
for (let i = period - 1; i < data.length; i++) {
|
|
35
|
+
const item = data[i];
|
|
36
|
+
if (!item)
|
|
37
|
+
continue;
|
|
38
|
+
// 更新窗口求和
|
|
39
|
+
if (i >= period) {
|
|
40
|
+
const oldVal = window.shift();
|
|
41
|
+
if (oldVal !== undefined)
|
|
42
|
+
sum -= oldVal;
|
|
43
|
+
const close = item.close;
|
|
44
|
+
window.push(close);
|
|
45
|
+
sum += close;
|
|
46
|
+
}
|
|
47
|
+
const ma = sum / period;
|
|
48
|
+
// 计算标准差
|
|
49
|
+
let variance = 0;
|
|
50
|
+
for (let j = 0; j < period; j++) {
|
|
51
|
+
const wVal = window[j];
|
|
52
|
+
if (wVal !== undefined) {
|
|
53
|
+
variance += Math.pow(wVal - ma, 2);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
const stdDev = Math.sqrt(variance / period);
|
|
57
|
+
result[i] = {
|
|
58
|
+
upper: ma + multiplier * stdDev,
|
|
59
|
+
middle: ma,
|
|
60
|
+
lower: ma - multiplier * stdDev,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
return result;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* 默认 EXPMA 参数
|
|
67
|
+
*/
|
|
68
|
+
export const DEFAULT_EXPMA_FAST_PERIOD = 12;
|
|
69
|
+
export const DEFAULT_EXPMA_SLOW_PERIOD = 50;
|
|
70
|
+
/**
|
|
71
|
+
* 计算 EXPMA 数据
|
|
72
|
+
* 公式:EXPMA(i) = C(i) × K + EXPMA(i-1) × (1-K),K = 2/(N+1)
|
|
73
|
+
* @param data K线数据数组
|
|
74
|
+
* @param fastPeriod 快线周期(默认12)
|
|
75
|
+
* @param slowPeriod 慢线周期(默认50)
|
|
76
|
+
* @returns 每个索引对应的EXPMA值(从 index 0 开始有值)
|
|
77
|
+
*/
|
|
78
|
+
export function calcEXPMAData(data, fastPeriod, slowPeriod) {
|
|
79
|
+
const result = new Array(data.length);
|
|
80
|
+
if (data.length === 0)
|
|
81
|
+
return result;
|
|
82
|
+
const fastK = 2 / (fastPeriod + 1);
|
|
83
|
+
const slowK = 2 / (slowPeriod + 1);
|
|
84
|
+
// 第一个点的 EXPMA 等于第一天的收盘价
|
|
85
|
+
const firstClose = data[0].close;
|
|
86
|
+
let fastEMA = firstClose;
|
|
87
|
+
let slowEMA = firstClose;
|
|
88
|
+
result[0] = { fast: fastEMA, slow: slowEMA };
|
|
89
|
+
for (let i = 1; i < data.length; i++) {
|
|
90
|
+
const close = data[i].close;
|
|
91
|
+
fastEMA = close * fastK + fastEMA * (1 - fastK);
|
|
92
|
+
slowEMA = close * slowK + slowEMA * (1 - slowK);
|
|
93
|
+
result[i] = { fast: fastEMA, slow: slowEMA };
|
|
94
|
+
}
|
|
95
|
+
return result;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* 默认 ENE 参数
|
|
99
|
+
*/
|
|
100
|
+
export const DEFAULT_ENE_PERIOD = 10;
|
|
101
|
+
export const DEFAULT_ENE_DEVIATION = 11;
|
|
102
|
+
/**
|
|
103
|
+
* 计算 ENE 数据
|
|
104
|
+
* 中轨 = MA(close, N)
|
|
105
|
+
* 上轨 = 中轨 × (1 + M/100)
|
|
106
|
+
* 下轨 = 中轨 × (1 - M/100)
|
|
107
|
+
* @param data K线数据数组
|
|
108
|
+
* @param period 周期(默认10)
|
|
109
|
+
* @param deviation 偏离率百分比(默认11)
|
|
110
|
+
* @returns 每个索引对应的ENE值,前 period-1 个为 undefined
|
|
111
|
+
*/
|
|
112
|
+
export function calcENEData(data, period, deviation) {
|
|
113
|
+
const result = new Array(data.length);
|
|
114
|
+
if (data.length < period)
|
|
115
|
+
return result;
|
|
116
|
+
// 使用滑动窗口计算 MA
|
|
117
|
+
let sum = 0;
|
|
118
|
+
// 初始化第一个窗口
|
|
119
|
+
for (let i = 0; i < period; i++) {
|
|
120
|
+
const item = data[i];
|
|
121
|
+
if (!item)
|
|
122
|
+
return result;
|
|
123
|
+
sum += item.close;
|
|
124
|
+
}
|
|
125
|
+
// 第一个有效点
|
|
126
|
+
const firstMA = sum / period;
|
|
127
|
+
const firstDeviation = deviation / 100;
|
|
128
|
+
result[period - 1] = {
|
|
129
|
+
upper: firstMA * (1 + firstDeviation),
|
|
130
|
+
middle: firstMA,
|
|
131
|
+
lower: firstMA * (1 - firstDeviation),
|
|
132
|
+
};
|
|
133
|
+
// 滑动计算后续点
|
|
134
|
+
for (let i = period; i < data.length; i++) {
|
|
135
|
+
const prevItem = data[i - period];
|
|
136
|
+
const currItem = data[i];
|
|
137
|
+
if (!prevItem || !currItem)
|
|
138
|
+
continue;
|
|
139
|
+
sum = sum - prevItem.close + currItem.close;
|
|
140
|
+
const ma = sum / period;
|
|
141
|
+
const dev = deviation / 100;
|
|
142
|
+
result[i] = {
|
|
143
|
+
upper: ma * (1 + dev),
|
|
144
|
+
middle: ma,
|
|
145
|
+
lower: ma * (1 - dev),
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
return result;
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* 计算指定周期的 MA 数据(使用滑动窗口优化,O(n) 复杂度)
|
|
152
|
+
* @param data K线数据数组
|
|
153
|
+
* @param period MA周期
|
|
154
|
+
* @returns 每个索引对应的MA值,前 period-1 个为 undefined
|
|
155
|
+
*/
|
|
156
|
+
export function calcMAData(data, period) {
|
|
157
|
+
const result = new Array(data.length);
|
|
158
|
+
if (data.length < period)
|
|
159
|
+
return result;
|
|
160
|
+
// 滑动窗口求和
|
|
161
|
+
let sum = 0;
|
|
162
|
+
// 初始化第一个窗口
|
|
163
|
+
for (let i = 0; i < period; i++) {
|
|
164
|
+
const item = data[i];
|
|
165
|
+
if (!item)
|
|
166
|
+
return result;
|
|
167
|
+
sum += item.close;
|
|
168
|
+
}
|
|
169
|
+
// 第一个有效点
|
|
170
|
+
result[period - 1] = sum / period;
|
|
171
|
+
// 滑动计算后续点
|
|
172
|
+
for (let i = period; i < data.length; i++) {
|
|
173
|
+
const prevItem = data[i - period];
|
|
174
|
+
const currItem = data[i];
|
|
175
|
+
if (!prevItem || !currItem)
|
|
176
|
+
continue;
|
|
177
|
+
sum = sum - prevItem.close + currItem.close;
|
|
178
|
+
result[i] = sum / period;
|
|
179
|
+
}
|
|
180
|
+
return result;
|
|
181
|
+
}
|
|
182
|
+
// ============================================================================
|
|
183
|
+
// RSI 相对强弱指标
|
|
184
|
+
// ============================================================================
|
|
185
|
+
/**
|
|
186
|
+
* 默认 RSI 参数
|
|
187
|
+
*/
|
|
188
|
+
export const DEFAULT_RSI_PERIOD1 = 6;
|
|
189
|
+
export const DEFAULT_RSI_PERIOD2 = 12;
|
|
190
|
+
export const DEFAULT_RSI_PERIOD3 = 24;
|
|
191
|
+
export const DEFAULT_RSI_PERIODS = [6, 12, 24];
|
|
192
|
+
/**
|
|
193
|
+
* 计算 RSI 数据
|
|
194
|
+
* RSI = 100 - 100 / (1 + RS)
|
|
195
|
+
* RS = 平均上涨幅度 / 平均下跌幅度
|
|
196
|
+
* @param data K线数据数组
|
|
197
|
+
* @param period RSI周期
|
|
198
|
+
* @returns 每个索引对应的RSI值,前 period+1 个为 undefined(需要 period+1 个数据点计算初始平均)
|
|
199
|
+
*/
|
|
200
|
+
export function calcRSIData(data, period) {
|
|
201
|
+
const result = new Array(data.length);
|
|
202
|
+
if (data.length < period + 1)
|
|
203
|
+
return result;
|
|
204
|
+
// 计算价格变化
|
|
205
|
+
const changes = [];
|
|
206
|
+
for (let i = 1; i < data.length; i++) {
|
|
207
|
+
changes.push(data[i].close - data[i - 1].close);
|
|
208
|
+
}
|
|
209
|
+
// 初始化:计算前 period 天的平均涨跌
|
|
210
|
+
let sumGain = 0;
|
|
211
|
+
let sumLoss = 0;
|
|
212
|
+
for (let i = 0; i < period; i++) {
|
|
213
|
+
const change = changes[i];
|
|
214
|
+
if (change !== undefined) {
|
|
215
|
+
if (change > 0)
|
|
216
|
+
sumGain += change;
|
|
217
|
+
else
|
|
218
|
+
sumLoss += Math.abs(change);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
// 第一个 RSI 值
|
|
222
|
+
let avgGain = sumGain / period;
|
|
223
|
+
let avgLoss = sumLoss / period;
|
|
224
|
+
if (avgLoss === 0) {
|
|
225
|
+
result[period] = 100;
|
|
226
|
+
}
|
|
227
|
+
else {
|
|
228
|
+
const rs = avgGain / avgLoss;
|
|
229
|
+
result[period] = 100 - 100 / (1 + rs);
|
|
230
|
+
}
|
|
231
|
+
// 后续使用平滑计算(Wilder's smoothing)
|
|
232
|
+
for (let i = period; i < changes.length; i++) {
|
|
233
|
+
const change = changes[i];
|
|
234
|
+
if (change === undefined)
|
|
235
|
+
continue;
|
|
236
|
+
if (change > 0) {
|
|
237
|
+
avgGain = (avgGain * (period - 1) + change) / period;
|
|
238
|
+
avgLoss = (avgLoss * (period - 1)) / period;
|
|
239
|
+
}
|
|
240
|
+
else {
|
|
241
|
+
avgGain = (avgGain * (period - 1)) / period;
|
|
242
|
+
avgLoss = (avgLoss * (period - 1) + Math.abs(change)) / period;
|
|
243
|
+
}
|
|
244
|
+
if (avgLoss === 0) {
|
|
245
|
+
result[i + 1] = 100;
|
|
246
|
+
}
|
|
247
|
+
else {
|
|
248
|
+
const rs = avgGain / avgLoss;
|
|
249
|
+
result[i + 1] = 100 - 100 / (1 + rs);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
return result;
|
|
253
|
+
}
|
|
254
|
+
// ============================================================================
|
|
255
|
+
// CCI 顺势指标
|
|
256
|
+
// ============================================================================
|
|
257
|
+
export const DEFAULT_CCI_PERIOD = 14;
|
|
258
|
+
export function calcCCIData(data, period) {
|
|
259
|
+
const result = new Array(data.length);
|
|
260
|
+
if (data.length < period)
|
|
261
|
+
return result;
|
|
262
|
+
// 计算 TP (Typical Price) = (H + L + C) / 3
|
|
263
|
+
const tpValues = [];
|
|
264
|
+
for (const item of data) {
|
|
265
|
+
tpValues.push((item.high + item.low + item.close) / 3);
|
|
266
|
+
}
|
|
267
|
+
// 计算 TP 的 SMA
|
|
268
|
+
let sum = 0;
|
|
269
|
+
for (let i = 0; i < period; i++) {
|
|
270
|
+
sum += tpValues[i];
|
|
271
|
+
}
|
|
272
|
+
for (let i = period - 1; i < data.length; i++) {
|
|
273
|
+
if (i >= period) {
|
|
274
|
+
sum = sum - tpValues[i - period] + tpValues[i];
|
|
275
|
+
}
|
|
276
|
+
const sma = sum / period;
|
|
277
|
+
// 计算平均绝对偏差
|
|
278
|
+
let meanDeviation = 0;
|
|
279
|
+
for (let j = 0; j < period; j++) {
|
|
280
|
+
meanDeviation += Math.abs(tpValues[i - j] - sma);
|
|
281
|
+
}
|
|
282
|
+
meanDeviation /= period;
|
|
283
|
+
if (meanDeviation === 0) {
|
|
284
|
+
result[i] = 0;
|
|
285
|
+
}
|
|
286
|
+
else {
|
|
287
|
+
result[i] = (tpValues[i] - sma) / (0.015 * meanDeviation);
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
return result;
|
|
291
|
+
}
|
|
292
|
+
// ============================================================================
|
|
293
|
+
// STOCH 随机指标
|
|
294
|
+
// ============================================================================
|
|
295
|
+
export const DEFAULT_STOCH_N = 9;
|
|
296
|
+
export const DEFAULT_STOCH_M = 3;
|
|
297
|
+
export function calcSTOCHData(data, n, m) {
|
|
298
|
+
const result = new Array(data.length);
|
|
299
|
+
if (data.length < n)
|
|
300
|
+
return result;
|
|
301
|
+
// 计算 RSV 和 K
|
|
302
|
+
const kValues = new Array(data.length);
|
|
303
|
+
for (let i = n - 1; i < data.length; i++) {
|
|
304
|
+
let highest = -Infinity;
|
|
305
|
+
let lowest = Infinity;
|
|
306
|
+
for (let j = 0; j < n; j++) {
|
|
307
|
+
const item = data[i - j];
|
|
308
|
+
if (!item)
|
|
309
|
+
continue;
|
|
310
|
+
highest = Math.max(highest, item.high);
|
|
311
|
+
lowest = Math.min(lowest, item.low);
|
|
312
|
+
}
|
|
313
|
+
const close = data[i].close;
|
|
314
|
+
if (highest === lowest) {
|
|
315
|
+
kValues[i] = 50;
|
|
316
|
+
}
|
|
317
|
+
else {
|
|
318
|
+
kValues[i] = ((close - lowest) / (highest - lowest)) * 100;
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
// 计算 D (K 的 M 日移动平均)
|
|
322
|
+
for (let i = n - 1 + m - 1; i < data.length; i++) {
|
|
323
|
+
const k = kValues[i];
|
|
324
|
+
if (k === undefined)
|
|
325
|
+
continue;
|
|
326
|
+
let sum = 0;
|
|
327
|
+
let validCount = 0;
|
|
328
|
+
for (let j = 0; j < m; j++) {
|
|
329
|
+
const kv = kValues[i - j];
|
|
330
|
+
if (kv !== undefined) {
|
|
331
|
+
sum += kv;
|
|
332
|
+
validCount++;
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
if (validCount === m) {
|
|
336
|
+
result[i] = { k, d: sum / m };
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
return result;
|
|
340
|
+
}
|
|
341
|
+
// ============================================================================
|
|
342
|
+
// MOM 动量指标
|
|
343
|
+
// ============================================================================
|
|
344
|
+
export const DEFAULT_MOM_PERIOD = 10;
|
|
345
|
+
export function calcMOMData(data, period) {
|
|
346
|
+
const result = new Array(data.length);
|
|
347
|
+
if (data.length < period + 1)
|
|
348
|
+
return result;
|
|
349
|
+
for (let i = period; i < data.length; i++) {
|
|
350
|
+
const currentClose = data[i]?.close;
|
|
351
|
+
const prevClose = data[i - period]?.close;
|
|
352
|
+
if (currentClose !== undefined && prevClose !== undefined) {
|
|
353
|
+
result[i] = currentClose - prevClose;
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
return result;
|
|
357
|
+
}
|
|
358
|
+
// ============================================================================
|
|
359
|
+
// WMSR 威廉指标
|
|
360
|
+
// ============================================================================
|
|
361
|
+
export const DEFAULT_WMSR_PERIOD = 14;
|
|
362
|
+
export function calcWMSRData(data, period) {
|
|
363
|
+
const result = new Array(data.length);
|
|
364
|
+
if (data.length < period)
|
|
365
|
+
return result;
|
|
366
|
+
for (let i = period - 1; i < data.length; i++) {
|
|
367
|
+
let highest = -Infinity;
|
|
368
|
+
let lowest = Infinity;
|
|
369
|
+
for (let j = 0; j < period; j++) {
|
|
370
|
+
const item = data[i - j];
|
|
371
|
+
if (!item)
|
|
372
|
+
continue;
|
|
373
|
+
highest = Math.max(highest, item.high);
|
|
374
|
+
lowest = Math.min(lowest, item.low);
|
|
375
|
+
}
|
|
376
|
+
const close = data[i].close;
|
|
377
|
+
if (highest === lowest) {
|
|
378
|
+
result[i] = -50;
|
|
379
|
+
}
|
|
380
|
+
else {
|
|
381
|
+
result[i] = ((highest - close) / (highest - lowest)) * -100;
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
return result;
|
|
385
|
+
}
|
|
386
|
+
// ============================================================================
|
|
387
|
+
// KST 确知指标
|
|
388
|
+
// ============================================================================
|
|
389
|
+
export const DEFAULT_KST_ROC1 = 10;
|
|
390
|
+
export const DEFAULT_KST_ROC2 = 15;
|
|
391
|
+
export const DEFAULT_KST_ROC3 = 20;
|
|
392
|
+
export const DEFAULT_KST_ROC4 = 30;
|
|
393
|
+
export const DEFAULT_KST_SIGNAL = 9;
|
|
394
|
+
function calcROCInternal(data, period) {
|
|
395
|
+
const result = new Array(data.length);
|
|
396
|
+
if (data.length < period + 1)
|
|
397
|
+
return result;
|
|
398
|
+
for (let i = period; i < data.length; i++) {
|
|
399
|
+
const currentClose = data[i]?.close;
|
|
400
|
+
const prevClose = data[i - period]?.close;
|
|
401
|
+
if (currentClose !== undefined && prevClose !== undefined && prevClose !== 0) {
|
|
402
|
+
result[i] = ((currentClose - prevClose) / prevClose) * 100;
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
return result;
|
|
406
|
+
}
|
|
407
|
+
function calcSMAInternal(data, period) {
|
|
408
|
+
const result = new Array(data.length);
|
|
409
|
+
let sum = 0;
|
|
410
|
+
let count = 0;
|
|
411
|
+
for (let i = 0; i < data.length; i++) {
|
|
412
|
+
const val = data[i];
|
|
413
|
+
if (val !== undefined) {
|
|
414
|
+
sum += val;
|
|
415
|
+
count++;
|
|
416
|
+
if (count > period) {
|
|
417
|
+
const oldVal = data[i - period];
|
|
418
|
+
if (oldVal !== undefined) {
|
|
419
|
+
sum -= oldVal;
|
|
420
|
+
count--;
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
if (count === period) {
|
|
424
|
+
result[i] = sum / period;
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
return result;
|
|
429
|
+
}
|
|
430
|
+
export function calcKSTData(data, roc1, roc2, roc3, roc4, signalPeriod) {
|
|
431
|
+
const result = new Array(data.length);
|
|
432
|
+
const roc1Data = calcROCInternal(data, roc1);
|
|
433
|
+
const roc2Data = calcROCInternal(data, roc2);
|
|
434
|
+
const roc3Data = calcROCInternal(data, roc3);
|
|
435
|
+
const roc4Data = calcROCInternal(data, roc4);
|
|
436
|
+
const sma1 = calcSMAInternal(roc1Data, 10);
|
|
437
|
+
const sma2 = calcSMAInternal(roc2Data, 10);
|
|
438
|
+
const sma3 = calcSMAInternal(roc3Data, 10);
|
|
439
|
+
const sma4 = calcSMAInternal(roc4Data, 15);
|
|
440
|
+
const kstValues = new Array(data.length);
|
|
441
|
+
for (let i = 0; i < data.length; i++) {
|
|
442
|
+
const v1 = sma1[i];
|
|
443
|
+
const v2 = sma2[i];
|
|
444
|
+
const v3 = sma3[i];
|
|
445
|
+
const v4 = sma4[i];
|
|
446
|
+
if (v1 !== undefined && v2 !== undefined && v3 !== undefined && v4 !== undefined) {
|
|
447
|
+
kstValues[i] = v1 * 1 + v2 * 2 + v3 * 3 + v4 * 4;
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
const signalData = calcSMAInternal(kstValues, signalPeriod);
|
|
451
|
+
for (let i = 0; i < data.length; i++) {
|
|
452
|
+
const kst = kstValues[i];
|
|
453
|
+
const signal = signalData[i];
|
|
454
|
+
if (kst !== undefined && signal !== undefined) {
|
|
455
|
+
result[i] = { kst, signal };
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
return result;
|
|
459
|
+
}
|
|
460
|
+
// ============================================================================
|
|
461
|
+
// FASTK 快速随机指标
|
|
462
|
+
// ============================================================================
|
|
463
|
+
export const DEFAULT_FASTK_PERIOD = 9;
|
|
464
|
+
export function calcFASTKData(data, period) {
|
|
465
|
+
const result = new Array(data.length);
|
|
466
|
+
if (data.length < period)
|
|
467
|
+
return result;
|
|
468
|
+
for (let i = period - 1; i < data.length; i++) {
|
|
469
|
+
let highest = -Infinity;
|
|
470
|
+
let lowest = Infinity;
|
|
471
|
+
for (let j = 0; j < period; j++) {
|
|
472
|
+
const item = data[i - j];
|
|
473
|
+
if (!item)
|
|
474
|
+
continue;
|
|
475
|
+
highest = Math.max(highest, item.high);
|
|
476
|
+
lowest = Math.min(lowest, item.low);
|
|
477
|
+
}
|
|
478
|
+
const close = data[i].close;
|
|
479
|
+
if (highest === lowest) {
|
|
480
|
+
result[i] = 50;
|
|
481
|
+
}
|
|
482
|
+
else {
|
|
483
|
+
result[i] = ((close - lowest) / (highest - lowest)) * 100;
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
return result;
|
|
487
|
+
}
|
|
488
|
+
/**
|
|
489
|
+
* 默认 MACD 参数
|
|
490
|
+
*/
|
|
491
|
+
export const DEFAULT_MACD_FAST_PERIOD = 12;
|
|
492
|
+
export const DEFAULT_MACD_SLOW_PERIOD = 26;
|
|
493
|
+
export const DEFAULT_MACD_SIGNAL_PERIOD = 9;
|
|
494
|
+
/**
|
|
495
|
+
* 计算 EMA(指数移动平均)值
|
|
496
|
+
* EMA(today) = close × K + EMA(yesterday) × (1 - K)
|
|
497
|
+
* K = 2 / (period + 1)
|
|
498
|
+
* @param data K线数据数组
|
|
499
|
+
* @param period 周期
|
|
500
|
+
* @returns EMA 值数组,第一个值使用第一个收盘价
|
|
501
|
+
*/
|
|
502
|
+
export function calcEMA(data, period) {
|
|
503
|
+
const result = new Array(data.length);
|
|
504
|
+
const k = 2 / (period + 1);
|
|
505
|
+
if (data.length === 0)
|
|
506
|
+
return result;
|
|
507
|
+
// 第一个 EMA 值使用第一个收盘价
|
|
508
|
+
result[0] = data[0].close;
|
|
509
|
+
for (let i = 1; i < data.length; i++) {
|
|
510
|
+
const item = data[i];
|
|
511
|
+
if (!item)
|
|
512
|
+
continue;
|
|
513
|
+
result[i] = item.close * k + result[i - 1] * (1 - k);
|
|
514
|
+
}
|
|
515
|
+
return result;
|
|
516
|
+
}
|
|
517
|
+
/**
|
|
518
|
+
* 基于数值数组计算 EMA
|
|
519
|
+
* @param values 数值数组(可能包含 undefined)
|
|
520
|
+
* @param period 周期
|
|
521
|
+
* @returns EMA 值数组
|
|
522
|
+
*/
|
|
523
|
+
export function calcEMAFromArray(values, period) {
|
|
524
|
+
const result = new Array(values.length);
|
|
525
|
+
const k = 2 / (period + 1);
|
|
526
|
+
const firstValid = values.findIndex(v => v !== undefined);
|
|
527
|
+
if (firstValid === -1)
|
|
528
|
+
return result;
|
|
529
|
+
result[firstValid] = values[firstValid];
|
|
530
|
+
for (let i = firstValid + 1; i < values.length; i++) {
|
|
531
|
+
const val = values[i];
|
|
532
|
+
const prev = result[i - 1];
|
|
533
|
+
if (val === undefined || prev === undefined)
|
|
534
|
+
continue;
|
|
535
|
+
result[i] = val * k + prev * (1 - k);
|
|
536
|
+
}
|
|
537
|
+
return result;
|
|
538
|
+
}
|
|
539
|
+
/**
|
|
540
|
+
* 计算 MACD 数据
|
|
541
|
+
* DIF = EMA(close, fastPeriod) - EMA(close, slowPeriod)
|
|
542
|
+
* DEA = EMA(DIF, signalPeriod)
|
|
543
|
+
* MACD = (DIF - DEA) × 2
|
|
544
|
+
* @param data K线数据数组
|
|
545
|
+
* @param fastPeriod 快线周期(默认12)
|
|
546
|
+
* @param slowPeriod 慢线周期(默认26)
|
|
547
|
+
* @param signalPeriod 信号线周期(默认9)
|
|
548
|
+
* @returns MACD 数据点数组,前 slowPeriod-1 个可能为 undefined
|
|
549
|
+
*/
|
|
550
|
+
export function calcMACDData(data, fastPeriod, slowPeriod, signalPeriod) {
|
|
551
|
+
const result = new Array(data.length);
|
|
552
|
+
if (data.length < slowPeriod)
|
|
553
|
+
return result;
|
|
554
|
+
// 计算 EMA12 和 EMA26
|
|
555
|
+
const emaFast = calcEMA(data, fastPeriod);
|
|
556
|
+
const emaSlow = calcEMA(data, slowPeriod);
|
|
557
|
+
// 计算 DIF
|
|
558
|
+
const dif = new Array(data.length);
|
|
559
|
+
for (let i = 0; i < data.length; i++) {
|
|
560
|
+
const fast = emaFast[i];
|
|
561
|
+
const slow = emaSlow[i];
|
|
562
|
+
if (fast !== undefined && slow !== undefined) {
|
|
563
|
+
dif[i] = fast - slow;
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
// 计算 DEA(DIF 的 signalPeriod 日 EMA)
|
|
567
|
+
const dea = calcEMAFromArray(dif, signalPeriod);
|
|
568
|
+
// 计算 MACD 柱
|
|
569
|
+
for (let i = 0; i < data.length; i++) {
|
|
570
|
+
const d = dif[i];
|
|
571
|
+
const e = dea[i];
|
|
572
|
+
if (d !== undefined && e !== undefined) {
|
|
573
|
+
result[i] = {
|
|
574
|
+
dif: d,
|
|
575
|
+
dea: e,
|
|
576
|
+
macd: (d - e) * 2,
|
|
577
|
+
};
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
return result;
|
|
581
|
+
}
|
|
582
|
+
import { SharedKLineBuffer } from './soa';
|
|
583
|
+
/**
|
|
584
|
+
* 从 SoA 布局计算 BOLL 数据(验证用包装函数)
|
|
585
|
+
* @param layout SoA 布局
|
|
586
|
+
* @param period 周期
|
|
587
|
+
* @param multiplier 标准差倍数
|
|
588
|
+
* @returns BOLL 数据点数组
|
|
589
|
+
*/
|
|
590
|
+
export function calcBOLLDataSoA(layout, period, multiplier) {
|
|
591
|
+
const data = SharedKLineBuffer.toKLineData(layout);
|
|
592
|
+
return calcBOLLData(data, period, multiplier);
|
|
593
|
+
}
|
|
594
|
+
/**
|
|
595
|
+
* 从 SoA 布局计算 EXPMA 数据(验证用包装函数)
|
|
596
|
+
* @param layout SoA 布局
|
|
597
|
+
* @param fastPeriod 快线周期
|
|
598
|
+
* @param slowPeriod 慢线周期
|
|
599
|
+
* @returns EXPMA 数据点数组
|
|
600
|
+
*/
|
|
601
|
+
export function calcEXPMADataSoA(layout, fastPeriod, slowPeriod) {
|
|
602
|
+
const data = SharedKLineBuffer.toKLineData(layout);
|
|
603
|
+
return calcEXPMAData(data, fastPeriod, slowPeriod);
|
|
604
|
+
}
|
|
605
|
+
/**
|
|
606
|
+
* 从 SoA 布局计算 ENE 数据(验证用包装函数)
|
|
607
|
+
* @param layout SoA 布局
|
|
608
|
+
* @param period 周期
|
|
609
|
+
* @param deviation 偏离率百分比
|
|
610
|
+
* @returns ENE 数据点数组
|
|
611
|
+
*/
|
|
612
|
+
export function calcENEDataSoA(layout, period, deviation) {
|
|
613
|
+
const data = SharedKLineBuffer.toKLineData(layout);
|
|
614
|
+
return calcENEData(data, period, deviation);
|
|
615
|
+
}
|
|
616
|
+
/**
|
|
617
|
+
* 从 SoA 布局计算 MA 数据(验证用包装函数)
|
|
618
|
+
* @param layout SoA 布局
|
|
619
|
+
* @param period MA周期
|
|
620
|
+
* @returns MA 值数组
|
|
621
|
+
*/
|
|
622
|
+
export function calcMADataSoA(layout, period) {
|
|
623
|
+
const data = SharedKLineBuffer.toKLineData(layout);
|
|
624
|
+
return calcMAData(data, period);
|
|
625
|
+
}
|
|
626
|
+
/**
|
|
627
|
+
* 从 SoA 布局计算 RSI 数据(验证用包装函数)
|
|
628
|
+
* @param layout SoA 布局
|
|
629
|
+
* @param period RSI周期
|
|
630
|
+
* @returns RSI 值数组
|
|
631
|
+
*/
|
|
632
|
+
export function calcRSIDataSoA(layout, period) {
|
|
633
|
+
const data = SharedKLineBuffer.toKLineData(layout);
|
|
634
|
+
return calcRSIData(data, period);
|
|
635
|
+
}
|
|
636
|
+
/**
|
|
637
|
+
* 从 SoA 布局计算 CCI 数据(验证用包装函数)
|
|
638
|
+
* @param layout SoA 布局
|
|
639
|
+
* @param period 周期
|
|
640
|
+
* @returns CCI 值数组
|
|
641
|
+
*/
|
|
642
|
+
export function calcCCIDataSoA(layout, period) {
|
|
643
|
+
const data = SharedKLineBuffer.toKLineData(layout);
|
|
644
|
+
return calcCCIData(data, period);
|
|
645
|
+
}
|
|
646
|
+
/**
|
|
647
|
+
* 从 SoA 布局计算 STOCH 数据(验证用包装函数)
|
|
648
|
+
* @param layout SoA 布局
|
|
649
|
+
* @param n RSV周期
|
|
650
|
+
* @param m K的M日移动平均周期
|
|
651
|
+
* @returns STOCH 数据点数组
|
|
652
|
+
*/
|
|
653
|
+
export function calcSTOCHDataSoA(layout, n, m) {
|
|
654
|
+
const data = SharedKLineBuffer.toKLineData(layout);
|
|
655
|
+
return calcSTOCHData(data, n, m);
|
|
656
|
+
}
|
|
657
|
+
/**
|
|
658
|
+
* 从 SoA 布局计算 MOM 数据(验证用包装函数)
|
|
659
|
+
* @param layout SoA 布局
|
|
660
|
+
* @param period 周期
|
|
661
|
+
* @returns MOM 值数组
|
|
662
|
+
*/
|
|
663
|
+
export function calcMOMDataSoA(layout, period) {
|
|
664
|
+
const data = SharedKLineBuffer.toKLineData(layout);
|
|
665
|
+
return calcMOMData(data, period);
|
|
666
|
+
}
|
|
667
|
+
/**
|
|
668
|
+
* 从 SoA 布局计算 WMSR 数据(验证用包装函数)
|
|
669
|
+
* @param layout SoA 布局
|
|
670
|
+
* @param period 周期
|
|
671
|
+
* @returns WMSR 值数组
|
|
672
|
+
*/
|
|
673
|
+
export function calcWMSRDataSoA(layout, period) {
|
|
674
|
+
const data = SharedKLineBuffer.toKLineData(layout);
|
|
675
|
+
return calcWMSRData(data, period);
|
|
676
|
+
}
|
|
677
|
+
/**
|
|
678
|
+
* 从 SoA 布局计算 KST 数据(验证用包装函数)
|
|
679
|
+
* @param layout SoA 布局
|
|
680
|
+
* @param roc1 第一个ROC周期
|
|
681
|
+
* @param roc2 第二个ROC周期
|
|
682
|
+
* @param roc3 第三个ROC周期
|
|
683
|
+
* @param roc4 第四个ROC周期
|
|
684
|
+
* @param signalPeriod 信号线周期
|
|
685
|
+
* @returns KST 数据点数组
|
|
686
|
+
*/
|
|
687
|
+
export function calcKSTDataSoA(layout, roc1, roc2, roc3, roc4, signalPeriod) {
|
|
688
|
+
const data = SharedKLineBuffer.toKLineData(layout);
|
|
689
|
+
return calcKSTData(data, roc1, roc2, roc3, roc4, signalPeriod);
|
|
690
|
+
}
|
|
691
|
+
/**
|
|
692
|
+
* 从 SoA 布局计算 FASTK 数据(验证用包装函数)
|
|
693
|
+
* @param layout SoA 布局
|
|
694
|
+
* @param period 周期
|
|
695
|
+
* @returns FASTK 值数组
|
|
696
|
+
*/
|
|
697
|
+
export function calcFASTKDataSoA(layout, period) {
|
|
698
|
+
const data = SharedKLineBuffer.toKLineData(layout);
|
|
699
|
+
return calcFASTKData(data, period);
|
|
700
|
+
}
|
|
701
|
+
/**
|
|
702
|
+
* 从 SoA 布局计算 MACD 数据(验证用包装函数)
|
|
703
|
+
* @param layout SoA 布局
|
|
704
|
+
* @param fastPeriod 快线周期
|
|
705
|
+
* @param slowPeriod 慢线周期
|
|
706
|
+
* @param signalPeriod 信号线周期
|
|
707
|
+
* @returns MACD 数据点数组
|
|
708
|
+
*/
|
|
709
|
+
export function calcMACDDataSoA(layout, fastPeriod, slowPeriod, signalPeriod) {
|
|
710
|
+
const data = SharedKLineBuffer.toKLineData(layout);
|
|
711
|
+
return calcMACDData(data, fastPeriod, slowPeriod, signalPeriod);
|
|
712
|
+
}
|
|
713
|
+
// ============================================================================
|
|
714
|
+
// ATR — Wilder's Average True Range
|
|
715
|
+
// ============================================================================
|
|
716
|
+
export const DEFAULT_ATR_PERIOD = 14;
|
|
717
|
+
/**
|
|
718
|
+
* 计算 Wilder ATR。
|
|
719
|
+
* TR(0) = H(0) - L(0)
|
|
720
|
+
* TR(t) = max(H(t) - L(t), |H(t) - C(t-1)|, |L(t) - C(t-1)|)
|
|
721
|
+
* ATR(period-1) = mean(TR[0..period-1])
|
|
722
|
+
* ATR(t) = ((period-1) * ATR(t-1) + TR(t)) / period for t >= period
|
|
723
|
+
*
|
|
724
|
+
* @param data K 线数组
|
|
725
|
+
* @param period 周期,需 >= 1;若 <= 0 或 data.length < period,返回全 undefined
|
|
726
|
+
*/
|
|
727
|
+
export function calcATRData(data, period) {
|
|
728
|
+
const n = data.length;
|
|
729
|
+
const result = new Array(n).fill(undefined);
|
|
730
|
+
if (n === 0 || period <= 0)
|
|
731
|
+
return result;
|
|
732
|
+
if (period === 1) {
|
|
733
|
+
const first = data[0];
|
|
734
|
+
result[0] = first.high - first.low;
|
|
735
|
+
let prevClose = first.close;
|
|
736
|
+
for (let i = 1; i < n; i++) {
|
|
737
|
+
const cur = data[i];
|
|
738
|
+
const tr = Math.max(cur.high - cur.low, Math.abs(cur.high - prevClose), Math.abs(cur.low - prevClose));
|
|
739
|
+
result[i] = tr;
|
|
740
|
+
prevClose = cur.close;
|
|
741
|
+
}
|
|
742
|
+
return result;
|
|
743
|
+
}
|
|
744
|
+
if (n < period)
|
|
745
|
+
return result;
|
|
746
|
+
const first = data[0];
|
|
747
|
+
let sumTR = first.high - first.low;
|
|
748
|
+
let prevClose = first.close;
|
|
749
|
+
for (let i = 1; i < period; i++) {
|
|
750
|
+
const cur = data[i];
|
|
751
|
+
sumTR += Math.max(cur.high - cur.low, Math.abs(cur.high - prevClose), Math.abs(cur.low - prevClose));
|
|
752
|
+
prevClose = cur.close;
|
|
753
|
+
}
|
|
754
|
+
let atr = sumTR / period;
|
|
755
|
+
result[period - 1] = atr;
|
|
756
|
+
const periodMinusOne = period - 1;
|
|
757
|
+
for (let i = period; i < n; i++) {
|
|
758
|
+
const cur = data[i];
|
|
759
|
+
const tr = Math.max(cur.high - cur.low, Math.abs(cur.high - prevClose), Math.abs(cur.low - prevClose));
|
|
760
|
+
atr = (periodMinusOne * atr + tr) / period;
|
|
761
|
+
result[i] = atr;
|
|
762
|
+
prevClose = cur.close;
|
|
763
|
+
}
|
|
764
|
+
return result;
|
|
765
|
+
}
|
|
766
|
+
/**
|
|
767
|
+
* 从 SoA 布局计算 ATR(包装函数,对齐其他指标的 SoA 入口)
|
|
768
|
+
*/
|
|
769
|
+
export function calcATRDataSoA(layout, period) {
|
|
770
|
+
const data = SharedKLineBuffer.toKLineData(layout);
|
|
771
|
+
return calcATRData(data, period);
|
|
772
|
+
}
|
|
773
|
+
// ============================================================================
|
|
774
|
+
// WMA — Weighted Moving Average (linear weights)
|
|
775
|
+
// 权重: w_i = i (i=1..period),分母 = period*(period+1)/2
|
|
776
|
+
// 滞后 = (period-1)/3 (相比 SMA 更快响应)
|
|
777
|
+
// ============================================================================
|
|
778
|
+
export const DEFAULT_WMA_PERIOD = 9;
|
|
779
|
+
function _computeWMAOnNumbers(values, period) {
|
|
780
|
+
const n = values.length;
|
|
781
|
+
const result = new Array(n).fill(undefined);
|
|
782
|
+
if (n === 0 || period <= 0 || n < period)
|
|
783
|
+
return result;
|
|
784
|
+
const denom = (period * (period + 1)) / 2;
|
|
785
|
+
for (let t = period - 1; t < n; t++) {
|
|
786
|
+
let sw = 0;
|
|
787
|
+
let valid = true;
|
|
788
|
+
for (let k = 0; k < period; k++) {
|
|
789
|
+
const v = values[t - period + 1 + k];
|
|
790
|
+
if (v === undefined) {
|
|
791
|
+
valid = false;
|
|
792
|
+
break;
|
|
793
|
+
}
|
|
794
|
+
sw += (k + 1) * v;
|
|
795
|
+
}
|
|
796
|
+
if (valid)
|
|
797
|
+
result[t] = sw / denom;
|
|
798
|
+
}
|
|
799
|
+
return result;
|
|
800
|
+
}
|
|
801
|
+
export function calcWMAData(data, period) {
|
|
802
|
+
if (data.length === 0 || period <= 0) {
|
|
803
|
+
return new Array(data.length).fill(undefined);
|
|
804
|
+
}
|
|
805
|
+
const closes = new Array(data.length);
|
|
806
|
+
for (let i = 0; i < data.length; i++)
|
|
807
|
+
closes[i] = data[i].close;
|
|
808
|
+
return _computeWMAOnNumbers(closes, period);
|
|
809
|
+
}
|
|
810
|
+
export function calcWMADataSoA(layout, period) {
|
|
811
|
+
const data = SharedKLineBuffer.toKLineData(layout);
|
|
812
|
+
return calcWMAData(data, period);
|
|
813
|
+
}
|
|
814
|
+
// ============================================================================
|
|
815
|
+
// EMA helper(DEMA / TEMA 复用,沿用 EXPMA 的 first-close seed 习惯)
|
|
816
|
+
// alpha = 2 / (period + 1)
|
|
817
|
+
// ============================================================================
|
|
818
|
+
function _computeEMASeries(values, period) {
|
|
819
|
+
const n = values.length;
|
|
820
|
+
const result = new Array(n).fill(undefined);
|
|
821
|
+
if (n === 0 || period <= 0)
|
|
822
|
+
return result;
|
|
823
|
+
const alpha = 2 / (period + 1);
|
|
824
|
+
let i = 0;
|
|
825
|
+
while (i < n && values[i] === undefined)
|
|
826
|
+
i++;
|
|
827
|
+
if (i >= n)
|
|
828
|
+
return result;
|
|
829
|
+
let ema = values[i];
|
|
830
|
+
result[i] = ema;
|
|
831
|
+
for (let t = i + 1; t < n; t++) {
|
|
832
|
+
const v = values[t];
|
|
833
|
+
if (v === undefined)
|
|
834
|
+
continue;
|
|
835
|
+
ema = v * alpha + ema * (1 - alpha);
|
|
836
|
+
result[t] = ema;
|
|
837
|
+
}
|
|
838
|
+
return result;
|
|
839
|
+
}
|
|
840
|
+
// ============================================================================
|
|
841
|
+
// DEMA — Double Exponential Moving Average
|
|
842
|
+
// 公式: DEMA(t) = 2*EMA(t) - EMA(EMA)(t)
|
|
843
|
+
// 性质: 对线性输入零滞后(稳态),warmup ~ 2*(period-1)
|
|
844
|
+
// ============================================================================
|
|
845
|
+
export const DEFAULT_DEMA_PERIOD = 20;
|
|
846
|
+
export function calcDEMAData(data, period) {
|
|
847
|
+
const n = data.length;
|
|
848
|
+
const result = new Array(n).fill(undefined);
|
|
849
|
+
if (n === 0 || period <= 0)
|
|
850
|
+
return result;
|
|
851
|
+
const closes = new Array(n);
|
|
852
|
+
for (let i = 0; i < n; i++)
|
|
853
|
+
closes[i] = data[i].close;
|
|
854
|
+
const ema1 = _computeEMASeries(closes, period);
|
|
855
|
+
const ema2 = _computeEMASeries(ema1, period);
|
|
856
|
+
for (let i = 0; i < n; i++) {
|
|
857
|
+
const e1 = ema1[i];
|
|
858
|
+
const e2 = ema2[i];
|
|
859
|
+
if (e1 === undefined || e2 === undefined)
|
|
860
|
+
continue;
|
|
861
|
+
result[i] = 2 * e1 - e2;
|
|
862
|
+
}
|
|
863
|
+
return result;
|
|
864
|
+
}
|
|
865
|
+
export function calcDEMADataSoA(layout, period) {
|
|
866
|
+
const data = SharedKLineBuffer.toKLineData(layout);
|
|
867
|
+
return calcDEMAData(data, period);
|
|
868
|
+
}
|
|
869
|
+
// ============================================================================
|
|
870
|
+
// TEMA — Triple Exponential Moving Average
|
|
871
|
+
// 公式: TEMA(t) = 3*EMA(t) - 3*EMA(EMA)(t) + EMA(EMA(EMA))(t)
|
|
872
|
+
// 性质: 对二次多项式输入零滞后(稳态),warmup ~ 3*(period-1)
|
|
873
|
+
// ============================================================================
|
|
874
|
+
export const DEFAULT_TEMA_PERIOD = 20;
|
|
875
|
+
export function calcTEMAData(data, period) {
|
|
876
|
+
const n = data.length;
|
|
877
|
+
const result = new Array(n).fill(undefined);
|
|
878
|
+
if (n === 0 || period <= 0)
|
|
879
|
+
return result;
|
|
880
|
+
const closes = new Array(n);
|
|
881
|
+
for (let i = 0; i < n; i++)
|
|
882
|
+
closes[i] = data[i].close;
|
|
883
|
+
const ema1 = _computeEMASeries(closes, period);
|
|
884
|
+
const ema2 = _computeEMASeries(ema1, period);
|
|
885
|
+
const ema3 = _computeEMASeries(ema2, period);
|
|
886
|
+
for (let i = 0; i < n; i++) {
|
|
887
|
+
const e1 = ema1[i];
|
|
888
|
+
const e2 = ema2[i];
|
|
889
|
+
const e3 = ema3[i];
|
|
890
|
+
if (e1 === undefined || e2 === undefined || e3 === undefined)
|
|
891
|
+
continue;
|
|
892
|
+
result[i] = 3 * e1 - 3 * e2 + e3;
|
|
893
|
+
}
|
|
894
|
+
return result;
|
|
895
|
+
}
|
|
896
|
+
export function calcTEMADataSoA(layout, period) {
|
|
897
|
+
const data = SharedKLineBuffer.toKLineData(layout);
|
|
898
|
+
return calcTEMAData(data, period);
|
|
899
|
+
}
|
|
900
|
+
// ============================================================================
|
|
901
|
+
// HMA — Hull Moving Average
|
|
902
|
+
// 公式: HMA(n) = WMA( 2*WMA(close, n/2) - WMA(close, n), sqrt(n) )
|
|
903
|
+
// 性质: 平滑性高于 WMA,滞后远低于同期 SMA
|
|
904
|
+
// warmup ≈ period - 1 + round(sqrt(period)) - 1
|
|
905
|
+
// ============================================================================
|
|
906
|
+
export const DEFAULT_HMA_PERIOD = 9;
|
|
907
|
+
export function calcHMAData(data, period) {
|
|
908
|
+
const n = data.length;
|
|
909
|
+
const result = new Array(n).fill(undefined);
|
|
910
|
+
if (n === 0 || period <= 0)
|
|
911
|
+
return result;
|
|
912
|
+
const closes = new Array(n);
|
|
913
|
+
for (let i = 0; i < n; i++)
|
|
914
|
+
closes[i] = data[i].close;
|
|
915
|
+
const halfPeriod = Math.max(1, Math.floor(period / 2));
|
|
916
|
+
const sqrtPeriod = Math.max(1, Math.round(Math.sqrt(period)));
|
|
917
|
+
const wmaHalf = _computeWMAOnNumbers(closes, halfPeriod);
|
|
918
|
+
const wmaFull = _computeWMAOnNumbers(closes, period);
|
|
919
|
+
const raw = new Array(n).fill(undefined);
|
|
920
|
+
for (let i = 0; i < n; i++) {
|
|
921
|
+
const h = wmaHalf[i];
|
|
922
|
+
const f = wmaFull[i];
|
|
923
|
+
if (h === undefined || f === undefined)
|
|
924
|
+
continue;
|
|
925
|
+
raw[i] = 2 * h - f;
|
|
926
|
+
}
|
|
927
|
+
return _computeWMAOnNumbers(raw, sqrtPeriod);
|
|
928
|
+
}
|
|
929
|
+
export function calcHMADataSoA(layout, period) {
|
|
930
|
+
const data = SharedKLineBuffer.toKLineData(layout);
|
|
931
|
+
return calcHMAData(data, period);
|
|
932
|
+
}
|
|
933
|
+
// ============================================================================
|
|
934
|
+
// KAMA — Kaufman's Adaptive Moving Average
|
|
935
|
+
// 自适应:在趋势强时跟得紧(接近 fast EMA),在震荡时跟得慢(接近 slow EMA)。
|
|
936
|
+
// ER (efficiency ratio) = |close[t] - close[t-n]| / sum(|close[i] - close[i-1]|, i=t-n+1..t)
|
|
937
|
+
// SC = (ER * (2/(fast+1) - 2/(slow+1)) + 2/(slow+1))^2
|
|
938
|
+
// KAMA(t) = KAMA(t-1) + SC * (close[t] - KAMA(t-1))
|
|
939
|
+
// 种子 KAMA(n-1) = close[n-1](或 SMA(n);这里采用 close 种子以保持与项目内 EMA 系列一致)
|
|
940
|
+
// ============================================================================
|
|
941
|
+
export const DEFAULT_KAMA_PERIOD = 10;
|
|
942
|
+
export const DEFAULT_KAMA_FAST_PERIOD = 2;
|
|
943
|
+
export const DEFAULT_KAMA_SLOW_PERIOD = 30;
|
|
944
|
+
export function calcKAMAData(data, period, fastPeriod, slowPeriod) {
|
|
945
|
+
const n = data.length;
|
|
946
|
+
const result = new Array(n).fill(undefined);
|
|
947
|
+
if (n === 0 || period <= 0 || fastPeriod <= 0 || slowPeriod <= 0 || n <= period)
|
|
948
|
+
return result;
|
|
949
|
+
const fastSC = 2 / (fastPeriod + 1);
|
|
950
|
+
const slowSC = 2 / (slowPeriod + 1);
|
|
951
|
+
const scRange = fastSC - slowSC;
|
|
952
|
+
// 维护滚动求和:sum(|close[i] - close[i-1]|, i=t-period+1..t)
|
|
953
|
+
let volSum = 0;
|
|
954
|
+
for (let i = 1; i <= period; i++) {
|
|
955
|
+
volSum += Math.abs(data[i].close - data[i - 1].close);
|
|
956
|
+
}
|
|
957
|
+
let kama = data[period - 1].close;
|
|
958
|
+
result[period - 1] = kama;
|
|
959
|
+
for (let t = period; t < n; t++) {
|
|
960
|
+
const close = data[t].close;
|
|
961
|
+
const closeNPeriodsAgo = data[t - period].close;
|
|
962
|
+
const direction = Math.abs(close - closeNPeriodsAgo);
|
|
963
|
+
const er = volSum > 0 ? direction / volSum : 0;
|
|
964
|
+
const sc = (er * scRange + slowSC) ** 2;
|
|
965
|
+
kama = kama + sc * (close - kama);
|
|
966
|
+
result[t] = kama;
|
|
967
|
+
// 滚动 volSum:减去最旧的 |close[t-period+1] - close[t-period]|,加上最新的 |close[t+1] - close[t]|
|
|
968
|
+
if (t < n - 1) {
|
|
969
|
+
volSum -= Math.abs(data[t - period + 1].close - data[t - period].close);
|
|
970
|
+
volSum += Math.abs(data[t + 1].close - data[t].close);
|
|
971
|
+
}
|
|
972
|
+
}
|
|
973
|
+
return result;
|
|
974
|
+
}
|
|
975
|
+
export function calcKAMADataSoA(layout, period, fastPeriod, slowPeriod) {
|
|
976
|
+
const data = SharedKLineBuffer.toKLineData(layout);
|
|
977
|
+
return calcKAMAData(data, period, fastPeriod, slowPeriod);
|
|
978
|
+
}
|
|
979
|
+
export const DEFAULT_SAR_STEP = 0.02;
|
|
980
|
+
export const DEFAULT_SAR_MAX_STEP = 0.2;
|
|
981
|
+
export function calcSARData(data, step, maxStep) {
|
|
982
|
+
const n = data.length;
|
|
983
|
+
const result = new Array(n).fill(undefined);
|
|
984
|
+
if (n < 2 || step <= 0 || maxStep <= 0)
|
|
985
|
+
return result;
|
|
986
|
+
let trend = data[1].close >= data[0].close ? 'up' : 'down';
|
|
987
|
+
let sar = trend === 'up' ? data[0].low : data[0].high;
|
|
988
|
+
let ep = trend === 'up' ? data[0].high : data[0].low;
|
|
989
|
+
let af = step;
|
|
990
|
+
result[0] = { value: sar, trend };
|
|
991
|
+
for (let t = 1; t < n; t++) {
|
|
992
|
+
const bar = data[t];
|
|
993
|
+
// 先按当前趋势推进 SAR
|
|
994
|
+
sar = sar + af * (ep - sar);
|
|
995
|
+
// 边界约束:SAR 不能穿透前两根 K 线的极端
|
|
996
|
+
if (trend === 'up') {
|
|
997
|
+
const cap1 = data[t - 1].low;
|
|
998
|
+
const cap2 = t >= 2 ? data[t - 2].low : cap1;
|
|
999
|
+
sar = Math.min(sar, cap1, cap2);
|
|
1000
|
+
}
|
|
1001
|
+
else {
|
|
1002
|
+
const cap1 = data[t - 1].high;
|
|
1003
|
+
const cap2 = t >= 2 ? data[t - 2].high : cap1;
|
|
1004
|
+
sar = Math.max(sar, cap1, cap2);
|
|
1005
|
+
}
|
|
1006
|
+
// 检测翻转
|
|
1007
|
+
if (trend === 'up' && bar.low < sar) {
|
|
1008
|
+
trend = 'down';
|
|
1009
|
+
sar = ep;
|
|
1010
|
+
ep = bar.low;
|
|
1011
|
+
af = step;
|
|
1012
|
+
}
|
|
1013
|
+
else if (trend === 'down' && bar.high > sar) {
|
|
1014
|
+
trend = 'up';
|
|
1015
|
+
sar = ep;
|
|
1016
|
+
ep = bar.high;
|
|
1017
|
+
af = step;
|
|
1018
|
+
}
|
|
1019
|
+
else {
|
|
1020
|
+
// 同趋势:更新 EP / AF
|
|
1021
|
+
if (trend === 'up' && bar.high > ep) {
|
|
1022
|
+
ep = bar.high;
|
|
1023
|
+
af = Math.min(af + step, maxStep);
|
|
1024
|
+
}
|
|
1025
|
+
else if (trend === 'down' && bar.low < ep) {
|
|
1026
|
+
ep = bar.low;
|
|
1027
|
+
af = Math.min(af + step, maxStep);
|
|
1028
|
+
}
|
|
1029
|
+
}
|
|
1030
|
+
result[t] = { value: sar, trend };
|
|
1031
|
+
}
|
|
1032
|
+
return result;
|
|
1033
|
+
}
|
|
1034
|
+
export function calcSARDataSoA(layout, step, maxStep) {
|
|
1035
|
+
const data = SharedKLineBuffer.toKLineData(layout);
|
|
1036
|
+
return calcSARData(data, step, maxStep);
|
|
1037
|
+
}
|
|
1038
|
+
export const DEFAULT_SUPERTREND_ATR_PERIOD = 10;
|
|
1039
|
+
export const DEFAULT_SUPERTREND_MULTIPLIER = 3;
|
|
1040
|
+
export function calcSuperTrendData(data, atrPeriod, multiplier) {
|
|
1041
|
+
const n = data.length;
|
|
1042
|
+
const result = new Array(n).fill(undefined);
|
|
1043
|
+
if (n === 0 || atrPeriod <= 0 || multiplier <= 0)
|
|
1044
|
+
return result;
|
|
1045
|
+
const atr = calcATRData(data, atrPeriod);
|
|
1046
|
+
let trend = 'up';
|
|
1047
|
+
let prevUpper = Infinity;
|
|
1048
|
+
let prevLower = -Infinity;
|
|
1049
|
+
for (let t = 0; t < n; t++) {
|
|
1050
|
+
const bar = data[t];
|
|
1051
|
+
const a = atr[t];
|
|
1052
|
+
if (a === undefined)
|
|
1053
|
+
continue;
|
|
1054
|
+
const hl2 = (bar.high + bar.low) / 2;
|
|
1055
|
+
const upperBasic = hl2 + multiplier * a;
|
|
1056
|
+
const lowerBasic = hl2 - multiplier * a;
|
|
1057
|
+
// Smoothing: keep the previous band unless price has broken through it
|
|
1058
|
+
const prevClose = t > 0 ? data[t - 1].close : bar.close;
|
|
1059
|
+
const upper = (upperBasic < prevUpper || prevClose > prevUpper) ? upperBasic : prevUpper;
|
|
1060
|
+
const lower = (lowerBasic > prevLower || prevClose < prevLower) ? lowerBasic : prevLower;
|
|
1061
|
+
// Trend update
|
|
1062
|
+
if (trend === 'up' && bar.close < lower) {
|
|
1063
|
+
trend = 'down';
|
|
1064
|
+
}
|
|
1065
|
+
else if (trend === 'down' && bar.close > upper) {
|
|
1066
|
+
trend = 'up';
|
|
1067
|
+
}
|
|
1068
|
+
result[t] = { value: trend === 'up' ? lower : upper, trend };
|
|
1069
|
+
prevUpper = upper;
|
|
1070
|
+
prevLower = lower;
|
|
1071
|
+
}
|
|
1072
|
+
return result;
|
|
1073
|
+
}
|
|
1074
|
+
export function calcSuperTrendDataSoA(layout, atrPeriod, multiplier) {
|
|
1075
|
+
const data = SharedKLineBuffer.toKLineData(layout);
|
|
1076
|
+
return calcSuperTrendData(data, atrPeriod, multiplier);
|
|
1077
|
+
}
|
|
1078
|
+
export const DEFAULT_KELTNER_EMA_PERIOD = 20;
|
|
1079
|
+
export const DEFAULT_KELTNER_ATR_PERIOD = 10;
|
|
1080
|
+
export const DEFAULT_KELTNER_MULTIPLIER = 2;
|
|
1081
|
+
export function calcKeltnerData(data, emaPeriod, atrPeriod, multiplier) {
|
|
1082
|
+
const n = data.length;
|
|
1083
|
+
const result = new Array(n).fill(undefined);
|
|
1084
|
+
if (n === 0 || emaPeriod <= 0 || atrPeriod <= 0)
|
|
1085
|
+
return result;
|
|
1086
|
+
const closes = new Array(n);
|
|
1087
|
+
for (let i = 0; i < n; i++)
|
|
1088
|
+
closes[i] = data[i].close;
|
|
1089
|
+
const ema = _computeEMASeries(closes, emaPeriod);
|
|
1090
|
+
const atr = calcATRData(data, atrPeriod);
|
|
1091
|
+
for (let t = 0; t < n; t++) {
|
|
1092
|
+
const m = ema[t];
|
|
1093
|
+
const a = atr[t];
|
|
1094
|
+
if (m === undefined || a === undefined)
|
|
1095
|
+
continue;
|
|
1096
|
+
result[t] = {
|
|
1097
|
+
upper: m + multiplier * a,
|
|
1098
|
+
middle: m,
|
|
1099
|
+
lower: m - multiplier * a,
|
|
1100
|
+
};
|
|
1101
|
+
}
|
|
1102
|
+
return result;
|
|
1103
|
+
}
|
|
1104
|
+
export function calcKeltnerDataSoA(layout, emaPeriod, atrPeriod, multiplier) {
|
|
1105
|
+
const data = SharedKLineBuffer.toKLineData(layout);
|
|
1106
|
+
return calcKeltnerData(data, emaPeriod, atrPeriod, multiplier);
|
|
1107
|
+
}
|
|
1108
|
+
export const DEFAULT_DONCHIAN_PERIOD = 20;
|
|
1109
|
+
export function calcDonchianData(data, period) {
|
|
1110
|
+
const n = data.length;
|
|
1111
|
+
const result = new Array(n).fill(undefined);
|
|
1112
|
+
if (n === 0 || period <= 0 || n < period)
|
|
1113
|
+
return result;
|
|
1114
|
+
for (let t = period - 1; t < n; t++) {
|
|
1115
|
+
let hi = -Infinity;
|
|
1116
|
+
let lo = Infinity;
|
|
1117
|
+
for (let k = 0; k < period; k++) {
|
|
1118
|
+
const bar = data[t - k];
|
|
1119
|
+
if (bar.high > hi)
|
|
1120
|
+
hi = bar.high;
|
|
1121
|
+
if (bar.low < lo)
|
|
1122
|
+
lo = bar.low;
|
|
1123
|
+
}
|
|
1124
|
+
result[t] = { upper: hi, middle: (hi + lo) / 2, lower: lo };
|
|
1125
|
+
}
|
|
1126
|
+
return result;
|
|
1127
|
+
}
|
|
1128
|
+
export function calcDonchianDataSoA(layout, period) {
|
|
1129
|
+
const data = SharedKLineBuffer.toKLineData(layout);
|
|
1130
|
+
return calcDonchianData(data, period);
|
|
1131
|
+
}
|
|
1132
|
+
export const DEFAULT_ICHIMOKU_TENKAN = 9;
|
|
1133
|
+
export const DEFAULT_ICHIMOKU_KIJUN = 26;
|
|
1134
|
+
export const DEFAULT_ICHIMOKU_SPAN_B = 52;
|
|
1135
|
+
export const DEFAULT_ICHIMOKU_DISPLACEMENT = 26;
|
|
1136
|
+
function _rollingMidline(data, period) {
|
|
1137
|
+
const n = data.length;
|
|
1138
|
+
const result = new Array(n).fill(undefined);
|
|
1139
|
+
if (n < period || period <= 0)
|
|
1140
|
+
return result;
|
|
1141
|
+
for (let t = period - 1; t < n; t++) {
|
|
1142
|
+
let hi = -Infinity;
|
|
1143
|
+
let lo = Infinity;
|
|
1144
|
+
for (let k = 0; k < period; k++) {
|
|
1145
|
+
const bar = data[t - k];
|
|
1146
|
+
if (bar.high > hi)
|
|
1147
|
+
hi = bar.high;
|
|
1148
|
+
if (bar.low < lo)
|
|
1149
|
+
lo = bar.low;
|
|
1150
|
+
}
|
|
1151
|
+
result[t] = (hi + lo) / 2;
|
|
1152
|
+
}
|
|
1153
|
+
return result;
|
|
1154
|
+
}
|
|
1155
|
+
export function calcIchimokuData(data, tenkanPeriod, kijunPeriod, spanBPeriod, displacement) {
|
|
1156
|
+
const n = data.length;
|
|
1157
|
+
const result = new Array(n).fill(undefined);
|
|
1158
|
+
if (n === 0 || tenkanPeriod <= 0 || kijunPeriod <= 0 || spanBPeriod <= 0)
|
|
1159
|
+
return result;
|
|
1160
|
+
const tenkan = _rollingMidline(data, tenkanPeriod);
|
|
1161
|
+
const kijun = _rollingMidline(data, kijunPeriod);
|
|
1162
|
+
const spanBSource = _rollingMidline(data, spanBPeriod);
|
|
1163
|
+
for (let t = 0; t < n; t++) {
|
|
1164
|
+
const point = {};
|
|
1165
|
+
if (tenkan[t] !== undefined)
|
|
1166
|
+
point.tenkan = tenkan[t];
|
|
1167
|
+
if (kijun[t] !== undefined)
|
|
1168
|
+
point.kijun = kijun[t];
|
|
1169
|
+
// spanA / spanB 由 displacement 根之前的值填到当前槽位
|
|
1170
|
+
const src = t - displacement;
|
|
1171
|
+
if (src >= 0) {
|
|
1172
|
+
if (tenkan[src] !== undefined && kijun[src] !== undefined) {
|
|
1173
|
+
point.spanA = (tenkan[src] + kijun[src]) / 2;
|
|
1174
|
+
}
|
|
1175
|
+
if (spanBSource[src] !== undefined) {
|
|
1176
|
+
point.spanB = spanBSource[src];
|
|
1177
|
+
}
|
|
1178
|
+
}
|
|
1179
|
+
// chikou:当前 close 后置 displacement 根(即存到 t - displacement 槽位上 close[t])
|
|
1180
|
+
// 这里改成:存当前槽位的 chikou = close[t + displacement],需 future 数据;不可用时 undefined
|
|
1181
|
+
const future = t + displacement;
|
|
1182
|
+
if (future < n)
|
|
1183
|
+
point.chikou = data[future].close;
|
|
1184
|
+
result[t] = point;
|
|
1185
|
+
}
|
|
1186
|
+
return result;
|
|
1187
|
+
}
|
|
1188
|
+
export function calcIchimokuDataSoA(layout, tenkanPeriod, kijunPeriod, spanBPeriod, displacement) {
|
|
1189
|
+
const data = SharedKLineBuffer.toKLineData(layout);
|
|
1190
|
+
return calcIchimokuData(data, tenkanPeriod, kijunPeriod, spanBPeriod, displacement);
|
|
1191
|
+
}
|
|
1192
|
+
// ============================================================================
|
|
1193
|
+
// ROC — Rate of Change
|
|
1194
|
+
// ROC(t) = (close[t] - close[t-period]) / close[t-period] * 100
|
|
1195
|
+
// ============================================================================
|
|
1196
|
+
export const DEFAULT_ROC_PERIOD = 12;
|
|
1197
|
+
export function calcROCData(data, period) {
|
|
1198
|
+
const n = data.length;
|
|
1199
|
+
const result = new Array(n).fill(undefined);
|
|
1200
|
+
if (n === 0 || period <= 0)
|
|
1201
|
+
return result;
|
|
1202
|
+
for (let t = period; t < n; t++) {
|
|
1203
|
+
const prev = data[t - period].close;
|
|
1204
|
+
if (prev === 0)
|
|
1205
|
+
continue;
|
|
1206
|
+
result[t] = (data[t].close - prev) / prev * 100;
|
|
1207
|
+
}
|
|
1208
|
+
return result;
|
|
1209
|
+
}
|
|
1210
|
+
export function calcROCDataSoA(layout, period) {
|
|
1211
|
+
const data = SharedKLineBuffer.toKLineData(layout);
|
|
1212
|
+
return calcROCData(data, period);
|
|
1213
|
+
}
|
|
1214
|
+
export const DEFAULT_TRIX_PERIOD = 15;
|
|
1215
|
+
export const DEFAULT_TRIX_SIGNAL_PERIOD = 9;
|
|
1216
|
+
export function calcTRIXData(data, period, signalPeriod) {
|
|
1217
|
+
const n = data.length;
|
|
1218
|
+
const series = new Array(n).fill(undefined);
|
|
1219
|
+
const signalSeries = new Array(n).fill(undefined);
|
|
1220
|
+
if (n === 0 || period <= 0)
|
|
1221
|
+
return { series, signalSeries };
|
|
1222
|
+
const closes = new Array(n);
|
|
1223
|
+
for (let i = 0; i < n; i++)
|
|
1224
|
+
closes[i] = data[i].close;
|
|
1225
|
+
const ema1 = _computeEMASeries(closes, period);
|
|
1226
|
+
const ema2 = _computeEMASeries(ema1, period);
|
|
1227
|
+
const ema3 = _computeEMASeries(ema2, period);
|
|
1228
|
+
for (let t = 1; t < n; t++) {
|
|
1229
|
+
const cur = ema3[t];
|
|
1230
|
+
const prev = ema3[t - 1];
|
|
1231
|
+
if (cur === undefined || prev === undefined || prev === 0)
|
|
1232
|
+
continue;
|
|
1233
|
+
series[t] = (cur - prev) / prev * 100;
|
|
1234
|
+
}
|
|
1235
|
+
if (signalPeriod > 0) {
|
|
1236
|
+
const smoothed = _computeEMASeries(series, signalPeriod);
|
|
1237
|
+
for (let i = 0; i < n; i++)
|
|
1238
|
+
signalSeries[i] = smoothed[i];
|
|
1239
|
+
}
|
|
1240
|
+
return { series, signalSeries };
|
|
1241
|
+
}
|
|
1242
|
+
export function calcTRIXDataSoA(layout, period, signalPeriod) {
|
|
1243
|
+
const data = SharedKLineBuffer.toKLineData(layout);
|
|
1244
|
+
return calcTRIXData(data, period, signalPeriod);
|
|
1245
|
+
}
|
|
1246
|
+
// ============================================================================
|
|
1247
|
+
// HV — Historical Volatility (close-to-close log returns)
|
|
1248
|
+
// HV(t) = stdDev(log(close[i]/close[i-1]), i=t-period+1..t) * sqrt(annualization)
|
|
1249
|
+
// 输出年化波动率(百分比形式 × 100)
|
|
1250
|
+
// ============================================================================
|
|
1251
|
+
export const DEFAULT_HV_PERIOD = 20;
|
|
1252
|
+
export const DEFAULT_HV_ANNUALIZATION = 252;
|
|
1253
|
+
export function calcHVData(data, period, annualizationFactor) {
|
|
1254
|
+
const n = data.length;
|
|
1255
|
+
const result = new Array(n).fill(undefined);
|
|
1256
|
+
if (n < 2 || period <= 0 || annualizationFactor <= 0)
|
|
1257
|
+
return result;
|
|
1258
|
+
const logReturns = new Array(n);
|
|
1259
|
+
logReturns[0] = 0;
|
|
1260
|
+
for (let t = 1; t < n; t++) {
|
|
1261
|
+
const prev = data[t - 1].close;
|
|
1262
|
+
const cur = data[t].close;
|
|
1263
|
+
logReturns[t] = (prev > 0 && cur > 0) ? Math.log(cur / prev) : 0;
|
|
1264
|
+
}
|
|
1265
|
+
const annScale = Math.sqrt(annualizationFactor);
|
|
1266
|
+
for (let t = period; t < n; t++) {
|
|
1267
|
+
let sum = 0;
|
|
1268
|
+
for (let k = 1; k <= period; k++)
|
|
1269
|
+
sum += logReturns[t - period + k];
|
|
1270
|
+
const mean = sum / period;
|
|
1271
|
+
let varSum = 0;
|
|
1272
|
+
for (let k = 1; k <= period; k++) {
|
|
1273
|
+
const diff = logReturns[t - period + k] - mean;
|
|
1274
|
+
varSum += diff * diff;
|
|
1275
|
+
}
|
|
1276
|
+
const std = Math.sqrt(varSum / (period - 1 > 0 ? period - 1 : 1));
|
|
1277
|
+
result[t] = std * annScale * 100;
|
|
1278
|
+
}
|
|
1279
|
+
return result;
|
|
1280
|
+
}
|
|
1281
|
+
export function calcHVDataSoA(layout, period, annualizationFactor) {
|
|
1282
|
+
const data = SharedKLineBuffer.toKLineData(layout);
|
|
1283
|
+
return calcHVData(data, period, annualizationFactor);
|
|
1284
|
+
}
|
|
1285
|
+
// ============================================================================
|
|
1286
|
+
// Parkinson Volatility — high-low range volatility
|
|
1287
|
+
// PV(t) = sqrt( (1/(4*ln(2))) * mean(ln(high[i]/low[i])^2) * annualization ) * 100
|
|
1288
|
+
// ============================================================================
|
|
1289
|
+
export const DEFAULT_PARKINSON_PERIOD = 20;
|
|
1290
|
+
export const DEFAULT_PARKINSON_ANNUALIZATION = 252;
|
|
1291
|
+
export function calcParkinsonData(data, period, annualizationFactor) {
|
|
1292
|
+
const n = data.length;
|
|
1293
|
+
const result = new Array(n).fill(undefined);
|
|
1294
|
+
if (n === 0 || period <= 0 || annualizationFactor <= 0 || n < period)
|
|
1295
|
+
return result;
|
|
1296
|
+
const factor = 1 / (4 * Math.log(2));
|
|
1297
|
+
const annScale = Math.sqrt(annualizationFactor);
|
|
1298
|
+
const hlLogSq = new Array(n);
|
|
1299
|
+
for (let i = 0; i < n; i++) {
|
|
1300
|
+
const bar = data[i];
|
|
1301
|
+
if (bar.high > 0 && bar.low > 0) {
|
|
1302
|
+
const ln = Math.log(bar.high / bar.low);
|
|
1303
|
+
hlLogSq[i] = ln * ln;
|
|
1304
|
+
}
|
|
1305
|
+
else {
|
|
1306
|
+
hlLogSq[i] = 0;
|
|
1307
|
+
}
|
|
1308
|
+
}
|
|
1309
|
+
for (let t = period - 1; t < n; t++) {
|
|
1310
|
+
let sum = 0;
|
|
1311
|
+
for (let k = 0; k < period; k++)
|
|
1312
|
+
sum += hlLogSq[t - k];
|
|
1313
|
+
const mean = sum / period;
|
|
1314
|
+
result[t] = Math.sqrt(factor * mean) * annScale * 100;
|
|
1315
|
+
}
|
|
1316
|
+
return result;
|
|
1317
|
+
}
|
|
1318
|
+
export function calcParkinsonDataSoA(layout, period, annualizationFactor) {
|
|
1319
|
+
const data = SharedKLineBuffer.toKLineData(layout);
|
|
1320
|
+
return calcParkinsonData(data, period, annualizationFactor);
|
|
1321
|
+
}
|
|
1322
|
+
// ============================================================================
|
|
1323
|
+
// Chaikin Volatility — EMA(high-low) 的 ROC
|
|
1324
|
+
// ChaikinVol(t) = (EMA(H-L, p)[t] - EMA(H-L, p)[t-rocPeriod]) / EMA(H-L, p)[t-rocPeriod] * 100
|
|
1325
|
+
// ============================================================================
|
|
1326
|
+
export const DEFAULT_CHAIKIN_VOL_EMA_PERIOD = 10;
|
|
1327
|
+
export const DEFAULT_CHAIKIN_VOL_ROC_PERIOD = 10;
|
|
1328
|
+
export function calcChaikinVolData(data, emaPeriod, rocPeriod) {
|
|
1329
|
+
const n = data.length;
|
|
1330
|
+
const result = new Array(n).fill(undefined);
|
|
1331
|
+
if (n === 0 || emaPeriod <= 0 || rocPeriod <= 0)
|
|
1332
|
+
return result;
|
|
1333
|
+
const hl = new Array(n);
|
|
1334
|
+
for (let i = 0; i < n; i++)
|
|
1335
|
+
hl[i] = data[i].high - data[i].low;
|
|
1336
|
+
const emaSeries = _computeEMASeries(hl, emaPeriod);
|
|
1337
|
+
for (let t = rocPeriod; t < n; t++) {
|
|
1338
|
+
const cur = emaSeries[t];
|
|
1339
|
+
const prev = emaSeries[t - rocPeriod];
|
|
1340
|
+
if (cur === undefined || prev === undefined || prev === 0)
|
|
1341
|
+
continue;
|
|
1342
|
+
result[t] = (cur - prev) / prev * 100;
|
|
1343
|
+
}
|
|
1344
|
+
return result;
|
|
1345
|
+
}
|
|
1346
|
+
export function calcChaikinVolDataSoA(layout, emaPeriod, rocPeriod) {
|
|
1347
|
+
const data = SharedKLineBuffer.toKLineData(layout);
|
|
1348
|
+
return calcChaikinVolData(data, emaPeriod, rocPeriod);
|
|
1349
|
+
}
|
|
1350
|
+
// ============================================================================
|
|
1351
|
+
// VMA — Volume Moving Average (SMA of volume)
|
|
1352
|
+
// ============================================================================
|
|
1353
|
+
export const DEFAULT_VMA_PERIOD = 5;
|
|
1354
|
+
export function calcVMAData(data, period) {
|
|
1355
|
+
const n = data.length;
|
|
1356
|
+
const result = new Array(n).fill(undefined);
|
|
1357
|
+
if (n === 0 || period <= 0 || n < period)
|
|
1358
|
+
return result;
|
|
1359
|
+
let sum = 0;
|
|
1360
|
+
for (let i = 0; i < period; i++)
|
|
1361
|
+
sum += data[i].volume ?? 0;
|
|
1362
|
+
result[period - 1] = sum / period;
|
|
1363
|
+
for (let t = period; t < n; t++) {
|
|
1364
|
+
sum += (data[t].volume ?? 0) - (data[t - period].volume ?? 0);
|
|
1365
|
+
result[t] = sum / period;
|
|
1366
|
+
}
|
|
1367
|
+
return result;
|
|
1368
|
+
}
|
|
1369
|
+
export function calcVMADataSoA(layout, period) {
|
|
1370
|
+
const data = SharedKLineBuffer.toKLineData(layout);
|
|
1371
|
+
return calcVMAData(data, period);
|
|
1372
|
+
}
|
|
1373
|
+
// ============================================================================
|
|
1374
|
+
// OBV — On Balance Volume (cumulative)
|
|
1375
|
+
// close[t] > close[t-1] → OBV += volume[t]
|
|
1376
|
+
// close[t] < close[t-1] → OBV -= volume[t]
|
|
1377
|
+
// else → OBV unchanged
|
|
1378
|
+
// ============================================================================
|
|
1379
|
+
export function calcOBVData(data) {
|
|
1380
|
+
const n = data.length;
|
|
1381
|
+
const result = new Array(n).fill(undefined);
|
|
1382
|
+
if (n === 0)
|
|
1383
|
+
return result;
|
|
1384
|
+
let obv = 0;
|
|
1385
|
+
result[0] = 0;
|
|
1386
|
+
for (let t = 1; t < n; t++) {
|
|
1387
|
+
const cur = data[t];
|
|
1388
|
+
const prev = data[t - 1];
|
|
1389
|
+
if (cur.close > prev.close)
|
|
1390
|
+
obv += cur.volume ?? 0;
|
|
1391
|
+
else if (cur.close < prev.close)
|
|
1392
|
+
obv -= cur.volume ?? 0;
|
|
1393
|
+
result[t] = obv;
|
|
1394
|
+
}
|
|
1395
|
+
return result;
|
|
1396
|
+
}
|
|
1397
|
+
export function calcOBVDataSoA(layout) {
|
|
1398
|
+
const data = SharedKLineBuffer.toKLineData(layout);
|
|
1399
|
+
return calcOBVData(data);
|
|
1400
|
+
}
|
|
1401
|
+
// ============================================================================
|
|
1402
|
+
// PVT — Price Volume Trend (cumulative)
|
|
1403
|
+
// PVT(t) = PVT(t-1) + ((close[t] - close[t-1]) / close[t-1]) * volume[t]
|
|
1404
|
+
// ============================================================================
|
|
1405
|
+
export function calcPVTData(data) {
|
|
1406
|
+
const n = data.length;
|
|
1407
|
+
const result = new Array(n).fill(undefined);
|
|
1408
|
+
if (n === 0)
|
|
1409
|
+
return result;
|
|
1410
|
+
let pvt = 0;
|
|
1411
|
+
result[0] = 0;
|
|
1412
|
+
for (let t = 1; t < n; t++) {
|
|
1413
|
+
const prevClose = data[t - 1].close;
|
|
1414
|
+
if (prevClose === 0) {
|
|
1415
|
+
result[t] = pvt;
|
|
1416
|
+
continue;
|
|
1417
|
+
}
|
|
1418
|
+
pvt += ((data[t].close - prevClose) / prevClose) * (data[t].volume ?? 0);
|
|
1419
|
+
result[t] = pvt;
|
|
1420
|
+
}
|
|
1421
|
+
return result;
|
|
1422
|
+
}
|
|
1423
|
+
export function calcPVTDataSoA(layout) {
|
|
1424
|
+
const data = SharedKLineBuffer.toKLineData(layout);
|
|
1425
|
+
return calcPVTData(data);
|
|
1426
|
+
}
|
|
1427
|
+
// ============================================================================
|
|
1428
|
+
// VWAP — Volume-Weighted Average Price
|
|
1429
|
+
// VWAP(t) = sum_{i in session} TP(i) * V(i) / sum_{i in session} V(i)
|
|
1430
|
+
// where TP(i) = (H+L+C)/3 (typical price)
|
|
1431
|
+
// Session reset: if sessionResetGapMs > 0, reset cumulative sums when the gap
|
|
1432
|
+
// between consecutive bar timestamps exceeds this value (e.g., overnight)
|
|
1433
|
+
// ============================================================================
|
|
1434
|
+
export const DEFAULT_VWAP_SESSION_GAP_MS = 0;
|
|
1435
|
+
export function calcVWAPData(data, sessionResetGapMs) {
|
|
1436
|
+
const n = data.length;
|
|
1437
|
+
const result = new Array(n).fill(undefined);
|
|
1438
|
+
if (n === 0)
|
|
1439
|
+
return result;
|
|
1440
|
+
let cumPV = 0;
|
|
1441
|
+
let cumV = 0;
|
|
1442
|
+
let prevTs = data[0].timestamp;
|
|
1443
|
+
for (let t = 0; t < n; t++) {
|
|
1444
|
+
const bar = data[t];
|
|
1445
|
+
if (sessionResetGapMs > 0 && t > 0 && bar.timestamp - prevTs > sessionResetGapMs) {
|
|
1446
|
+
cumPV = 0;
|
|
1447
|
+
cumV = 0;
|
|
1448
|
+
}
|
|
1449
|
+
const tp = (bar.high + bar.low + bar.close) / 3;
|
|
1450
|
+
cumPV += tp * (bar.volume ?? 0);
|
|
1451
|
+
cumV += bar.volume ?? 0;
|
|
1452
|
+
result[t] = cumV > 0 ? cumPV / cumV : tp;
|
|
1453
|
+
prevTs = bar.timestamp;
|
|
1454
|
+
}
|
|
1455
|
+
return result;
|
|
1456
|
+
}
|
|
1457
|
+
export function calcVWAPDataSoA(layout, sessionResetGapMs) {
|
|
1458
|
+
const data = SharedKLineBuffer.toKLineData(layout);
|
|
1459
|
+
return calcVWAPData(data, sessionResetGapMs);
|
|
1460
|
+
}
|
|
1461
|
+
// ============================================================================
|
|
1462
|
+
// CMF — Chaikin Money Flow
|
|
1463
|
+
// MFM = ((C-L) - (H-C)) / (H-L) ∈ [-1, 1]
|
|
1464
|
+
// MFV = MFM * Volume
|
|
1465
|
+
// CMF(t) = sum(MFV[t-period+1..t]) / sum(Volume[t-period+1..t]) ∈ [-1, 1]
|
|
1466
|
+
// ============================================================================
|
|
1467
|
+
export const DEFAULT_CMF_PERIOD = 20;
|
|
1468
|
+
export function calcCMFData(data, period) {
|
|
1469
|
+
const n = data.length;
|
|
1470
|
+
const result = new Array(n).fill(undefined);
|
|
1471
|
+
if (n === 0 || period <= 0 || n < period)
|
|
1472
|
+
return result;
|
|
1473
|
+
const mfv = new Array(n);
|
|
1474
|
+
for (let i = 0; i < n; i++) {
|
|
1475
|
+
const bar = data[i];
|
|
1476
|
+
const range = bar.high - bar.low;
|
|
1477
|
+
const mfm = range > 0 ? ((bar.close - bar.low) - (bar.high - bar.close)) / range : 0;
|
|
1478
|
+
mfv[i] = mfm * (bar.volume ?? 0);
|
|
1479
|
+
}
|
|
1480
|
+
let sumMFV = 0;
|
|
1481
|
+
let sumV = 0;
|
|
1482
|
+
for (let i = 0; i < period; i++) {
|
|
1483
|
+
sumMFV += mfv[i];
|
|
1484
|
+
sumV += data[i].volume ?? 0;
|
|
1485
|
+
}
|
|
1486
|
+
result[period - 1] = sumV > 0 ? sumMFV / sumV : 0;
|
|
1487
|
+
for (let t = period; t < n; t++) {
|
|
1488
|
+
sumMFV += mfv[t] - mfv[t - period];
|
|
1489
|
+
sumV += (data[t].volume ?? 0) - (data[t - period].volume ?? 0);
|
|
1490
|
+
result[t] = sumV > 0 ? sumMFV / sumV : 0;
|
|
1491
|
+
}
|
|
1492
|
+
return result;
|
|
1493
|
+
}
|
|
1494
|
+
export function calcCMFDataSoA(layout, period) {
|
|
1495
|
+
const data = SharedKLineBuffer.toKLineData(layout);
|
|
1496
|
+
return calcCMFData(data, period);
|
|
1497
|
+
}
|
|
1498
|
+
// ============================================================================
|
|
1499
|
+
// MFI — Money Flow Index
|
|
1500
|
+
// TP = (H+L+C)/3, RMF = TP * Volume
|
|
1501
|
+
// PMF = sum of RMF where TP > TP[-1]; NMF = sum where TP < TP[-1]
|
|
1502
|
+
// MFR = PMF / NMF; MFI = 100 - 100 / (1 + MFR) ∈ [0, 100]
|
|
1503
|
+
// ============================================================================
|
|
1504
|
+
export const DEFAULT_MFI_PERIOD = 14;
|
|
1505
|
+
export function calcMFIData(data, period) {
|
|
1506
|
+
const n = data.length;
|
|
1507
|
+
const result = new Array(n).fill(undefined);
|
|
1508
|
+
if (n < period + 1 || period <= 0)
|
|
1509
|
+
return result;
|
|
1510
|
+
const tp = new Array(n);
|
|
1511
|
+
for (let i = 0; i < n; i++)
|
|
1512
|
+
tp[i] = (data[i].high + data[i].low + data[i].close) / 3;
|
|
1513
|
+
// Pre-classified positive/negative money flow per bar
|
|
1514
|
+
const pmfArr = new Array(n);
|
|
1515
|
+
const nmfArr = new Array(n);
|
|
1516
|
+
pmfArr[0] = 0;
|
|
1517
|
+
nmfArr[0] = 0;
|
|
1518
|
+
for (let i = 1; i < n; i++) {
|
|
1519
|
+
const rmf = tp[i] * (data[i].volume ?? 0);
|
|
1520
|
+
if (tp[i] > tp[i - 1]) {
|
|
1521
|
+
pmfArr[i] = rmf;
|
|
1522
|
+
nmfArr[i] = 0;
|
|
1523
|
+
}
|
|
1524
|
+
else if (tp[i] < tp[i - 1]) {
|
|
1525
|
+
pmfArr[i] = 0;
|
|
1526
|
+
nmfArr[i] = rmf;
|
|
1527
|
+
}
|
|
1528
|
+
else {
|
|
1529
|
+
pmfArr[i] = 0;
|
|
1530
|
+
nmfArr[i] = 0;
|
|
1531
|
+
}
|
|
1532
|
+
}
|
|
1533
|
+
let pSum = 0;
|
|
1534
|
+
let nSum = 0;
|
|
1535
|
+
for (let i = 1; i <= period; i++) {
|
|
1536
|
+
pSum += pmfArr[i];
|
|
1537
|
+
nSum += nmfArr[i];
|
|
1538
|
+
}
|
|
1539
|
+
result[period] = nSum > 0 ? 100 - 100 / (1 + pSum / nSum) : 100;
|
|
1540
|
+
for (let t = period + 1; t < n; t++) {
|
|
1541
|
+
pSum += pmfArr[t] - pmfArr[t - period];
|
|
1542
|
+
nSum += nmfArr[t] - nmfArr[t - period];
|
|
1543
|
+
result[t] = nSum > 0 ? 100 - 100 / (1 + pSum / nSum) : 100;
|
|
1544
|
+
}
|
|
1545
|
+
return result;
|
|
1546
|
+
}
|
|
1547
|
+
export function calcMFIDataSoA(layout, period) {
|
|
1548
|
+
const data = SharedKLineBuffer.toKLineData(layout);
|
|
1549
|
+
return calcMFIData(data, period);
|
|
1550
|
+
}
|
|
1551
|
+
export function calcPivotData(data) {
|
|
1552
|
+
const n = data.length;
|
|
1553
|
+
const result = new Array(n).fill(undefined);
|
|
1554
|
+
if (n < 2)
|
|
1555
|
+
return result;
|
|
1556
|
+
for (let t = 1; t < n; t++) {
|
|
1557
|
+
const p = data[t - 1];
|
|
1558
|
+
const pp = (p.high + p.low + p.close) / 3;
|
|
1559
|
+
const range = p.high - p.low;
|
|
1560
|
+
result[t] = {
|
|
1561
|
+
pp,
|
|
1562
|
+
r1: 2 * pp - p.low,
|
|
1563
|
+
s1: 2 * pp - p.high,
|
|
1564
|
+
r2: pp + range,
|
|
1565
|
+
s2: pp - range,
|
|
1566
|
+
r3: p.high + 2 * (pp - p.low),
|
|
1567
|
+
s3: p.low - 2 * (p.high - pp),
|
|
1568
|
+
};
|
|
1569
|
+
}
|
|
1570
|
+
return result;
|
|
1571
|
+
}
|
|
1572
|
+
export function calcPivotDataSoA(layout) {
|
|
1573
|
+
const data = SharedKLineBuffer.toKLineData(layout);
|
|
1574
|
+
return calcPivotData(data);
|
|
1575
|
+
}
|
|
1576
|
+
export const DEFAULT_FIB_PERIOD = 50;
|
|
1577
|
+
export function calcFibData(data, period) {
|
|
1578
|
+
const n = data.length;
|
|
1579
|
+
const result = new Array(n).fill(undefined);
|
|
1580
|
+
if (n === 0 || period <= 0 || n < period)
|
|
1581
|
+
return result;
|
|
1582
|
+
for (let t = period - 1; t < n; t++) {
|
|
1583
|
+
let hi = -Infinity;
|
|
1584
|
+
let lo = Infinity;
|
|
1585
|
+
let hiIdx = t;
|
|
1586
|
+
let loIdx = t;
|
|
1587
|
+
for (let k = 0; k < period; k++) {
|
|
1588
|
+
const bar = data[t - k];
|
|
1589
|
+
if (bar.high > hi) {
|
|
1590
|
+
hi = bar.high;
|
|
1591
|
+
hiIdx = t - k;
|
|
1592
|
+
}
|
|
1593
|
+
if (bar.low < lo) {
|
|
1594
|
+
lo = bar.low;
|
|
1595
|
+
loIdx = t - k;
|
|
1596
|
+
}
|
|
1597
|
+
}
|
|
1598
|
+
const direction = hiIdx >= loIdx ? 'up' : 'down';
|
|
1599
|
+
const range = hi - lo;
|
|
1600
|
+
// For uptrend retracements: 0% at high, 100% at low; price retraces FROM high TOWARD low
|
|
1601
|
+
// For downtrend: 0% at low, 100% at high
|
|
1602
|
+
const level = (frac) => direction === 'up' ? hi - range * frac : lo + range * frac;
|
|
1603
|
+
result[t] = {
|
|
1604
|
+
high: hi,
|
|
1605
|
+
low: lo,
|
|
1606
|
+
direction,
|
|
1607
|
+
level236: level(0.236),
|
|
1608
|
+
level382: level(0.382),
|
|
1609
|
+
level500: level(0.5),
|
|
1610
|
+
level618: level(0.618),
|
|
1611
|
+
level786: level(0.786),
|
|
1612
|
+
};
|
|
1613
|
+
}
|
|
1614
|
+
return result;
|
|
1615
|
+
}
|
|
1616
|
+
export function calcFibDataSoA(layout, period) {
|
|
1617
|
+
const data = SharedKLineBuffer.toKLineData(layout);
|
|
1618
|
+
return calcFibData(data, period);
|
|
1619
|
+
}
|
|
1620
|
+
export const DEFAULT_STRUCTURE_LEFT = 2;
|
|
1621
|
+
export const DEFAULT_STRUCTURE_RIGHT = 2;
|
|
1622
|
+
export function calcStructureData(data, leftWindow, rightWindow, breakoutSource) {
|
|
1623
|
+
const n = data.length;
|
|
1624
|
+
if (n === 0 || leftWindow < 0 || rightWindow < 0) {
|
|
1625
|
+
return { swings: [], events: [], trend: 'range' };
|
|
1626
|
+
}
|
|
1627
|
+
const rawSwings = [];
|
|
1628
|
+
for (let i = 0; i < n; i++) {
|
|
1629
|
+
const bar = data[i];
|
|
1630
|
+
if (isExtremum(data, i, leftWindow, rightWindow, 'high')) {
|
|
1631
|
+
rawSwings.push({ index: i, price: bar.high, kind: 'high', confirmed: i + rightWindow < n });
|
|
1632
|
+
}
|
|
1633
|
+
if (isExtremum(data, i, leftWindow, rightWindow, 'low')) {
|
|
1634
|
+
rawSwings.push({ index: i, price: bar.low, kind: 'low', confirmed: i + rightWindow < n });
|
|
1635
|
+
}
|
|
1636
|
+
}
|
|
1637
|
+
rawSwings.sort((a, b) => a.index - b.index);
|
|
1638
|
+
const swings = [];
|
|
1639
|
+
let lastHigh = null;
|
|
1640
|
+
let lastLow = null;
|
|
1641
|
+
for (const s of rawSwings) {
|
|
1642
|
+
let label;
|
|
1643
|
+
if (s.kind === 'high') {
|
|
1644
|
+
label = lastHigh && s.price > lastHigh.price ? 'HH' : 'LH';
|
|
1645
|
+
lastHigh = { index: s.index, price: s.price };
|
|
1646
|
+
}
|
|
1647
|
+
else {
|
|
1648
|
+
label = lastLow && s.price > lastLow.price ? 'HL' : 'LL';
|
|
1649
|
+
lastLow = { index: s.index, price: s.price };
|
|
1650
|
+
}
|
|
1651
|
+
swings.push({ ...s, label });
|
|
1652
|
+
}
|
|
1653
|
+
const events = [];
|
|
1654
|
+
let trend = 'range';
|
|
1655
|
+
let lastSwingHigh = null;
|
|
1656
|
+
let lastSwingLow = null;
|
|
1657
|
+
const confirmedSwings = swings.filter((s) => s.confirmed);
|
|
1658
|
+
let swingCursor = 0;
|
|
1659
|
+
for (let t = 0; t < n; t++) {
|
|
1660
|
+
while (swingCursor < confirmedSwings.length && confirmedSwings[swingCursor].index + rightWindow <= t) {
|
|
1661
|
+
const s = confirmedSwings[swingCursor];
|
|
1662
|
+
if (s.kind === 'high')
|
|
1663
|
+
lastSwingHigh = { index: s.index, price: s.price };
|
|
1664
|
+
else
|
|
1665
|
+
lastSwingLow = { index: s.index, price: s.price };
|
|
1666
|
+
swingCursor++;
|
|
1667
|
+
}
|
|
1668
|
+
const bar = data[t];
|
|
1669
|
+
const upBreakPrice = breakoutSource === 'close' ? bar.close : bar.high;
|
|
1670
|
+
const downBreakPrice = breakoutSource === 'close' ? bar.close : bar.low;
|
|
1671
|
+
if (lastSwingHigh && upBreakPrice > lastSwingHigh.price) {
|
|
1672
|
+
const kind = trend === 'down' ? 'CHOCH' : 'BOS';
|
|
1673
|
+
events.push({
|
|
1674
|
+
kind,
|
|
1675
|
+
index: t,
|
|
1676
|
+
triggerPrice: upBreakPrice,
|
|
1677
|
+
brokenLevel: lastSwingHigh.price,
|
|
1678
|
+
brokenSwingIndex: lastSwingHigh.index,
|
|
1679
|
+
direction: 'up',
|
|
1680
|
+
});
|
|
1681
|
+
trend = 'up';
|
|
1682
|
+
lastSwingHigh = null;
|
|
1683
|
+
}
|
|
1684
|
+
else if (lastSwingLow && downBreakPrice < lastSwingLow.price) {
|
|
1685
|
+
const kind = trend === 'up' ? 'CHOCH' : 'BOS';
|
|
1686
|
+
events.push({
|
|
1687
|
+
kind,
|
|
1688
|
+
index: t,
|
|
1689
|
+
triggerPrice: downBreakPrice,
|
|
1690
|
+
brokenLevel: lastSwingLow.price,
|
|
1691
|
+
brokenSwingIndex: lastSwingLow.index,
|
|
1692
|
+
direction: 'down',
|
|
1693
|
+
});
|
|
1694
|
+
trend = 'down';
|
|
1695
|
+
lastSwingLow = null;
|
|
1696
|
+
}
|
|
1697
|
+
}
|
|
1698
|
+
return { swings, events, trend };
|
|
1699
|
+
}
|
|
1700
|
+
function isExtremum(data, i, left, right, kind) {
|
|
1701
|
+
const n = data.length;
|
|
1702
|
+
if (i < left || i + right >= n)
|
|
1703
|
+
return false;
|
|
1704
|
+
const center = kind === 'high' ? data[i].high : data[i].low;
|
|
1705
|
+
for (let k = 1; k <= left; k++) {
|
|
1706
|
+
const v = kind === 'high' ? data[i - k].high : data[i - k].low;
|
|
1707
|
+
if (kind === 'high' ? v >= center : v <= center)
|
|
1708
|
+
return false;
|
|
1709
|
+
}
|
|
1710
|
+
for (let k = 1; k <= right; k++) {
|
|
1711
|
+
const v = kind === 'high' ? data[i + k].high : data[i + k].low;
|
|
1712
|
+
if (kind === 'high' ? v >= center : v <= center)
|
|
1713
|
+
return false;
|
|
1714
|
+
}
|
|
1715
|
+
return true;
|
|
1716
|
+
}
|
|
1717
|
+
export function calcStructureDataSoA(layout, leftWindow, rightWindow, breakoutSource) {
|
|
1718
|
+
const data = SharedKLineBuffer.toKLineData(layout);
|
|
1719
|
+
return calcStructureData(data, leftWindow, rightWindow, breakoutSource);
|
|
1720
|
+
}
|
|
1721
|
+
export const DEFAULT_ZONES_OB_LOOKBACK = 5;
|
|
1722
|
+
export function calcZonesData(data, obLookback, structureLeftWindow, structureRightWindow, breakoutSource) {
|
|
1723
|
+
const n = data.length;
|
|
1724
|
+
if (n < 3)
|
|
1725
|
+
return [];
|
|
1726
|
+
const zones = [];
|
|
1727
|
+
// 1. Detect FVGs
|
|
1728
|
+
for (let t = 2; t < n; t++) {
|
|
1729
|
+
const a = data[t - 2];
|
|
1730
|
+
const c = data[t];
|
|
1731
|
+
// Bullish FVG: a.high < c.low → gap
|
|
1732
|
+
if (a.high < c.low) {
|
|
1733
|
+
zones.push({
|
|
1734
|
+
kind: 'FVG_BULL',
|
|
1735
|
+
startIndex: t - 1,
|
|
1736
|
+
high: c.low,
|
|
1737
|
+
low: a.high,
|
|
1738
|
+
});
|
|
1739
|
+
}
|
|
1740
|
+
// Bearish FVG: a.low > c.high → gap
|
|
1741
|
+
if (a.low > c.high) {
|
|
1742
|
+
zones.push({
|
|
1743
|
+
kind: 'FVG_BEAR',
|
|
1744
|
+
startIndex: t - 1,
|
|
1745
|
+
high: a.low,
|
|
1746
|
+
low: c.high,
|
|
1747
|
+
});
|
|
1748
|
+
}
|
|
1749
|
+
}
|
|
1750
|
+
// 2. Detect Order Blocks using structure BOS events
|
|
1751
|
+
const struct = calcStructureData(data, structureLeftWindow, structureRightWindow, breakoutSource);
|
|
1752
|
+
for (const ev of struct.events) {
|
|
1753
|
+
if (ev.kind !== 'BOS')
|
|
1754
|
+
continue;
|
|
1755
|
+
// Look back obLookback bars for the OB candle
|
|
1756
|
+
const start = Math.max(0, ev.index - obLookback);
|
|
1757
|
+
if (ev.direction === 'up') {
|
|
1758
|
+
// Bullish OB: latest bearish candle (close < open) in [start, ev.index)
|
|
1759
|
+
for (let k = ev.index - 1; k >= start; k--) {
|
|
1760
|
+
const bar = data[k];
|
|
1761
|
+
if (bar.close < bar.open) {
|
|
1762
|
+
zones.push({ kind: 'OB_BULL', startIndex: k, high: bar.high, low: bar.low });
|
|
1763
|
+
break;
|
|
1764
|
+
}
|
|
1765
|
+
}
|
|
1766
|
+
}
|
|
1767
|
+
else {
|
|
1768
|
+
// Bearish OB: latest bullish candle (close > open) in [start, ev.index)
|
|
1769
|
+
for (let k = ev.index - 1; k >= start; k--) {
|
|
1770
|
+
const bar = data[k];
|
|
1771
|
+
if (bar.close > bar.open) {
|
|
1772
|
+
zones.push({ kind: 'OB_BEAR', startIndex: k, high: bar.high, low: bar.low });
|
|
1773
|
+
break;
|
|
1774
|
+
}
|
|
1775
|
+
}
|
|
1776
|
+
}
|
|
1777
|
+
}
|
|
1778
|
+
// 3. Mark zones as filled when price re-enters their range
|
|
1779
|
+
for (const zone of zones) {
|
|
1780
|
+
for (let t = zone.startIndex + 1; t < n; t++) {
|
|
1781
|
+
const bar = data[t];
|
|
1782
|
+
// Zone is touched if the bar overlaps the zone's [low, high]
|
|
1783
|
+
if (bar.low <= zone.high && bar.high >= zone.low) {
|
|
1784
|
+
zone.endIndex = t;
|
|
1785
|
+
break;
|
|
1786
|
+
}
|
|
1787
|
+
}
|
|
1788
|
+
}
|
|
1789
|
+
return zones;
|
|
1790
|
+
}
|
|
1791
|
+
export function calcZonesDataSoA(layout, obLookback, structureLeftWindow, structureRightWindow, breakoutSource) {
|
|
1792
|
+
const data = SharedKLineBuffer.toKLineData(layout);
|
|
1793
|
+
return calcZonesData(data, obLookback, structureLeftWindow, structureRightWindow, breakoutSource);
|
|
1794
|
+
}
|
|
1795
|
+
export const DEFAULT_VP_BINS = 24;
|
|
1796
|
+
export const DEFAULT_VP_LOOKBACK = 0;
|
|
1797
|
+
export const DEFAULT_VP_VALUE_AREA = 0.7;
|
|
1798
|
+
export function calcVolumeProfileData(data, bins, lookback, valueAreaPercent) {
|
|
1799
|
+
const n = data.length;
|
|
1800
|
+
if (n === 0 || bins <= 0) {
|
|
1801
|
+
return { bins: [], poc: 0, vah: 0, val: 0, totalVolume: 0 };
|
|
1802
|
+
}
|
|
1803
|
+
const startIdx = lookback > 0 ? Math.max(0, n - lookback) : 0;
|
|
1804
|
+
let priceMin = Infinity;
|
|
1805
|
+
let priceMax = -Infinity;
|
|
1806
|
+
for (let i = startIdx; i < n; i++) {
|
|
1807
|
+
const bar = data[i];
|
|
1808
|
+
if (bar.low < priceMin)
|
|
1809
|
+
priceMin = bar.low;
|
|
1810
|
+
if (bar.high > priceMax)
|
|
1811
|
+
priceMax = bar.high;
|
|
1812
|
+
}
|
|
1813
|
+
if (!Number.isFinite(priceMin) || !Number.isFinite(priceMax) || priceMax <= priceMin) {
|
|
1814
|
+
return { bins: [], poc: priceMin, vah: priceMin, val: priceMin, totalVolume: 0 };
|
|
1815
|
+
}
|
|
1816
|
+
const binWidth = (priceMax - priceMin) / bins;
|
|
1817
|
+
const binVolumes = new Array(bins).fill(0);
|
|
1818
|
+
// Distribute each bar's volume uniformly across the bins its [low, high] covers
|
|
1819
|
+
for (let i = startIdx; i < n; i++) {
|
|
1820
|
+
const bar = data[i];
|
|
1821
|
+
const barRange = bar.high - bar.low;
|
|
1822
|
+
if (barRange <= 0) {
|
|
1823
|
+
const binIdx = Math.min(bins - 1, Math.max(0, Math.floor((bar.close - priceMin) / binWidth)));
|
|
1824
|
+
binVolumes[binIdx] += bar.volume ?? 0;
|
|
1825
|
+
continue;
|
|
1826
|
+
}
|
|
1827
|
+
const volPerPrice = (bar.volume ?? 0) / barRange;
|
|
1828
|
+
const startBin = Math.max(0, Math.floor((bar.low - priceMin) / binWidth));
|
|
1829
|
+
const endBin = Math.min(bins - 1, Math.floor((bar.high - priceMin) / binWidth));
|
|
1830
|
+
for (let b = startBin; b <= endBin; b++) {
|
|
1831
|
+
const binLow = priceMin + b * binWidth;
|
|
1832
|
+
const binHigh = binLow + binWidth;
|
|
1833
|
+
const overlapLow = Math.max(bar.low, binLow);
|
|
1834
|
+
const overlapHigh = Math.min(bar.high, binHigh);
|
|
1835
|
+
const overlap = overlapHigh - overlapLow;
|
|
1836
|
+
if (overlap > 0) {
|
|
1837
|
+
binVolumes[b] += overlap * volPerPrice;
|
|
1838
|
+
}
|
|
1839
|
+
}
|
|
1840
|
+
}
|
|
1841
|
+
const binsArr = binVolumes.map((v, b) => ({
|
|
1842
|
+
priceLow: priceMin + b * binWidth,
|
|
1843
|
+
priceHigh: priceMin + (b + 1) * binWidth,
|
|
1844
|
+
volume: v,
|
|
1845
|
+
}));
|
|
1846
|
+
// POC = max-volume bin center
|
|
1847
|
+
let pocBinIdx = 0;
|
|
1848
|
+
for (let b = 1; b < bins; b++) {
|
|
1849
|
+
if (binVolumes[b] > binVolumes[pocBinIdx])
|
|
1850
|
+
pocBinIdx = b;
|
|
1851
|
+
}
|
|
1852
|
+
const poc = (binsArr[pocBinIdx].priceLow + binsArr[pocBinIdx].priceHigh) / 2;
|
|
1853
|
+
const totalVolume = binVolumes.reduce((a, b) => a + b, 0);
|
|
1854
|
+
// Value Area: expand outward from POC until cumulative volume >= valueAreaPercent of total
|
|
1855
|
+
const target = totalVolume * valueAreaPercent;
|
|
1856
|
+
let acc = binVolumes[pocBinIdx];
|
|
1857
|
+
let lo = pocBinIdx;
|
|
1858
|
+
let hi = pocBinIdx;
|
|
1859
|
+
while (acc < target && (lo > 0 || hi < bins - 1)) {
|
|
1860
|
+
const loCand = lo > 0 ? binVolumes[lo - 1] : -Infinity;
|
|
1861
|
+
const hiCand = hi < bins - 1 ? binVolumes[hi + 1] : -Infinity;
|
|
1862
|
+
if (loCand >= hiCand && lo > 0) {
|
|
1863
|
+
lo--;
|
|
1864
|
+
acc += binVolumes[lo];
|
|
1865
|
+
}
|
|
1866
|
+
else if (hi < bins - 1) {
|
|
1867
|
+
hi++;
|
|
1868
|
+
acc += binVolumes[hi];
|
|
1869
|
+
}
|
|
1870
|
+
else {
|
|
1871
|
+
break;
|
|
1872
|
+
}
|
|
1873
|
+
}
|
|
1874
|
+
const val = binsArr[lo].priceLow;
|
|
1875
|
+
const vah = binsArr[hi].priceHigh;
|
|
1876
|
+
return { bins: binsArr, poc, vah, val, totalVolume };
|
|
1877
|
+
}
|
|
1878
|
+
export function calcVolumeProfileDataSoA(layout, bins, lookback, valueAreaPercent) {
|
|
1879
|
+
const data = SharedKLineBuffer.toKLineData(layout);
|
|
1880
|
+
return calcVolumeProfileData(data, bins, lookback, valueAreaPercent);
|
|
1881
|
+
}
|
|
1882
|
+
//# sourceMappingURL=calculators.js.map
|