@forgecharts/sdk 1.1.23 → 1.1.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/__tests__/backwardCompatibility.test.d.ts +14 -0
- package/dist/__tests__/backwardCompatibility.test.d.ts.map +1 -0
- package/dist/__tests__/backwardCompatibility.test.js +159 -0
- package/dist/__tests__/backwardCompatibility.test.js.map +1 -0
- package/dist/__tests__/candleInvariant.test.d.ts +20 -0
- package/dist/__tests__/candleInvariant.test.d.ts.map +1 -0
- package/dist/__tests__/candleInvariant.test.js +415 -0
- package/dist/__tests__/candleInvariant.test.js.map +1 -0
- package/dist/__tests__/public-api-surface.d.ts +13 -0
- package/dist/__tests__/public-api-surface.d.ts.map +1 -0
- package/{src/__tests__/public-api-surface.ts → dist/__tests__/public-api-surface.js} +4 -42
- package/dist/__tests__/public-api-surface.js.map +1 -0
- package/dist/__tests__/timeframeBoundary.test.d.ts +17 -0
- package/dist/__tests__/timeframeBoundary.test.d.ts.map +1 -0
- package/dist/__tests__/timeframeBoundary.test.js +452 -0
- package/dist/__tests__/timeframeBoundary.test.js.map +1 -0
- package/dist/api/DrawingManager.d.ts +20 -0
- package/dist/api/DrawingManager.d.ts.map +1 -0
- package/dist/api/DrawingManager.js +190 -0
- package/dist/api/DrawingManager.js.map +1 -0
- package/dist/api/EventBus.d.ts +19 -0
- package/dist/api/EventBus.d.ts.map +1 -0
- package/dist/api/EventBus.js +44 -0
- package/dist/api/EventBus.js.map +1 -0
- package/dist/api/IndicatorDAG.d.ts +85 -0
- package/dist/api/IndicatorDAG.d.ts.map +1 -0
- package/dist/api/IndicatorDAG.js +316 -0
- package/dist/api/IndicatorDAG.js.map +1 -0
- package/dist/api/IndicatorRegistry.d.ts +22 -0
- package/dist/api/IndicatorRegistry.d.ts.map +1 -0
- package/dist/api/IndicatorRegistry.js +39 -0
- package/dist/api/IndicatorRegistry.js.map +1 -0
- package/dist/api/LayoutManager.d.ts +30 -0
- package/dist/api/LayoutManager.d.ts.map +1 -0
- package/dist/api/LayoutManager.js +51 -0
- package/dist/api/LayoutManager.js.map +1 -0
- package/dist/api/PaneManager.d.ts +42 -0
- package/dist/api/PaneManager.d.ts.map +1 -0
- package/dist/api/PaneManager.js +119 -0
- package/dist/api/PaneManager.js.map +1 -0
- package/dist/api/ReferenceAPI.d.ts +78 -0
- package/dist/api/ReferenceAPI.d.ts.map +1 -0
- package/dist/api/ReferenceAPI.js +153 -0
- package/dist/api/ReferenceAPI.js.map +1 -0
- package/dist/api/TChart.d.ts +345 -0
- package/dist/api/TChart.d.ts.map +1 -0
- package/dist/api/TChart.js +765 -0
- package/dist/api/TChart.js.map +1 -0
- package/{src/api/createChart.ts → dist/api/createChart.d.ts} +2 -7
- package/dist/api/createChart.d.ts.map +1 -0
- package/dist/api/createChart.js +42 -0
- package/dist/api/createChart.js.map +1 -0
- package/dist/api/drawing tools/fib gann menu/fibRetracement.d.ts +4 -0
- package/dist/api/drawing tools/fib gann menu/fibRetracement.d.ts.map +1 -0
- package/dist/api/drawing tools/fib gann menu/fibRetracement.js +22 -0
- package/dist/api/drawing tools/fib gann menu/fibRetracement.js.map +1 -0
- package/dist/api/drawing tools/lines menu/crossLine.d.ts +4 -0
- package/dist/api/drawing tools/lines menu/crossLine.d.ts.map +1 -0
- package/dist/api/drawing tools/lines menu/crossLine.js +16 -0
- package/dist/api/drawing tools/lines menu/crossLine.js.map +1 -0
- package/dist/api/drawing tools/lines menu/disjointChannel.d.ts +17 -0
- package/dist/api/drawing tools/lines menu/disjointChannel.d.ts.map +1 -0
- package/dist/api/drawing tools/lines menu/disjointChannel.js +59 -0
- package/dist/api/drawing tools/lines menu/disjointChannel.js.map +1 -0
- package/dist/api/drawing tools/lines menu/extendedLine.d.ts +4 -0
- package/dist/api/drawing tools/lines menu/extendedLine.d.ts.map +1 -0
- package/dist/api/drawing tools/lines menu/extendedLine.js +17 -0
- package/dist/api/drawing tools/lines menu/extendedLine.js.map +1 -0
- package/dist/api/drawing tools/lines menu/flatTopBottom.d.ts +4 -0
- package/dist/api/drawing tools/lines menu/flatTopBottom.d.ts.map +1 -0
- package/dist/api/drawing tools/lines menu/flatTopBottom.js +41 -0
- package/dist/api/drawing tools/lines menu/flatTopBottom.js.map +1 -0
- package/dist/api/drawing tools/lines menu/horizontal.d.ts +4 -0
- package/dist/api/drawing tools/lines menu/horizontal.d.ts.map +1 -0
- package/dist/api/drawing tools/lines menu/horizontal.js +19 -0
- package/dist/api/drawing tools/lines menu/horizontal.js.map +1 -0
- package/dist/api/drawing tools/lines menu/horizontalRay.d.ts +4 -0
- package/dist/api/drawing tools/lines menu/horizontalRay.d.ts.map +1 -0
- package/dist/api/drawing tools/lines menu/horizontalRay.js +20 -0
- package/dist/api/drawing tools/lines menu/horizontalRay.js.map +1 -0
- package/dist/api/drawing tools/lines menu/infoLine.d.ts +4 -0
- package/dist/api/drawing tools/lines menu/infoLine.d.ts.map +1 -0
- package/dist/api/drawing tools/lines menu/infoLine.js +107 -0
- package/dist/api/drawing tools/lines menu/infoLine.js.map +1 -0
- package/dist/api/drawing tools/lines menu/insidePitchfork.d.ts +4 -0
- package/dist/api/drawing tools/lines menu/insidePitchfork.d.ts.map +1 -0
- package/dist/api/drawing tools/lines menu/insidePitchfork.js +31 -0
- package/dist/api/drawing tools/lines menu/insidePitchfork.js.map +1 -0
- package/dist/api/drawing tools/lines menu/modifiedSchiffPitchfork.d.ts +4 -0
- package/dist/api/drawing tools/lines menu/modifiedSchiffPitchfork.d.ts.map +1 -0
- package/dist/api/drawing tools/lines menu/modifiedSchiffPitchfork.js +15 -0
- package/dist/api/drawing tools/lines menu/modifiedSchiffPitchfork.js.map +1 -0
- package/dist/api/drawing tools/lines menu/parallelChannel.d.ts +4 -0
- package/dist/api/drawing tools/lines menu/parallelChannel.d.ts.map +1 -0
- package/dist/api/drawing tools/lines menu/parallelChannel.js +43 -0
- package/dist/api/drawing tools/lines menu/parallelChannel.js.map +1 -0
- package/dist/api/drawing tools/lines menu/pitchfork.d.ts +4 -0
- package/dist/api/drawing tools/lines menu/pitchfork.d.ts.map +1 -0
- package/dist/api/drawing tools/lines menu/pitchfork.js +12 -0
- package/dist/api/drawing tools/lines menu/pitchfork.js.map +1 -0
- package/dist/api/drawing tools/lines menu/ray.d.ts +4 -0
- package/dist/api/drawing tools/lines menu/ray.d.ts.map +1 -0
- package/dist/api/drawing tools/lines menu/ray.js +23 -0
- package/dist/api/drawing tools/lines menu/ray.js.map +1 -0
- package/dist/api/drawing tools/lines menu/regressionTrend.d.ts +4 -0
- package/dist/api/drawing tools/lines menu/regressionTrend.d.ts.map +1 -0
- package/dist/api/drawing tools/lines menu/regressionTrend.js +127 -0
- package/dist/api/drawing tools/lines menu/regressionTrend.js.map +1 -0
- package/dist/api/drawing tools/lines menu/schiffPitchfork.d.ts +4 -0
- package/dist/api/drawing tools/lines menu/schiffPitchfork.d.ts.map +1 -0
- package/dist/api/drawing tools/lines menu/schiffPitchfork.js +15 -0
- package/dist/api/drawing tools/lines menu/schiffPitchfork.js.map +1 -0
- package/dist/api/drawing tools/lines menu/trendAngle.d.ts +4 -0
- package/dist/api/drawing tools/lines menu/trendAngle.d.ts.map +1 -0
- package/dist/api/drawing tools/lines menu/trendAngle.js +51 -0
- package/dist/api/drawing tools/lines menu/trendAngle.js.map +1 -0
- package/dist/api/drawing tools/lines menu/trendline.d.ts +4 -0
- package/dist/api/drawing tools/lines menu/trendline.d.ts.map +1 -0
- package/dist/api/drawing tools/lines menu/trendline.js +11 -0
- package/dist/api/drawing tools/lines menu/trendline.js.map +1 -0
- package/dist/api/drawing tools/lines menu/vertical.d.ts +4 -0
- package/dist/api/drawing tools/lines menu/vertical.d.ts.map +1 -0
- package/dist/api/drawing tools/lines menu/vertical.js +11 -0
- package/dist/api/drawing tools/lines menu/vertical.js.map +1 -0
- package/dist/api/drawing tools/pointers menu/crosshair.d.ts +16 -0
- package/dist/api/drawing tools/pointers menu/crosshair.d.ts.map +1 -0
- package/{src/api/drawing tools/pointers menu/crosshair.ts → dist/api/drawing tools/pointers menu/crosshair.js } +6 -7
- package/dist/api/drawing tools/pointers menu/crosshair.js.map +1 -0
- package/dist/api/drawing tools/pointers menu/cursor.d.ts +15 -0
- package/dist/api/drawing tools/pointers menu/cursor.d.ts.map +1 -0
- package/{src/api/drawing tools/pointers menu/cursor.ts → dist/api/drawing tools/pointers menu/cursor.js } +7 -8
- package/dist/api/drawing tools/pointers menu/cursor.js.map +1 -0
- package/dist/api/drawing tools/pointers menu/demonstration.d.ts +30 -0
- package/dist/api/drawing tools/pointers menu/demonstration.d.ts.map +1 -0
- package/{src/api/drawing tools/pointers menu/demonstration.ts → dist/api/drawing tools/pointers menu/demonstration.js } +9 -14
- package/dist/api/drawing tools/pointers menu/demonstration.js.map +1 -0
- package/dist/api/drawing tools/pointers menu/dot.d.ts +23 -0
- package/dist/api/drawing tools/pointers menu/dot.d.ts.map +1 -0
- package/{src/api/drawing tools/pointers menu/dot.ts → dist/api/drawing tools/pointers menu/dot.js } +8 -11
- package/dist/api/drawing tools/pointers menu/dot.js.map +1 -0
- package/dist/api/drawing tools/shapes menu/rectangle.d.ts +4 -0
- package/dist/api/drawing tools/shapes menu/rectangle.d.ts.map +1 -0
- package/dist/api/drawing tools/shapes menu/rectangle.js +19 -0
- package/dist/api/drawing tools/shapes menu/rectangle.js.map +1 -0
- package/dist/api/drawing tools/shapes menu/text.d.ts +4 -0
- package/dist/api/drawing tools/shapes menu/text.d.ts.map +1 -0
- package/dist/api/drawing tools/shapes menu/text.js +25 -0
- package/dist/api/drawing tools/shapes menu/text.js.map +1 -0
- package/dist/api/drawingUtils.d.ts +22 -0
- package/dist/api/drawingUtils.d.ts.map +1 -0
- package/dist/api/drawingUtils.js +83 -0
- package/dist/api/drawingUtils.js.map +1 -0
- package/dist/core/CanvasLayer.d.ts +26 -0
- package/dist/core/CanvasLayer.d.ts.map +1 -0
- package/dist/core/CanvasLayer.js +56 -0
- package/dist/core/CanvasLayer.js.map +1 -0
- package/dist/core/Chart.d.ts +164 -0
- package/dist/core/Chart.d.ts.map +1 -0
- package/dist/core/Chart.js +839 -0
- package/dist/core/Chart.js.map +1 -0
- package/dist/core/CoordTransform.d.ts +168 -0
- package/dist/core/CoordTransform.d.ts.map +1 -0
- package/dist/core/CoordTransform.js +224 -0
- package/dist/core/CoordTransform.js.map +1 -0
- package/dist/core/Crosshair.d.ts +30 -0
- package/dist/core/Crosshair.d.ts.map +1 -0
- package/dist/core/Crosshair.js +186 -0
- package/dist/core/Crosshair.js.map +1 -0
- package/dist/core/IndicatorEngine.d.ts +51 -0
- package/dist/core/IndicatorEngine.d.ts.map +1 -0
- package/dist/core/IndicatorEngine.js +181 -0
- package/dist/core/IndicatorEngine.js.map +1 -0
- package/dist/core/InteractionManager.d.ts +197 -0
- package/dist/core/InteractionManager.d.ts.map +1 -0
- package/dist/core/InteractionManager.js +698 -0
- package/dist/core/InteractionManager.js.map +1 -0
- package/dist/core/PriceScale.d.ts +27 -0
- package/dist/core/PriceScale.d.ts.map +1 -0
- package/dist/core/PriceScale.js +113 -0
- package/dist/core/PriceScale.js.map +1 -0
- package/dist/core/Series.d.ts +40 -0
- package/dist/core/Series.d.ts.map +1 -0
- package/dist/core/Series.js +114 -0
- package/dist/core/Series.js.map +1 -0
- package/dist/core/TimeScale.d.ts +43 -0
- package/dist/core/TimeScale.d.ts.map +1 -0
- package/dist/core/TimeScale.js +150 -0
- package/dist/core/TimeScale.js.map +1 -0
- package/dist/datafeed/DatafeedConnector.d.ts +89 -0
- package/dist/datafeed/DatafeedConnector.d.ts.map +1 -0
- package/dist/datafeed/DatafeedConnector.js +268 -0
- package/dist/datafeed/DatafeedConnector.js.map +1 -0
- package/dist/engine/CandleEngine.d.ts +207 -0
- package/dist/engine/CandleEngine.d.ts.map +1 -0
- package/dist/engine/CandleEngine.js +318 -0
- package/dist/engine/CandleEngine.js.map +1 -0
- package/dist/engine/__tests__/CandleEngine.test.d.ts +2 -0
- package/dist/engine/__tests__/CandleEngine.test.d.ts.map +1 -0
- package/dist/engine/__tests__/CandleEngine.test.js +300 -0
- package/dist/engine/__tests__/CandleEngine.test.js.map +1 -0
- package/dist/engine/candleInvariants.d.ts +66 -0
- package/dist/engine/candleInvariants.d.ts.map +1 -0
- package/dist/engine/candleInvariants.js +134 -0
- package/dist/engine/candleInvariants.js.map +1 -0
- package/{src/engine/mergeUtils.ts → dist/engine/mergeUtils.d.ts} +15 -52
- package/dist/engine/mergeUtils.d.ts.map +1 -0
- package/dist/engine/mergeUtils.js +64 -0
- package/dist/engine/mergeUtils.js.map +1 -0
- package/dist/engine/timeframeUtils.d.ts +80 -0
- package/dist/engine/timeframeUtils.d.ts.map +1 -0
- package/{src/engine/timeframeUtils.ts → dist/engine/timeframeUtils.js} +30 -48
- package/dist/engine/timeframeUtils.js.map +1 -0
- package/dist/index.d.ts +40 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +49 -0
- package/dist/index.js.map +1 -0
- package/dist/internal.d.ts +29 -0
- package/dist/internal.d.ts.map +1 -0
- package/{src/internal.ts → dist/internal.js} +2 -11
- package/dist/internal.js.map +1 -0
- package/dist/licensing/ChartRuntimeResolver.d.ts +233 -0
- package/dist/licensing/ChartRuntimeResolver.d.ts.map +1 -0
- package/dist/licensing/ChartRuntimeResolver.js +310 -0
- package/dist/licensing/ChartRuntimeResolver.js.map +1 -0
- package/dist/licensing/LicenseManager.d.ts +55 -0
- package/dist/licensing/LicenseManager.d.ts.map +1 -0
- package/dist/licensing/LicenseManager.js +114 -0
- package/dist/licensing/LicenseManager.js.map +1 -0
- package/dist/licensing/__tests__/ChartRuntimeResolver.test.d.ts +13 -0
- package/dist/licensing/__tests__/ChartRuntimeResolver.test.d.ts.map +1 -0
- package/dist/licensing/__tests__/ChartRuntimeResolver.test.js +177 -0
- package/dist/licensing/__tests__/ChartRuntimeResolver.test.js.map +1 -0
- package/dist/licensing/__tests__/LicenseManager.test.d.ts +12 -0
- package/dist/licensing/__tests__/LicenseManager.test.d.ts.map +1 -0
- package/dist/licensing/__tests__/LicenseManager.test.js +153 -0
- package/dist/licensing/__tests__/LicenseManager.test.js.map +1 -0
- package/dist/licensing/licenseTypes.d.ts +18 -0
- package/dist/licensing/licenseTypes.d.ts.map +1 -0
- package/dist/licensing/licenseTypes.js +2 -0
- package/dist/licensing/licenseTypes.js.map +1 -0
- package/dist/pine/PineCompiler.d.ts +35 -0
- package/dist/pine/PineCompiler.d.ts.map +1 -0
- package/dist/pine/PineCompiler.js +44 -0
- package/dist/pine/PineCompiler.js.map +1 -0
- package/dist/pine/diagnostics.d.ts +20 -0
- package/dist/pine/diagnostics.d.ts.map +1 -0
- package/dist/pine/diagnostics.js +11 -0
- package/dist/pine/diagnostics.js.map +1 -0
- package/{src/pine/index.ts → dist/pine/index.d.ts} +4 -3
- package/dist/pine/index.d.ts.map +1 -0
- package/dist/pine/index.js +5 -0
- package/dist/pine/index.js.map +1 -0
- package/dist/pine/pine-ast.d.ts +142 -0
- package/dist/pine/pine-ast.d.ts.map +1 -0
- package/dist/pine/pine-ast.js +19 -0
- package/dist/pine/pine-ast.js.map +1 -0
- package/dist/pine/pine-lexer.d.ts +41 -0
- package/dist/pine/pine-lexer.d.ts.map +1 -0
- package/dist/pine/pine-lexer.js +249 -0
- package/dist/pine/pine-lexer.js.map +1 -0
- package/dist/pine/pine-parser.d.ts +51 -0
- package/dist/pine/pine-parser.d.ts.map +1 -0
- package/dist/pine/pine-parser.js +416 -0
- package/dist/pine/pine-parser.js.map +1 -0
- package/dist/pine/pine-transpiler.d.ts +33 -0
- package/dist/pine/pine-transpiler.d.ts.map +1 -0
- package/dist/pine/pine-transpiler.js +260 -0
- package/dist/pine/pine-transpiler.js.map +1 -0
- package/dist/pixi/LayerName.d.ts +18 -0
- package/dist/pixi/LayerName.d.ts.map +1 -0
- package/dist/pixi/LayerName.js +35 -0
- package/dist/pixi/LayerName.js.map +1 -0
- package/dist/pixi/PixiCandlestickRenderer.d.ts +23 -0
- package/dist/pixi/PixiCandlestickRenderer.d.ts.map +1 -0
- package/dist/pixi/PixiCandlestickRenderer.js +107 -0
- package/dist/pixi/PixiCandlestickRenderer.js.map +1 -0
- package/dist/pixi/PixiChart.d.ts +72 -0
- package/dist/pixi/PixiChart.d.ts.map +1 -0
- package/dist/pixi/PixiChart.js +367 -0
- package/dist/pixi/PixiChart.js.map +1 -0
- package/dist/pixi/PixiCrosshairRenderer.d.ts +29 -0
- package/dist/pixi/PixiCrosshairRenderer.d.ts.map +1 -0
- package/dist/pixi/PixiCrosshairRenderer.js +110 -0
- package/dist/pixi/PixiCrosshairRenderer.js.map +1 -0
- package/dist/pixi/PixiDrawingRenderer.d.ts +17 -0
- package/dist/pixi/PixiDrawingRenderer.d.ts.map +1 -0
- package/dist/pixi/PixiDrawingRenderer.js +111 -0
- package/dist/pixi/PixiDrawingRenderer.js.map +1 -0
- package/dist/pixi/PixiGridRenderer.d.ts +22 -0
- package/dist/pixi/PixiGridRenderer.d.ts.map +1 -0
- package/dist/pixi/PixiGridRenderer.js +114 -0
- package/dist/pixi/PixiGridRenderer.js.map +1 -0
- package/dist/pixi/PixiLayerManager.d.ts +56 -0
- package/dist/pixi/PixiLayerManager.d.ts.map +1 -0
- package/dist/pixi/PixiLayerManager.js +92 -0
- package/dist/pixi/PixiLayerManager.js.map +1 -0
- package/dist/react/canvas/ChartCanvas.d.ts +85 -0
- package/dist/react/canvas/ChartCanvas.d.ts.map +1 -0
- package/dist/react/canvas/ChartCanvas.js +604 -0
- package/dist/react/canvas/ChartCanvas.js.map +1 -0
- package/dist/react/canvas/ChartContextMenu.d.ts +18 -0
- package/dist/react/canvas/ChartContextMenu.d.ts.map +1 -0
- package/dist/react/canvas/ChartContextMenu.js +5 -0
- package/dist/react/canvas/ChartContextMenu.js.map +1 -0
- package/dist/react/canvas/ChartSettingsDialog.d.ts +25 -0
- package/dist/react/canvas/ChartSettingsDialog.d.ts.map +1 -0
- package/dist/react/canvas/ChartSettingsDialog.js +28 -0
- package/dist/react/canvas/ChartSettingsDialog.js.map +1 -0
- package/dist/react/canvas/IndicatorLabel.d.ts +21 -0
- package/dist/react/canvas/IndicatorLabel.d.ts.map +1 -0
- package/dist/react/canvas/IndicatorLabel.js +196 -0
- package/dist/react/canvas/IndicatorLabel.js.map +1 -0
- package/dist/react/canvas/IndicatorPane.d.ts +32 -0
- package/dist/react/canvas/IndicatorPane.d.ts.map +1 -0
- package/dist/react/canvas/IndicatorPane.js +395 -0
- package/dist/react/canvas/IndicatorPane.js.map +1 -0
- package/dist/react/canvas/PointerOverlay.d.ts +23 -0
- package/dist/react/canvas/PointerOverlay.d.ts.map +1 -0
- package/dist/react/canvas/PointerOverlay.js +61 -0
- package/dist/react/canvas/PointerOverlay.js.map +1 -0
- package/dist/react/canvas/toolbars/LeftToolbar.d.ts +19 -0
- package/dist/react/canvas/toolbars/LeftToolbar.d.ts.map +1 -0
- package/dist/react/canvas/toolbars/LeftToolbar.js +407 -0
- package/dist/react/canvas/toolbars/LeftToolbar.js.map +1 -0
- package/dist/react/hooks/useChartCapabilities.d.ts +21 -0
- package/dist/react/hooks/useChartCapabilities.d.ts.map +1 -0
- package/dist/react/hooks/useChartCapabilities.js +66 -0
- package/dist/react/hooks/useChartCapabilities.js.map +1 -0
- package/dist/react/index.d.ts +30 -0
- package/dist/react/index.d.ts.map +1 -0
- package/dist/react/index.js +28 -0
- package/dist/react/index.js.map +1 -0
- package/dist/react/internal.d.ts +38 -0
- package/dist/react/internal.d.ts.map +1 -0
- package/dist/react/internal.js +44 -0
- package/dist/react/internal.js.map +1 -0
- package/dist/react/shell/ManagedAppShell.d.ts +91 -0
- package/dist/react/shell/ManagedAppShell.d.ts.map +1 -0
- package/dist/react/shell/ManagedAppShell.js +440 -0
- package/dist/react/shell/ManagedAppShell.js.map +1 -0
- package/dist/react/trading/TradingBridge.d.ts +86 -0
- package/dist/react/trading/TradingBridge.d.ts.map +1 -0
- package/dist/react/trading/TradingBridge.js +73 -0
- package/dist/react/trading/TradingBridge.js.map +1 -0
- package/dist/react/workspace/ChartWorkspace.d.ts +73 -0
- package/dist/react/workspace/ChartWorkspace.d.ts.map +1 -0
- package/dist/react/workspace/ChartWorkspace.js +42 -0
- package/dist/react/workspace/ChartWorkspace.js.map +1 -0
- package/dist/react/workspace/FloatingPanel.d.ts +18 -0
- package/dist/react/workspace/FloatingPanel.d.ts.map +1 -0
- package/dist/react/workspace/FloatingPanel.js +82 -0
- package/dist/react/workspace/FloatingPanel.js.map +1 -0
- package/dist/react/workspace/IndicatorsDialog.d.ts +8 -0
- package/dist/react/workspace/IndicatorsDialog.d.ts.map +1 -0
- package/dist/react/workspace/IndicatorsDialog.js +121 -0
- package/dist/react/workspace/IndicatorsDialog.js.map +1 -0
- package/dist/react/workspace/LayoutMenu.d.ts +33 -0
- package/dist/react/workspace/LayoutMenu.d.ts.map +1 -0
- package/dist/react/workspace/LayoutMenu.js +113 -0
- package/dist/react/workspace/LayoutMenu.js.map +1 -0
- package/dist/react/workspace/SymbolSearchDialog.d.ts +10 -0
- package/dist/react/workspace/SymbolSearchDialog.d.ts.map +1 -0
- package/dist/react/workspace/SymbolSearchDialog.js +245 -0
- package/dist/react/workspace/SymbolSearchDialog.js.map +1 -0
- package/dist/react/workspace/TabBar.d.ts +17 -0
- package/dist/react/workspace/TabBar.d.ts.map +1 -0
- package/dist/react/workspace/TabBar.js +29 -0
- package/dist/react/workspace/TabBar.js.map +1 -0
- package/dist/react/workspace/toolbars/BottomToolbar.d.ts +19 -0
- package/dist/react/workspace/toolbars/BottomToolbar.d.ts.map +1 -0
- package/dist/react/workspace/toolbars/BottomToolbar.js +236 -0
- package/dist/react/workspace/toolbars/BottomToolbar.js.map +1 -0
- package/dist/react/workspace/toolbars/RightToolbar.d.ts +8 -0
- package/dist/react/workspace/toolbars/RightToolbar.d.ts.map +1 -0
- package/dist/react/workspace/toolbars/RightToolbar.js +18 -0
- package/dist/react/workspace/toolbars/RightToolbar.js.map +1 -0
- package/dist/react/workspace/toolbars/TopToolbar.d.ts +41 -0
- package/dist/react/workspace/toolbars/TopToolbar.d.ts.map +1 -0
- package/dist/react/workspace/toolbars/TopToolbar.js +82 -0
- package/dist/react/workspace/toolbars/TopToolbar.js.map +1 -0
- package/dist/renderers/CandlestickRenderer.d.ts +13 -0
- package/dist/renderers/CandlestickRenderer.d.ts.map +1 -0
- package/dist/renderers/CandlestickRenderer.js +98 -0
- package/dist/renderers/CandlestickRenderer.js.map +1 -0
- package/dist/renderers/HistogramRenderer.d.ts +11 -0
- package/dist/renderers/HistogramRenderer.d.ts.map +1 -0
- package/dist/renderers/HistogramRenderer.js +50 -0
- package/dist/renderers/HistogramRenderer.js.map +1 -0
- package/dist/renderers/LineRenderer.d.ts +12 -0
- package/dist/renderers/LineRenderer.d.ts.map +1 -0
- package/dist/renderers/LineRenderer.js +64 -0
- package/dist/renderers/LineRenderer.js.map +1 -0
- package/dist/theme/colors.d.ts +4 -0
- package/dist/theme/colors.d.ts.map +1 -0
- package/dist/theme/colors.js +19 -0
- package/dist/theme/colors.js.map +1 -0
- package/dist/tools/barDivergenceCheck.d.ts +120 -0
- package/dist/tools/barDivergenceCheck.d.ts.map +1 -0
- package/dist/tools/barDivergenceCheck.js +200 -0
- package/dist/tools/barDivergenceCheck.js.map +1 -0
- package/dist/trading/TradingOverlayStore.d.ts +86 -0
- package/dist/trading/TradingOverlayStore.d.ts.map +1 -0
- package/dist/trading/TradingOverlayStore.js +139 -0
- package/dist/trading/TradingOverlayStore.js.map +1 -0
- package/dist/trading/UnmanagedIngestion.d.ts +91 -0
- package/dist/trading/UnmanagedIngestion.d.ts.map +1 -0
- package/dist/trading/UnmanagedIngestion.js +114 -0
- package/dist/trading/UnmanagedIngestion.js.map +1 -0
- package/dist/trading/__tests__/ManagedTradingController.test.d.ts +18 -0
- package/dist/trading/__tests__/ManagedTradingController.test.d.ts.map +1 -0
- package/dist/trading/__tests__/ManagedTradingController.test.js +271 -0
- package/dist/trading/__tests__/ManagedTradingController.test.js.map +1 -0
- package/dist/trading/__tests__/TradingOverlayStore.test.d.ts +16 -0
- package/dist/trading/__tests__/TradingOverlayStore.test.d.ts.map +1 -0
- package/dist/trading/__tests__/TradingOverlayStore.test.js +267 -0
- package/dist/trading/__tests__/TradingOverlayStore.test.js.map +1 -0
- package/dist/trading/__tests__/UnmanagedIngestion.test.d.ts +16 -0
- package/dist/trading/__tests__/UnmanagedIngestion.test.d.ts.map +1 -0
- package/dist/trading/__tests__/UnmanagedIngestion.test.js +170 -0
- package/dist/trading/__tests__/UnmanagedIngestion.test.js.map +1 -0
- package/dist/trading/managed/ManagedTradingController.d.ts +110 -0
- package/dist/trading/managed/ManagedTradingController.d.ts.map +1 -0
- package/dist/trading/managed/ManagedTradingController.js +247 -0
- package/dist/trading/managed/ManagedTradingController.js.map +1 -0
- package/dist/trading/managed/managedCapabilities.d.ts +45 -0
- package/dist/trading/managed/managedCapabilities.d.ts.map +1 -0
- package/dist/trading/managed/managedCapabilities.js +79 -0
- package/dist/trading/managed/managedCapabilities.js.map +1 -0
- package/dist/trading/managed/managedTypes.d.ts +122 -0
- package/dist/trading/managed/managedTypes.d.ts.map +1 -0
- package/dist/trading/managed/managedTypes.js +13 -0
- package/dist/trading/managed/managedTypes.js.map +1 -0
- package/dist/trading/tradingTypes.d.ts +89 -0
- package/dist/trading/tradingTypes.d.ts.map +1 -0
- package/dist/trading/tradingTypes.js +8 -0
- package/dist/trading/tradingTypes.js.map +1 -0
- package/dist/tscript/TScriptIndicator.d.ts +41 -0
- package/dist/tscript/TScriptIndicator.d.ts.map +1 -0
- package/dist/tscript/TScriptIndicator.js +47 -0
- package/dist/tscript/TScriptIndicator.js.map +1 -0
- package/dist/tscript/ast.d.ts +89 -0
- package/dist/tscript/ast.d.ts.map +1 -0
- package/dist/tscript/ast.js +22 -0
- package/dist/tscript/ast.js.map +1 -0
- package/dist/tscript/lexer.d.ts +36 -0
- package/dist/tscript/lexer.d.ts.map +1 -0
- package/dist/tscript/lexer.js +187 -0
- package/dist/tscript/lexer.js.map +1 -0
- package/dist/tscript/parser.d.ts +50 -0
- package/dist/tscript/parser.d.ts.map +1 -0
- package/dist/tscript/parser.js +318 -0
- package/dist/tscript/parser.js.map +1 -0
- package/dist/tscript/runtime.d.ts +123 -0
- package/dist/tscript/runtime.d.ts.map +1 -0
- package/dist/tscript/runtime.js +475 -0
- package/dist/tscript/runtime.js.map +1 -0
- package/dist/tscript/series.d.ts +49 -0
- package/dist/tscript/series.d.ts.map +1 -0
- package/dist/tscript/series.js +79 -0
- package/dist/tscript/series.js.map +1 -0
- package/dist/types/IChart.d.ts +48 -0
- package/dist/types/IChart.d.ts.map +1 -0
- package/dist/types/IChart.js +2 -0
- package/dist/types/IChart.js.map +1 -0
- package/{src/types/IRenderer.ts → dist/types/IRenderer.d.ts} +2 -8
- package/dist/types/IRenderer.d.ts.map +1 -0
- package/dist/types/IRenderer.js +2 -0
- package/dist/types/IRenderer.js.map +1 -0
- package/dist/types/ISeries.d.ts +26 -0
- package/dist/types/ISeries.d.ts.map +1 -0
- package/dist/types/ISeries.js +2 -0
- package/dist/types/ISeries.js.map +1 -0
- package/package.json +32 -4
- package/src/__tests__/backwardCompatibility.test.ts +0 -191
- package/src/__tests__/candleInvariant.test.ts +0 -500
- package/src/__tests__/timeframeBoundary.test.ts +0 -583
- package/src/api/DrawingManager.ts +0 -188
- package/src/api/EventBus.ts +0 -53
- package/src/api/IndicatorDAG.ts +0 -389
- package/src/api/IndicatorRegistry.ts +0 -47
- package/src/api/LayoutManager.ts +0 -72
- package/src/api/PaneManager.ts +0 -129
- package/src/api/ReferenceAPI.ts +0 -195
- package/src/api/TChart.ts +0 -881
- package/src/api/drawing tools/fib gann menu/fibRetracement.ts +0 -27
- package/src/api/drawing tools/lines menu/crossLine.ts +0 -21
- package/src/api/drawing tools/lines menu/disjointChannel.ts +0 -74
- package/src/api/drawing tools/lines menu/extendedLine.ts +0 -22
- package/src/api/drawing tools/lines menu/flatTopBottom.ts +0 -45
- package/src/api/drawing tools/lines menu/horizontal.ts +0 -24
- package/src/api/drawing tools/lines menu/horizontalRay.ts +0 -25
- package/src/api/drawing tools/lines menu/infoLine.ts +0 -127
- package/src/api/drawing tools/lines menu/insidePitchfork.ts +0 -21
- package/src/api/drawing tools/lines menu/modifiedSchiffPitchfork.ts +0 -18
- package/src/api/drawing tools/lines menu/parallelChannel.ts +0 -47
- package/src/api/drawing tools/lines menu/pitchfork.ts +0 -15
- package/src/api/drawing tools/lines menu/ray.ts +0 -28
- package/src/api/drawing tools/lines menu/regressionTrend.ts +0 -157
- package/src/api/drawing tools/lines menu/schiffPitchfork.ts +0 -18
- package/src/api/drawing tools/lines menu/trendAngle.ts +0 -64
- package/src/api/drawing tools/lines menu/trendline.ts +0 -16
- package/src/api/drawing tools/lines menu/vertical.ts +0 -16
- package/src/api/drawing tools/shapes menu/rectangle.ts +0 -24
- package/src/api/drawing tools/shapes menu/text.ts +0 -30
- package/src/api/drawingUtils.ts +0 -82
- package/src/core/CanvasLayer.ts +0 -77
- package/src/core/Chart.ts +0 -917
- package/src/core/CoordTransform.ts +0 -282
- package/src/core/Crosshair.ts +0 -207
- package/src/core/IndicatorEngine.ts +0 -216
- package/src/core/InteractionManager.ts +0 -899
- package/src/core/PriceScale.ts +0 -133
- package/src/core/Series.ts +0 -132
- package/src/core/TimeScale.ts +0 -175
- package/src/datafeed/DatafeedConnector.ts +0 -300
- package/src/engine/CandleEngine.ts +0 -458
- package/src/engine/__tests__/CandleEngine.test.ts +0 -402
- package/src/engine/candleInvariants.ts +0 -172
- package/src/index.ts +0 -190
- package/src/licensing/ChartRuntimeResolver.ts +0 -380
- package/src/licensing/LicenseManager.ts +0 -131
- package/src/licensing/__tests__/ChartRuntimeResolver.test.ts +0 -207
- package/src/licensing/__tests__/LicenseManager.test.ts +0 -180
- package/src/licensing/licenseTypes.ts +0 -19
- package/src/pine/PineCompiler.ts +0 -68
- package/src/pine/diagnostics.ts +0 -30
- package/src/pine/pine-ast.ts +0 -163
- package/src/pine/pine-lexer.ts +0 -265
- package/src/pine/pine-parser.ts +0 -439
- package/src/pine/pine-transpiler.ts +0 -301
- package/src/pixi/LayerName.ts +0 -35
- package/src/pixi/PixiCandlestickRenderer.ts +0 -125
- package/src/pixi/PixiChart.ts +0 -425
- package/src/pixi/PixiCrosshairRenderer.ts +0 -134
- package/src/pixi/PixiDrawingRenderer.ts +0 -121
- package/src/pixi/PixiGridRenderer.ts +0 -136
- package/src/pixi/PixiLayerManager.ts +0 -102
- package/src/renderers/CandlestickRenderer.ts +0 -130
- package/src/renderers/HistogramRenderer.ts +0 -63
- package/src/renderers/LineRenderer.ts +0 -77
- package/src/theme/colors.ts +0 -21
- package/src/tools/barDivergenceCheck.ts +0 -305
- package/src/trading/TradingOverlayStore.ts +0 -161
- package/src/trading/UnmanagedIngestion.ts +0 -156
- package/src/trading/__tests__/ManagedTradingController.test.ts +0 -338
- package/src/trading/__tests__/TradingOverlayStore.test.ts +0 -323
- package/src/trading/__tests__/UnmanagedIngestion.test.ts +0 -205
- package/src/trading/managed/ManagedTradingController.ts +0 -292
- package/src/trading/managed/managedCapabilities.ts +0 -98
- package/src/trading/managed/managedTypes.ts +0 -151
- package/src/trading/tradingTypes.ts +0 -135
- package/src/tscript/TScriptIndicator.ts +0 -54
- package/src/tscript/ast.ts +0 -105
- package/src/tscript/lexer.ts +0 -190
- package/src/tscript/parser.ts +0 -334
- package/src/tscript/runtime.ts +0 -525
- package/src/tscript/series.ts +0 -84
- package/src/types/IChart.ts +0 -56
- package/src/types/ISeries.ts +0 -30
- package/tsconfig.json +0 -22
- package/tsup.config.ts +0 -15
- package/vitest.config.ts +0 -25
|
@@ -1,402 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, vi } from 'vitest';
|
|
2
|
-
import { CandleEngine } from '../CandleEngine';
|
|
3
|
-
import type { CandleBar, RawOHLCV, UpdateResult, GapInfo } from '../CandleEngine';
|
|
4
|
-
import { timeframeToMs, getBucketStart } from '../timeframeUtils';
|
|
5
|
-
import { getMissingBarCount, mergeBars } from '../mergeUtils';
|
|
6
|
-
|
|
7
|
-
// ─── Helpers ─────────────────────────────────────────────────────────────────
|
|
8
|
-
|
|
9
|
-
/** Build a minimal raw bar with time in seconds. */
|
|
10
|
-
function rawBar(
|
|
11
|
-
timeSec: number,
|
|
12
|
-
open: number,
|
|
13
|
-
high: number,
|
|
14
|
-
low: number,
|
|
15
|
-
close: number,
|
|
16
|
-
volume = 1,
|
|
17
|
-
isClosed = false,
|
|
18
|
-
): RawOHLCV {
|
|
19
|
-
return { time: timeSec, open, high, low, close, volume, isClosed };
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
/** Build a raw bar with time in milliseconds. */
|
|
23
|
-
function rawBarMs(timeSec: number, open: number, high: number, low: number, close: number): RawOHLCV {
|
|
24
|
-
return { time: timeSec * 1000, open, high, low, close, volume: 1 };
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
// 1-minute boundary: 2024-07-03T10:00:00Z = 1719997200 seconds
|
|
28
|
-
const T0 = 1_719_997_200;
|
|
29
|
-
const T1 = T0 + 60;
|
|
30
|
-
const T2 = T0 + 120;
|
|
31
|
-
const T3 = T0 + 180;
|
|
32
|
-
const T4 = T0 + 240;
|
|
33
|
-
|
|
34
|
-
// ─── 1. Same-candle update ────────────────────────────────────────────────────
|
|
35
|
-
|
|
36
|
-
describe('same-candle update (3 ticks, same bucket)', () => {
|
|
37
|
-
it('produces exactly one candle with correct O/H/L/C', () => {
|
|
38
|
-
const engine = new CandleEngine();
|
|
39
|
-
engine.initialize([], '1m');
|
|
40
|
-
|
|
41
|
-
engine.applyLiveUpdate(rawBar(T0, 100, 105, 98, 103));
|
|
42
|
-
engine.applyLiveUpdate(rawBar(T0, 100, 108, 96, 107)); // high rises, low drops
|
|
43
|
-
engine.applyLiveUpdate(rawBar(T0, 100, 107, 97, 106)); // high recedes — not applied
|
|
44
|
-
|
|
45
|
-
expect(engine.getBars().length).toBe(1);
|
|
46
|
-
|
|
47
|
-
const bar = engine.getLastBar()!;
|
|
48
|
-
expect(bar.open).toBe(100); // open preserved from first tick
|
|
49
|
-
expect(bar.high).toBe(108); // max of all ticks
|
|
50
|
-
expect(bar.low).toBe(96); // min of all ticks
|
|
51
|
-
expect(bar.close).toBe(106); // close from latest tick
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
it('returns UpdateResult type "update" for same-candle ticks', () => {
|
|
55
|
-
const engine = new CandleEngine();
|
|
56
|
-
engine.initialize([], '1m');
|
|
57
|
-
|
|
58
|
-
const r1 = engine.applyLiveUpdate(rawBar(T0, 100, 100, 100, 100));
|
|
59
|
-
const r2 = engine.applyLiveUpdate(rawBar(T0, 100, 110, 90, 105));
|
|
60
|
-
|
|
61
|
-
expect(r1.type).toBe('append'); // first tick is an append
|
|
62
|
-
expect(r2.type).toBe('update');
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
it('high can never decrease within a candle', () => {
|
|
66
|
-
const engine = new CandleEngine();
|
|
67
|
-
engine.initialize([], '1m');
|
|
68
|
-
|
|
69
|
-
engine.applyLiveUpdate(rawBar(T0, 50, 120, 40, 100));
|
|
70
|
-
engine.applyLiveUpdate(rawBar(T0, 50, 80, 60, 90)); // high=80 < 120
|
|
71
|
-
|
|
72
|
-
expect(engine.getLastBar()!.high).toBe(120);
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
it('low can never increase within a candle', () => {
|
|
76
|
-
const engine = new CandleEngine();
|
|
77
|
-
engine.initialize([], '1m');
|
|
78
|
-
|
|
79
|
-
engine.applyLiveUpdate(rawBar(T0, 50, 120, 40, 100));
|
|
80
|
-
engine.applyLiveUpdate(rawBar(T0, 50, 110, 75, 105)); // low=75 > 40
|
|
81
|
-
|
|
82
|
-
expect(engine.getLastBar()!.low).toBe(40);
|
|
83
|
-
});
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
// ─── 2. New-candle append ─────────────────────────────────────────────────────
|
|
87
|
-
|
|
88
|
-
describe('new-candle append (time advances)', () => {
|
|
89
|
-
it('appends a second candle and marks first as closed', () => {
|
|
90
|
-
const engine = new CandleEngine();
|
|
91
|
-
engine.initialize([], '1m');
|
|
92
|
-
|
|
93
|
-
engine.applyLiveUpdate(rawBar(T0, 100, 105, 98, 103));
|
|
94
|
-
const result = engine.applyLiveUpdate(rawBar(T1, 103, 110, 101, 108));
|
|
95
|
-
|
|
96
|
-
expect(result.type).toBe('append');
|
|
97
|
-
expect(engine.getBars().length).toBe(2);
|
|
98
|
-
expect(engine.getBars()[0]!.isClosed).toBe(true);
|
|
99
|
-
expect(engine.getBars()[1]!.isClosed).toBe(false);
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
it('appended candle uses the new tick\'s open price', () => {
|
|
103
|
-
const engine = new CandleEngine();
|
|
104
|
-
engine.initialize([], '1m');
|
|
105
|
-
|
|
106
|
-
engine.applyLiveUpdate(rawBar(T0, 100, 105, 98, 103));
|
|
107
|
-
engine.applyLiveUpdate(rawBar(T1, 200, 210, 195, 205));
|
|
108
|
-
|
|
109
|
-
expect(engine.getBars()[1]!.open).toBe(200);
|
|
110
|
-
});
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
// ─── 3. Out-of-order discard ──────────────────────────────────────────────────
|
|
114
|
-
|
|
115
|
-
describe('out-of-order ticks', () => {
|
|
116
|
-
it('discards ticks older than the current live candle', () => {
|
|
117
|
-
const engine = new CandleEngine();
|
|
118
|
-
engine.initialize([], '1m');
|
|
119
|
-
|
|
120
|
-
engine.applyLiveUpdate(rawBar(T1, 103, 110, 100, 107)); // at T1
|
|
121
|
-
const result = engine.applyLiveUpdate(rawBar(T0, 100, 120, 95, 115)); // T0 < T1
|
|
122
|
-
|
|
123
|
-
expect(result.type).toBe('ignore');
|
|
124
|
-
expect(engine.getBars().length).toBe(1);
|
|
125
|
-
expect(engine.getLastBar()!.time).toBe(T1);
|
|
126
|
-
});
|
|
127
|
-
|
|
128
|
-
it('does not change any OHLCV values after discarding', () => {
|
|
129
|
-
const engine = new CandleEngine();
|
|
130
|
-
engine.initialize([], '1m');
|
|
131
|
-
|
|
132
|
-
engine.applyLiveUpdate(rawBar(T1, 103, 110, 100, 107));
|
|
133
|
-
const snapBefore = { ...engine.getLastBar()! };
|
|
134
|
-
|
|
135
|
-
engine.applyLiveUpdate(rawBar(T0, 999, 999, 1, 999));
|
|
136
|
-
|
|
137
|
-
expect(engine.getLastBar()!.open).toBe(snapBefore.open);
|
|
138
|
-
expect(engine.getLastBar()!.high).toBe(snapBefore.high);
|
|
139
|
-
expect(engine.getLastBar()!.low).toBe(snapBefore.low);
|
|
140
|
-
expect(engine.getLastBar()!.close).toBe(snapBefore.close);
|
|
141
|
-
});
|
|
142
|
-
});
|
|
143
|
-
|
|
144
|
-
// ─── 4. Gap detection ─────────────────────────────────────────────────────────
|
|
145
|
-
|
|
146
|
-
describe('gap detection', () => {
|
|
147
|
-
it('fires onGapDetected when a bucket is skipped', () => {
|
|
148
|
-
const gaps: GapInfo[] = [];
|
|
149
|
-
|
|
150
|
-
const engine = new CandleEngine({ onGapDetected: (g) => gaps.push(g) });
|
|
151
|
-
engine.initialize([], '1m');
|
|
152
|
-
|
|
153
|
-
engine.applyLiveUpdate(rawBar(T0, 100, 105, 98, 103));
|
|
154
|
-
// Jump 3 minutes — T1 and T2 are missing
|
|
155
|
-
engine.applyLiveUpdate(rawBar(T3, 110, 115, 108, 113));
|
|
156
|
-
|
|
157
|
-
expect(gaps.length).toBe(1);
|
|
158
|
-
expect(gaps[0]!.missingCount).toBe(2);
|
|
159
|
-
expect(gaps[0]!.fromTimeMs).toBe(T0 * 1000);
|
|
160
|
-
expect(gaps[0]!.toTimeMs).toBe(T3 * 1000);
|
|
161
|
-
});
|
|
162
|
-
|
|
163
|
-
it('returns UpdateResult type "gap" when a gap occurs', () => {
|
|
164
|
-
const engine = new CandleEngine();
|
|
165
|
-
engine.initialize([], '1m');
|
|
166
|
-
|
|
167
|
-
engine.applyLiveUpdate(rawBar(T0, 100, 105, 98, 103));
|
|
168
|
-
const result = engine.applyLiveUpdate(rawBar(T4, 103, 108, 101, 106));
|
|
169
|
-
|
|
170
|
-
expect(result.type).toBe('gap');
|
|
171
|
-
if (result.type === 'gap') {
|
|
172
|
-
expect(result.missingCount).toBe(3);
|
|
173
|
-
}
|
|
174
|
-
});
|
|
175
|
-
|
|
176
|
-
it('does not fire onGapDetected for consecutive candles', () => {
|
|
177
|
-
const gapFn = vi.fn();
|
|
178
|
-
const engine = new CandleEngine({ onGapDetected: gapFn });
|
|
179
|
-
engine.initialize([], '1m');
|
|
180
|
-
|
|
181
|
-
engine.applyLiveUpdate(rawBar(T0, 100, 105, 98, 103));
|
|
182
|
-
engine.applyLiveUpdate(rawBar(T1, 103, 108, 101, 106));
|
|
183
|
-
|
|
184
|
-
expect(gapFn).not.toHaveBeenCalled();
|
|
185
|
-
});
|
|
186
|
-
});
|
|
187
|
-
|
|
188
|
-
// ─── 5. Reconnect reconciliation ─────────────────────────────────────────────
|
|
189
|
-
|
|
190
|
-
describe('handleReconnect', () => {
|
|
191
|
-
it('deduplicates bars correctly when there is overlap', () => {
|
|
192
|
-
const engine = new CandleEngine();
|
|
193
|
-
engine.initialize([
|
|
194
|
-
rawBar(T0, 100, 105, 98, 103, 10, true),
|
|
195
|
-
rawBar(T1, 103, 108, 101, 106, 12, true),
|
|
196
|
-
rawBar(T2, 106, 110, 104, 109, 8, false), // live
|
|
197
|
-
], '1m');
|
|
198
|
-
|
|
199
|
-
// Reconnect brings T1 and T2 with corrected values
|
|
200
|
-
engine.handleReconnect([
|
|
201
|
-
rawBar(T1, 103, 112, 99, 111, 15, true), // corrected T1
|
|
202
|
-
rawBar(T2, 106, 111, 103, 110, 9, false), // corrected T2 (live)
|
|
203
|
-
]);
|
|
204
|
-
|
|
205
|
-
expect(engine.getBars().length).toBe(3);
|
|
206
|
-
expect(engine.getBars()[1]!.high).toBe(112); // T1 updated
|
|
207
|
-
expect(engine.getBars()[2]!.high).toBe(111); // T2 updated
|
|
208
|
-
});
|
|
209
|
-
|
|
210
|
-
it('fires onResync after handleReconnect', () => {
|
|
211
|
-
const resyncFn = vi.fn();
|
|
212
|
-
const engine = new CandleEngine({ onResync: resyncFn });
|
|
213
|
-
engine.initialize([rawBar(T0, 100, 105, 98, 103)], '1m');
|
|
214
|
-
|
|
215
|
-
engine.handleReconnect([rawBar(T0, 100, 107, 96, 104)]);
|
|
216
|
-
|
|
217
|
-
expect(resyncFn).toHaveBeenCalledOnce();
|
|
218
|
-
});
|
|
219
|
-
});
|
|
220
|
-
|
|
221
|
-
// ─── 6. ms → s timestamp conversion ─────────────────────────────────────────
|
|
222
|
-
|
|
223
|
-
describe('millisecond vs second timestamp normalisation', () => {
|
|
224
|
-
it('converts ms timestamps to seconds correctly', () => {
|
|
225
|
-
const engine = new CandleEngine();
|
|
226
|
-
engine.initialize([], '1m');
|
|
227
|
-
|
|
228
|
-
// T0 in ms
|
|
229
|
-
engine.applyLiveUpdate(rawBarMs(T0, 100, 105, 98, 103));
|
|
230
|
-
|
|
231
|
-
const bar = engine.getLastBar()!;
|
|
232
|
-
expect(bar.time).toBe(T0); // chart field = seconds
|
|
233
|
-
expect(bar.timeMs).toBe(T0 * 1000); // engine field = ms
|
|
234
|
-
});
|
|
235
|
-
|
|
236
|
-
it('handles both ms and s inputs in the same session without corruption', () => {
|
|
237
|
-
const engine = new CandleEngine();
|
|
238
|
-
engine.initialize([], '1m');
|
|
239
|
-
|
|
240
|
-
engine.applyLiveUpdate(rawBarMs(T0, 100, 105, 98, 103)); // ms
|
|
241
|
-
engine.applyLiveUpdate(rawBar(T0, 100, 110, 95, 108)); // seconds, same bucket
|
|
242
|
-
|
|
243
|
-
expect(engine.getBars().length).toBe(1); // same bucket → still one candle
|
|
244
|
-
expect(engine.getLastBar()!.high).toBe(110);
|
|
245
|
-
});
|
|
246
|
-
|
|
247
|
-
it('floors ms timestamp to candle boundary', () => {
|
|
248
|
-
const engine = new CandleEngine();
|
|
249
|
-
engine.initialize([], '1m');
|
|
250
|
-
|
|
251
|
-
// T0 + 30s (mid-candle) in ms → should still map to T0 bucket
|
|
252
|
-
engine.applyLiveUpdate({ time: (T0 + 30) * 1000, open: 100, high: 105, low: 98, close: 103 });
|
|
253
|
-
|
|
254
|
-
expect(engine.getLastBar()!.time).toBe(T0);
|
|
255
|
-
});
|
|
256
|
-
});
|
|
257
|
-
|
|
258
|
-
// ─── 7. Custom timeframe aggregation (timeframeUtils) ────────────────────────
|
|
259
|
-
|
|
260
|
-
describe('timeframeUtils helpers', () => {
|
|
261
|
-
it('timeframeToMs returns correct durations', () => {
|
|
262
|
-
expect(timeframeToMs('1m')).toBe(60_000);
|
|
263
|
-
expect(timeframeToMs('5m')).toBe(300_000);
|
|
264
|
-
expect(timeframeToMs('1h')).toBe(3_600_000);
|
|
265
|
-
expect(timeframeToMs('4h')).toBe(14_400_000);
|
|
266
|
-
expect(timeframeToMs('1d')).toBe(86_400_000);
|
|
267
|
-
// 1w and 1M are calendar timeframes — no fixed ms duration.
|
|
268
|
-
// timeframeUtils returns the 60_000 compat fallback so CandleEngine
|
|
269
|
-
// always receives a finite number (calendar alignment is handled separately).
|
|
270
|
-
expect(timeframeToMs('1w')).toBe(60_000);
|
|
271
|
-
});
|
|
272
|
-
|
|
273
|
-
it('timeframeToMs falls back to 60_000 for unknown labels', () => {
|
|
274
|
-
// '3h' and '8h' are orphaned (excluded from canonical registry) → 60_000 fallback.
|
|
275
|
-
// '2m' is now registered (120_000) — use genuinely unknown keys here.
|
|
276
|
-
expect(timeframeToMs('3h')).toBe(60_000);
|
|
277
|
-
expect(timeframeToMs('')).toBe(60_000);
|
|
278
|
-
});
|
|
279
|
-
|
|
280
|
-
it('getBucketStart floors to candle boundary', () => {
|
|
281
|
-
expect(getBucketStart(62_000, 60_000)).toBe(60_000); // 1m01s → 1m00s
|
|
282
|
-
expect(getBucketStart(3_720_000, 3_600_000)).toBe(3_600_000); // 1h02m → 1h00m
|
|
283
|
-
expect(getBucketStart(0, 60_000)).toBe(0);
|
|
284
|
-
});
|
|
285
|
-
|
|
286
|
-
it('5m candle engine buckets a mid-bar tick to the 5m open', () => {
|
|
287
|
-
const engine = new CandleEngine();
|
|
288
|
-
engine.initialize([], '5m');
|
|
289
|
-
|
|
290
|
-
const T5m = getBucketStart(T0 * 1000, timeframeToMs('5m')); // floor T0 to 5m
|
|
291
|
-
const mid = T5m / 1000 + 120; // 2 minutes into the 5m bucket
|
|
292
|
-
|
|
293
|
-
engine.applyLiveUpdate({ time: mid, open: 50, high: 55, low: 48, close: 52 });
|
|
294
|
-
|
|
295
|
-
expect(engine.getLastBar()!.timeMs).toBe(T5m);
|
|
296
|
-
});
|
|
297
|
-
});
|
|
298
|
-
|
|
299
|
-
// ─── 8. mergeUtils helpers ────────────────────────────────────────────────────
|
|
300
|
-
|
|
301
|
-
describe('mergeUtils helpers', () => {
|
|
302
|
-
const makeBar = (timeSec: number, close: number, isClosed: boolean): CandleBar => ({
|
|
303
|
-
timeMs: timeSec * 1000,
|
|
304
|
-
time: timeSec,
|
|
305
|
-
open: 100, high: 110, low: 90, close,
|
|
306
|
-
volume: 1, isClosed,
|
|
307
|
-
});
|
|
308
|
-
|
|
309
|
-
it('getMissingBarCount returns 0 for consecutive bars', () => {
|
|
310
|
-
expect(getMissingBarCount(T0 * 1000, T1 * 1000, 60_000)).toBe(0);
|
|
311
|
-
});
|
|
312
|
-
|
|
313
|
-
it('getMissingBarCount returns correct count for gap', () => {
|
|
314
|
-
expect(getMissingBarCount(T0 * 1000, T3 * 1000, 60_000)).toBe(2); // T1 and T2
|
|
315
|
-
expect(getMissingBarCount(T0 * 1000, T4 * 1000, 60_000)).toBe(3); // T1, T2, T3
|
|
316
|
-
});
|
|
317
|
-
|
|
318
|
-
it('mergeBars deduplicates by timeMs with incoming winning', () => {
|
|
319
|
-
const existing = [makeBar(T0, 103, true), makeBar(T1, 106, true)];
|
|
320
|
-
const incoming = [makeBar(T1, 999, true), makeBar(T2, 110, false)]; // T1 override
|
|
321
|
-
|
|
322
|
-
const merged = mergeBars(existing, incoming);
|
|
323
|
-
|
|
324
|
-
expect(merged.length).toBe(3);
|
|
325
|
-
expect(merged[1]!.close).toBe(999); // incoming wins for closed bar
|
|
326
|
-
expect(merged[2]!.time).toBe(T2);
|
|
327
|
-
});
|
|
328
|
-
|
|
329
|
-
it('mergeBars preserves existing live candle when incoming is also live and same time', () => {
|
|
330
|
-
const existing = [makeBar(T0, 103, false)]; // live, close=103
|
|
331
|
-
const incoming = [makeBar(T0, 107, false)]; // fresher live tick, close=107
|
|
332
|
-
|
|
333
|
-
const merged = mergeBars(existing, incoming);
|
|
334
|
-
|
|
335
|
-
// Live bar: incoming wins because it is the freshest tick
|
|
336
|
-
expect(merged[0]!.close).toBe(107);
|
|
337
|
-
});
|
|
338
|
-
|
|
339
|
-
it('mergeBars sorts output by timeMs', () => {
|
|
340
|
-
const bars = [makeBar(T2, 100, true), makeBar(T0, 100, true), makeBar(T1, 100, true)];
|
|
341
|
-
const sorted = mergeBars(bars, []);
|
|
342
|
-
expect(sorted.map(b => b.time)).toEqual([T0, T1, T2]);
|
|
343
|
-
});
|
|
344
|
-
});
|
|
345
|
-
|
|
346
|
-
// ─── 9. backfillGap ───────────────────────────────────────────────────────────
|
|
347
|
-
|
|
348
|
-
describe('backfillGap', () => {
|
|
349
|
-
it('fills missing buckets and fires onResync', () => {
|
|
350
|
-
const resyncFn = vi.fn();
|
|
351
|
-
|
|
352
|
-
const engine = new CandleEngine({ onResync: resyncFn });
|
|
353
|
-
engine.initialize([
|
|
354
|
-
rawBar(T0, 100, 105, 98, 103),
|
|
355
|
-
rawBar(T3, 110, 115, 108, 113), // gap: T1, T2 missing
|
|
356
|
-
], '1m');
|
|
357
|
-
|
|
358
|
-
engine.backfillGap([
|
|
359
|
-
rawBar(T1, 103, 108, 101, 106),
|
|
360
|
-
rawBar(T2, 106, 110, 104, 109),
|
|
361
|
-
]);
|
|
362
|
-
|
|
363
|
-
expect(engine.getBars().length).toBe(4);
|
|
364
|
-
expect(resyncFn).toHaveBeenCalledOnce();
|
|
365
|
-
|
|
366
|
-
const times = engine.getBars().map(b => b.time);
|
|
367
|
-
expect(times).toEqual([T0, T1, T2, T3]);
|
|
368
|
-
});
|
|
369
|
-
});
|
|
370
|
-
|
|
371
|
-
// ─── 10. CandleEngine lifecycle ──────────────────────────────────────────────
|
|
372
|
-
|
|
373
|
-
describe('lifecycle', () => {
|
|
374
|
-
it('reset() clears all bars', () => {
|
|
375
|
-
const engine = new CandleEngine();
|
|
376
|
-
engine.initialize([rawBar(T0, 100, 105, 98, 103)], '1m');
|
|
377
|
-
|
|
378
|
-
engine.reset();
|
|
379
|
-
|
|
380
|
-
expect(engine.getBars().length).toBe(0);
|
|
381
|
-
expect(engine.getLastBar()).toBeNull();
|
|
382
|
-
});
|
|
383
|
-
|
|
384
|
-
it('handles initialize() with empty history', () => {
|
|
385
|
-
const engine = new CandleEngine();
|
|
386
|
-
engine.initialize([], '1m');
|
|
387
|
-
|
|
388
|
-
expect(engine.getBars().length).toBe(0);
|
|
389
|
-
expect(engine.getLastBar()).toBeNull();
|
|
390
|
-
});
|
|
391
|
-
|
|
392
|
-
it('handles duplicate historical bars (keeps last per timeMs)', () => {
|
|
393
|
-
const engine = new CandleEngine();
|
|
394
|
-
engine.initialize([
|
|
395
|
-
rawBar(T0, 100, 105, 98, 103),
|
|
396
|
-
rawBar(T0, 100, 110, 96, 108), // same time, last should win
|
|
397
|
-
], '1m');
|
|
398
|
-
|
|
399
|
-
expect(engine.getBars().length).toBe(1);
|
|
400
|
-
expect(engine.getLastBar()!.high).toBe(110);
|
|
401
|
-
});
|
|
402
|
-
});
|
|
@@ -1,172 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Candle Invariant Guards
|
|
3
|
-
*
|
|
4
|
-
* Defensive assertions for the CandleEngine update pipeline.
|
|
5
|
-
* All guards are no-ops in production (`NODE_ENV === 'production'`).
|
|
6
|
-
*
|
|
7
|
-
* Design principles:
|
|
8
|
-
* - Each guard checks exactly ONE invariant and logs a descriptive warning.
|
|
9
|
-
* - Guards never throw by default — they warn so streaming data is never blocked.
|
|
10
|
-
* - Call sites pass a `context` string that identifies where the check ran.
|
|
11
|
-
* - A test harness can replace `_reporter` to assert on violations.
|
|
12
|
-
*
|
|
13
|
-
* Usage:
|
|
14
|
-
* import { assertOhlcRelationships, assertNotFinalized } from './candleInvariants';
|
|
15
|
-
*/
|
|
16
|
-
|
|
17
|
-
import type { CandleBar } from './CandleEngine';
|
|
18
|
-
import { getCalendarBucketStart } from './timeframeUtils';
|
|
19
|
-
|
|
20
|
-
// ─── Reporter (swappable in tests) ───────────────────────────────────────────
|
|
21
|
-
|
|
22
|
-
/** Called for every invariant violation. Replaced in unit tests. */
|
|
23
|
-
export let _reporter: (message: string) => void = (msg) => console.warn(msg);
|
|
24
|
-
|
|
25
|
-
/** Replace the violation reporter (for unit-test assertions). */
|
|
26
|
-
export function _setReporter(fn: (message: string) => void): void {
|
|
27
|
-
_reporter = fn;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/** Re-install the default console.warn reporter. */
|
|
31
|
-
export function _resetReporter(): void {
|
|
32
|
-
_reporter = (msg) => console.warn(msg);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
// ─── Dev guard ───────────────────────────────────────────────────────────────
|
|
36
|
-
|
|
37
|
-
function isDevMode(): boolean {
|
|
38
|
-
// Access process via globalThis to avoid relying on @types/node in browser builds
|
|
39
|
-
const nodeEnv = (globalThis as { process?: { env?: { NODE_ENV?: string } } })
|
|
40
|
-
.process?.env?.['NODE_ENV'];
|
|
41
|
-
return nodeEnv !== 'production';
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
function violation(context: string, message: string): void {
|
|
45
|
-
_reporter(`[CANDLE_INVARIANT] ${context}: ${message}`);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
// ─── Guards ───────────────────────────────────────────────────────────────────
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* Verify that `high >= open, close, low` and `low <= open, close`.
|
|
52
|
-
*
|
|
53
|
-
* Floats from external feeds can occasionally violate these due to rounding.
|
|
54
|
-
* This guard surfaces them immediately rather than silently corrupting the chart.
|
|
55
|
-
*/
|
|
56
|
-
export function assertOhlcRelationships(bar: CandleBar, context: string): void {
|
|
57
|
-
if (!isDevMode()) return;
|
|
58
|
-
|
|
59
|
-
const { open, high, low, close, timeMs } = bar;
|
|
60
|
-
|
|
61
|
-
if (high < open) violation(context, `high(${high}) < open(${open}) at timeMs=${timeMs}`);
|
|
62
|
-
if (high < close) violation(context, `high(${high}) < close(${close}) at timeMs=${timeMs}`);
|
|
63
|
-
if (high < low) violation(context, `high(${high}) < low(${low}) at timeMs=${timeMs}`);
|
|
64
|
-
if (low > open) violation(context, `low(${low}) > open(${open}) at timeMs=${timeMs}`);
|
|
65
|
-
if (low > close) violation(context, `low(${low}) > close(${close}) at timeMs=${timeMs}`);
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* Verify that `bar.timeMs` is exactly equal to the candle-open boundary for the
|
|
70
|
-
* given timeframe. If it is not, `normalizeOhlcv` or `getCalendarBucketStart`
|
|
71
|
-
* has a bug.
|
|
72
|
-
*/
|
|
73
|
-
export function assertBucketAlignment(bar: CandleBar, tf: string, context: string): void {
|
|
74
|
-
if (!isDevMode()) return;
|
|
75
|
-
|
|
76
|
-
const expected = getCalendarBucketStart(bar.timeMs, tf);
|
|
77
|
-
if (bar.timeMs !== expected) {
|
|
78
|
-
violation(
|
|
79
|
-
context,
|
|
80
|
-
`timeMs(${bar.timeMs}) ≠ bucketStart(${expected}) for tf=${tf} ` +
|
|
81
|
-
`(delta=${bar.timeMs - expected} ms)`,
|
|
82
|
-
);
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* Verify that we are NOT about to mutate a candle that has already been finalised
|
|
88
|
-
* (`isClosed === true`). Mutating a closed candle corrupts the historical record.
|
|
89
|
-
*
|
|
90
|
-
* Triggers on: same-bucket update landing on a bar already marked closed.
|
|
91
|
-
*/
|
|
92
|
-
export function assertNotFinalized(bar: CandleBar, context: string): void {
|
|
93
|
-
if (!isDevMode()) return;
|
|
94
|
-
|
|
95
|
-
if (bar.isClosed) {
|
|
96
|
-
violation(
|
|
97
|
-
context,
|
|
98
|
-
`attempted to mutate a finalized (isClosed=true) candle at timeMs=${bar.timeMs}`,
|
|
99
|
-
);
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
/**
|
|
104
|
-
* Verify that a same-bucket update did NOT silently overwrite the candle's `open`.
|
|
105
|
-
*
|
|
106
|
-
* The first tick's open is authoritative; subsequent updates for the same bucket
|
|
107
|
-
* must preserve it. Call this AFTER the in-place mutation with the captured
|
|
108
|
-
* `prevOpen` value.
|
|
109
|
-
*/
|
|
110
|
-
export function assertOpenImmutability(
|
|
111
|
-
prevOpen: number,
|
|
112
|
-
bar: CandleBar,
|
|
113
|
-
context: string,
|
|
114
|
-
): void {
|
|
115
|
-
if (!isDevMode()) return;
|
|
116
|
-
|
|
117
|
-
if (bar.open !== prevOpen) {
|
|
118
|
-
violation(
|
|
119
|
-
context,
|
|
120
|
-
`open changed from ${prevOpen} → ${bar.open} on same-bucket update ` +
|
|
121
|
-
`at timeMs=${bar.timeMs} — first-tick open is authoritative`,
|
|
122
|
-
);
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
/**
|
|
127
|
-
* Verify that a same-bucket update does NOT append a new bar instead of
|
|
128
|
-
* updating the existing one.
|
|
129
|
-
*
|
|
130
|
-
* Call after an in-place update with the pre- and post-update bar counts.
|
|
131
|
-
*/
|
|
132
|
-
export function assertNoDuplicateAppend(
|
|
133
|
-
prevCount: number,
|
|
134
|
-
nextCount: number,
|
|
135
|
-
context: string,
|
|
136
|
-
): void {
|
|
137
|
-
if (!isDevMode()) return;
|
|
138
|
-
|
|
139
|
-
if (nextCount > prevCount) {
|
|
140
|
-
violation(
|
|
141
|
-
context,
|
|
142
|
-
`same-bucket update incremented bar count from ${prevCount} → ${nextCount} ` +
|
|
143
|
-
`(should have updated in-place, not appended)`,
|
|
144
|
-
);
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
/**
|
|
149
|
-
* Verify that a new-bucket append does NOT reduce the bar count or silently
|
|
150
|
-
* overwrite a finalized candle (would require bar count to stay the same while
|
|
151
|
-
* the last bar's timeMs changes, which the engine never does).
|
|
152
|
-
*
|
|
153
|
-
* Call after appending a new bar with the previous last bar for comparison.
|
|
154
|
-
*/
|
|
155
|
-
export function assertFinalizedUnchanged(
|
|
156
|
-
prevLastBar: Readonly<CandleBar>,
|
|
157
|
-
currentBars: readonly CandleBar[],
|
|
158
|
-
context: string,
|
|
159
|
-
): void {
|
|
160
|
-
if (!isDevMode()) return;
|
|
161
|
-
|
|
162
|
-
const prevIndex = currentBars.findIndex(b => b.timeMs === prevLastBar.timeMs);
|
|
163
|
-
if (prevIndex === -1) return; // bar may have been legitimately removed by merge
|
|
164
|
-
|
|
165
|
-
const preserved = currentBars[prevIndex]!;
|
|
166
|
-
if (!preserved.isClosed) {
|
|
167
|
-
violation(
|
|
168
|
-
context,
|
|
169
|
-
`bar at timeMs=${prevLastBar.timeMs} should be isClosed=true after new-bucket append`,
|
|
170
|
-
);
|
|
171
|
-
}
|
|
172
|
-
}
|