@363045841yyt/klinechart-core 0.8.11-alpha.0 → 0.8.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (578) hide show
  1. package/dist/alerts/createAlertController.d.ts +30 -0
  2. package/dist/alerts/createAlertController.d.ts.map +1 -0
  3. package/dist/alerts/createAlertController.js +261 -0
  4. package/dist/alerts/createAlertController.js.map +1 -0
  5. package/dist/alerts/index.d.ts +5 -0
  6. package/dist/alerts/index.d.ts.map +1 -0
  7. package/dist/alerts/index.js +4 -0
  8. package/dist/alerts/index.js.map +1 -0
  9. package/dist/alerts/predicates.d.ts +28 -0
  10. package/dist/alerts/predicates.d.ts.map +1 -0
  11. package/dist/alerts/predicates.js +211 -0
  12. package/dist/alerts/predicates.js.map +1 -0
  13. package/dist/alerts/rollingVolume.d.ts +15 -0
  14. package/dist/alerts/rollingVolume.d.ts.map +1 -0
  15. package/dist/alerts/rollingVolume.js +42 -0
  16. package/dist/alerts/rollingVolume.js.map +1 -0
  17. package/dist/alerts/ruleSchema.d.ts +42 -0
  18. package/dist/alerts/ruleSchema.d.ts.map +1 -0
  19. package/dist/alerts/ruleSchema.js +240 -0
  20. package/dist/alerts/ruleSchema.js.map +1 -0
  21. package/dist/alerts/types.d.ts +169 -0
  22. package/dist/alerts/types.d.ts.map +1 -0
  23. package/dist/alerts/types.js +24 -0
  24. package/dist/alerts/types.js.map +1 -0
  25. package/dist/chartTypes/heikinAshi.d.ts +49 -0
  26. package/dist/chartTypes/heikinAshi.d.ts.map +1 -0
  27. package/dist/chartTypes/heikinAshi.js +94 -0
  28. package/dist/chartTypes/heikinAshi.js.map +1 -0
  29. package/dist/chartTypes/index.d.ts +6 -0
  30. package/dist/chartTypes/index.d.ts.map +1 -0
  31. package/dist/chartTypes/index.js +5 -0
  32. package/dist/chartTypes/index.js.map +1 -0
  33. package/dist/chartTypes/pointAndFigure.d.ts +83 -0
  34. package/dist/chartTypes/pointAndFigure.d.ts.map +1 -0
  35. package/dist/chartTypes/pointAndFigure.js +159 -0
  36. package/dist/chartTypes/pointAndFigure.js.map +1 -0
  37. package/dist/chartTypes/rangeBars.d.ts +61 -0
  38. package/dist/chartTypes/rangeBars.d.ts.map +1 -0
  39. package/dist/chartTypes/rangeBars.js +181 -0
  40. package/dist/chartTypes/rangeBars.js.map +1 -0
  41. package/dist/chartTypes/renko.d.ts +94 -0
  42. package/dist/chartTypes/renko.d.ts.map +1 -0
  43. package/dist/chartTypes/renko.js +207 -0
  44. package/dist/chartTypes/renko.js.map +1 -0
  45. package/dist/chartTypes/types.d.ts +97 -0
  46. package/dist/chartTypes/types.d.ts.map +1 -0
  47. package/dist/chartTypes/types.js +39 -0
  48. package/dist/chartTypes/types.js.map +1 -0
  49. package/dist/components/anchoredVwap/computeAnchoredVwap.d.ts +76 -0
  50. package/dist/components/anchoredVwap/computeAnchoredVwap.d.ts.map +1 -0
  51. package/dist/components/anchoredVwap/computeAnchoredVwap.js +155 -0
  52. package/dist/components/anchoredVwap/computeAnchoredVwap.js.map +1 -0
  53. package/dist/components/anchoredVwap/createAnchoredVwapController.d.ts +28 -0
  54. package/dist/components/anchoredVwap/createAnchoredVwapController.d.ts.map +1 -0
  55. package/dist/components/anchoredVwap/createAnchoredVwapController.js +282 -0
  56. package/dist/components/anchoredVwap/createAnchoredVwapController.js.map +1 -0
  57. package/dist/components/anchoredVwap/index.d.ts +11 -0
  58. package/dist/components/anchoredVwap/index.d.ts.map +1 -0
  59. package/dist/components/anchoredVwap/index.js +10 -0
  60. package/dist/components/anchoredVwap/index.js.map +1 -0
  61. package/dist/components/anchoredVwap/types.d.ts +171 -0
  62. package/dist/components/anchoredVwap/types.d.ts.map +1 -0
  63. package/dist/components/anchoredVwap/types.js +25 -0
  64. package/dist/components/anchoredVwap/types.js.map +1 -0
  65. package/dist/components/crosshairSync/createCrosshairSync.d.ts +94 -0
  66. package/dist/components/crosshairSync/createCrosshairSync.d.ts.map +1 -0
  67. package/dist/components/crosshairSync/createCrosshairSync.js +118 -0
  68. package/dist/components/crosshairSync/createCrosshairSync.js.map +1 -0
  69. package/dist/components/crosshairSync/index.d.ts +2 -0
  70. package/dist/components/crosshairSync/index.d.ts.map +1 -0
  71. package/dist/components/crosshairSync/index.js +2 -0
  72. package/dist/components/crosshairSync/index.js.map +1 -0
  73. package/dist/components/footprint/aggressor.d.ts +89 -0
  74. package/dist/components/footprint/aggressor.d.ts.map +1 -0
  75. package/dist/components/footprint/aggressor.js +106 -0
  76. package/dist/components/footprint/aggressor.js.map +1 -0
  77. package/dist/components/footprint/createFootprintController.d.ts +29 -0
  78. package/dist/components/footprint/createFootprintController.d.ts.map +1 -0
  79. package/dist/components/footprint/createFootprintController.js +264 -0
  80. package/dist/components/footprint/createFootprintController.js.map +1 -0
  81. package/dist/components/footprint/index.d.ts +7 -0
  82. package/dist/components/footprint/index.d.ts.map +1 -0
  83. package/dist/components/footprint/index.js +4 -0
  84. package/dist/components/footprint/index.js.map +1 -0
  85. package/dist/components/footprint/perBarStats.d.ts +63 -0
  86. package/dist/components/footprint/perBarStats.d.ts.map +1 -0
  87. package/dist/components/footprint/perBarStats.js +123 -0
  88. package/dist/components/footprint/perBarStats.js.map +1 -0
  89. package/dist/components/footprint/types.d.ts +197 -0
  90. package/dist/components/footprint/types.d.ts.map +1 -0
  91. package/dist/components/footprint/types.js +23 -0
  92. package/dist/components/footprint/types.js.map +1 -0
  93. package/dist/components/mtfOverlay/alignToBaseIndex.d.ts +45 -0
  94. package/dist/components/mtfOverlay/alignToBaseIndex.d.ts.map +1 -0
  95. package/dist/components/mtfOverlay/alignToBaseIndex.js +92 -0
  96. package/dist/components/mtfOverlay/alignToBaseIndex.js.map +1 -0
  97. package/dist/components/mtfOverlay/createMtfController.d.ts +7 -0
  98. package/dist/components/mtfOverlay/createMtfController.d.ts.map +1 -0
  99. package/dist/components/mtfOverlay/createMtfController.js +134 -0
  100. package/dist/components/mtfOverlay/createMtfController.js.map +1 -0
  101. package/dist/components/mtfOverlay/index.d.ts +19 -0
  102. package/dist/components/mtfOverlay/index.d.ts.map +1 -0
  103. package/dist/components/mtfOverlay/index.js +18 -0
  104. package/dist/components/mtfOverlay/index.js.map +1 -0
  105. package/dist/components/mtfOverlay/resampleBars.d.ts +37 -0
  106. package/dist/components/mtfOverlay/resampleBars.d.ts.map +1 -0
  107. package/dist/components/mtfOverlay/resampleBars.js +93 -0
  108. package/dist/components/mtfOverlay/resampleBars.js.map +1 -0
  109. package/dist/components/mtfOverlay/types.d.ts +132 -0
  110. package/dist/components/mtfOverlay/types.d.ts.map +1 -0
  111. package/dist/components/mtfOverlay/types.js +22 -0
  112. package/dist/components/mtfOverlay/types.js.map +1 -0
  113. package/dist/components/orderBookHeatmap/createHeatmapController.d.ts +21 -0
  114. package/dist/components/orderBookHeatmap/createHeatmapController.d.ts.map +1 -0
  115. package/dist/components/orderBookHeatmap/createHeatmapController.js +234 -0
  116. package/dist/components/orderBookHeatmap/createHeatmapController.js.map +1 -0
  117. package/dist/components/orderBookHeatmap/createOrderBookState.d.ts +18 -0
  118. package/dist/components/orderBookHeatmap/createOrderBookState.d.ts.map +1 -0
  119. package/dist/components/orderBookHeatmap/createOrderBookState.js +102 -0
  120. package/dist/components/orderBookHeatmap/createOrderBookState.js.map +1 -0
  121. package/dist/components/orderBookHeatmap/deltaArchive.d.ts +25 -0
  122. package/dist/components/orderBookHeatmap/deltaArchive.d.ts.map +1 -0
  123. package/dist/components/orderBookHeatmap/deltaArchive.js +106 -0
  124. package/dist/components/orderBookHeatmap/deltaArchive.js.map +1 -0
  125. package/dist/components/orderBookHeatmap/index.d.ts +13 -0
  126. package/dist/components/orderBookHeatmap/index.d.ts.map +1 -0
  127. package/dist/components/orderBookHeatmap/index.js +12 -0
  128. package/dist/components/orderBookHeatmap/index.js.map +1 -0
  129. package/dist/components/orderBookHeatmap/logColorScale.d.ts +20 -0
  130. package/dist/components/orderBookHeatmap/logColorScale.d.ts.map +1 -0
  131. package/dist/components/orderBookHeatmap/logColorScale.js +71 -0
  132. package/dist/components/orderBookHeatmap/logColorScale.js.map +1 -0
  133. package/dist/components/orderBookHeatmap/snapshotRing.d.ts +16 -0
  134. package/dist/components/orderBookHeatmap/snapshotRing.d.ts.map +1 -0
  135. package/dist/components/orderBookHeatmap/snapshotRing.js +61 -0
  136. package/dist/components/orderBookHeatmap/snapshotRing.js.map +1 -0
  137. package/dist/components/orderBookHeatmap/types.d.ts +128 -0
  138. package/dist/components/orderBookHeatmap/types.d.ts.map +1 -0
  139. package/dist/components/orderBookHeatmap/types.js +16 -0
  140. package/dist/components/orderBookHeatmap/types.js.map +1 -0
  141. package/dist/components/volumeProfile/binning.d.ts +54 -0
  142. package/dist/components/volumeProfile/binning.d.ts.map +1 -0
  143. package/dist/components/volumeProfile/binning.js +123 -0
  144. package/dist/components/volumeProfile/binning.js.map +1 -0
  145. package/dist/components/volumeProfile/createVolumeProfileController.d.ts +31 -0
  146. package/dist/components/volumeProfile/createVolumeProfileController.d.ts.map +1 -0
  147. package/dist/components/volumeProfile/createVolumeProfileController.js +179 -0
  148. package/dist/components/volumeProfile/createVolumeProfileController.js.map +1 -0
  149. package/dist/components/volumeProfile/index.d.ts +6 -0
  150. package/dist/components/volumeProfile/index.d.ts.map +1 -0
  151. package/dist/components/volumeProfile/index.js +5 -0
  152. package/dist/components/volumeProfile/index.js.map +1 -0
  153. package/dist/components/volumeProfile/poc.d.ts +35 -0
  154. package/dist/components/volumeProfile/poc.d.ts.map +1 -0
  155. package/dist/components/volumeProfile/poc.js +51 -0
  156. package/dist/components/volumeProfile/poc.js.map +1 -0
  157. package/dist/components/volumeProfile/types.d.ts +138 -0
  158. package/dist/components/volumeProfile/types.d.ts.map +1 -0
  159. package/dist/components/volumeProfile/types.js +19 -0
  160. package/dist/components/volumeProfile/types.js.map +1 -0
  161. package/dist/components/volumeProfile/valueArea.d.ts +58 -0
  162. package/dist/components/volumeProfile/valueArea.d.ts.map +1 -0
  163. package/dist/components/volumeProfile/valueArea.js +172 -0
  164. package/dist/components/volumeProfile/valueArea.js.map +1 -0
  165. package/dist/controllers/createChartController.d.ts.map +1 -1
  166. package/dist/controllers/createChartController.js +22 -11
  167. package/dist/controllers/createChartController.js.map +1 -1
  168. package/dist/controllers/types.d.ts +3 -1
  169. package/dist/controllers/types.d.ts.map +1 -1
  170. package/dist/data-fetchers/baostock.d.ts.map +1 -1
  171. package/dist/data-fetchers/baostock.js +2 -1
  172. package/dist/data-fetchers/baostock.js.map +1 -1
  173. package/dist/data-fetchers/dataBuffer.effects.d.ts.map +1 -1
  174. package/dist/data-fetchers/dataBuffer.effects.js +2 -1
  175. package/dist/data-fetchers/dataBuffer.effects.js.map +1 -1
  176. package/dist/data-fetchers/fetcherDefinitionRegistry.d.ts.map +1 -1
  177. package/dist/data-fetchers/fetcherDefinitionRegistry.js +2 -1
  178. package/dist/data-fetchers/fetcherDefinitionRegistry.js.map +1 -1
  179. package/dist/data-fetchers/gotdx.js +4 -3
  180. package/dist/data-fetchers/gotdx.js.map +1 -1
  181. package/dist/data-fetchers/router.d.ts.map +1 -1
  182. package/dist/data-fetchers/router.js +4 -3
  183. package/dist/data-fetchers/router.js.map +1 -1
  184. package/dist/data-fetchers/tradingview.js +3 -2
  185. package/dist/data-fetchers/tradingview.js.map +1 -1
  186. package/dist/engine/chart.d.ts +13 -0
  187. package/dist/engine/chart.d.ts.map +1 -1
  188. package/dist/engine/chart.js +109 -0
  189. package/dist/engine/chart.js.map +1 -1
  190. package/dist/engine/data/chartDataManager.d.ts +1 -0
  191. package/dist/engine/data/chartDataManager.d.ts.map +1 -1
  192. package/dist/engine/data/chartDataManager.js +27 -4
  193. package/dist/engine/data/chartDataManager.js.map +1 -1
  194. package/dist/engine/drawing/toolConfig.d.ts.map +1 -1
  195. package/dist/engine/drawing/toolConfig.js +2 -1
  196. package/dist/engine/drawing/toolConfig.js.map +1 -1
  197. package/dist/engine/indicators/chartIndicatorManager.d.ts.map +1 -1
  198. package/dist/engine/indicators/chartIndicatorManager.js +2 -1
  199. package/dist/engine/indicators/chartIndicatorManager.js.map +1 -1
  200. package/dist/engine/indicators/indicatorDefinitionRegistry.d.ts.map +1 -1
  201. package/dist/engine/indicators/indicatorDefinitionRegistry.js +2 -1
  202. package/dist/engine/indicators/indicatorDefinitionRegistry.js.map +1 -1
  203. package/dist/engine/indicators/indicatorMetadata.d.ts.map +1 -1
  204. package/dist/engine/indicators/indicatorMetadata.js +2 -1
  205. package/dist/engine/indicators/indicatorMetadata.js.map +1 -1
  206. package/dist/engine/indicators/indicatorRegistry.d.ts.map +1 -1
  207. package/dist/engine/indicators/indicatorRegistry.js +6 -5
  208. package/dist/engine/indicators/indicatorRegistry.js.map +1 -1
  209. package/dist/engine/indicators/registerBuiltins.d.ts.map +1 -1
  210. package/dist/engine/indicators/registerBuiltins.js +2 -1
  211. package/dist/engine/indicators/registerBuiltins.js.map +1 -1
  212. package/dist/engine/indicators/scheduler.d.ts +6 -0
  213. package/dist/engine/indicators/scheduler.d.ts.map +1 -1
  214. package/dist/engine/indicators/scheduler.js +12 -0
  215. package/dist/engine/indicators/scheduler.js.map +1 -1
  216. package/dist/engine/indicators/soa.d.ts.map +1 -1
  217. package/dist/engine/indicators/soa.js +2 -1
  218. package/dist/engine/indicators/soa.js.map +1 -1
  219. package/dist/engine/indicators/stateComposer.d.ts.map +1 -1
  220. package/dist/engine/indicators/stateComposer.js +2 -1
  221. package/dist/engine/indicators/stateComposer.js.map +1 -1
  222. package/dist/engine/subPaneManager.d.ts.map +1 -1
  223. package/dist/engine/subPaneManager.js +2 -1
  224. package/dist/engine/subPaneManager.js.map +1 -1
  225. package/dist/engine/utils/chartZoomController.d.ts +2 -0
  226. package/dist/engine/utils/chartZoomController.d.ts.map +1 -1
  227. package/dist/engine/utils/chartZoomController.js +5 -1
  228. package/dist/engine/utils/chartZoomController.js.map +1 -1
  229. package/dist/errors-help.d.ts +72 -0
  230. package/dist/errors-help.d.ts.map +1 -0
  231. package/dist/errors-help.js +149 -0
  232. package/dist/errors-help.js.map +1 -0
  233. package/dist/errors.d.ts +64 -0
  234. package/dist/errors.d.ts.map +1 -0
  235. package/dist/errors.js +61 -0
  236. package/dist/errors.js.map +1 -0
  237. package/dist/index.d.ts +18 -0
  238. package/dist/index.d.ts.map +1 -1
  239. package/dist/index.js +22 -0
  240. package/dist/index.js.map +1 -1
  241. package/dist/indicators/alma.d.ts +27 -0
  242. package/dist/indicators/alma.d.ts.map +1 -0
  243. package/dist/indicators/alma.js +36 -0
  244. package/dist/indicators/alma.js.map +1 -0
  245. package/dist/indicators/awesomeOscillator.d.ts +19 -0
  246. package/dist/indicators/awesomeOscillator.d.ts.map +1 -0
  247. package/dist/indicators/awesomeOscillator.js +36 -0
  248. package/dist/indicators/awesomeOscillator.js.map +1 -0
  249. package/dist/indicators/dpo.d.ts +17 -0
  250. package/dist/indicators/dpo.d.ts.map +1 -0
  251. package/dist/indicators/dpo.js +24 -0
  252. package/dist/indicators/dpo.js.map +1 -0
  253. package/dist/indicators/fisherTransform.d.ts +26 -0
  254. package/dist/indicators/fisherTransform.d.ts.map +1 -0
  255. package/dist/indicators/fisherTransform.js +44 -0
  256. package/dist/indicators/fisherTransform.js.map +1 -0
  257. package/dist/indicators/frama.d.ts +25 -0
  258. package/dist/indicators/frama.d.ts.map +1 -0
  259. package/dist/indicators/frama.js +61 -0
  260. package/dist/indicators/frama.js.map +1 -0
  261. package/dist/indicators/index.d.ts +24 -0
  262. package/dist/indicators/index.d.ts.map +1 -0
  263. package/dist/indicators/index.js +26 -0
  264. package/dist/indicators/index.js.map +1 -0
  265. package/dist/indicators/lsma.d.ts +21 -0
  266. package/dist/indicators/lsma.d.ts.map +1 -0
  267. package/dist/indicators/lsma.js +37 -0
  268. package/dist/indicators/lsma.js.map +1 -0
  269. package/dist/indicators/schaffTrendCycle.d.ts +24 -0
  270. package/dist/indicators/schaffTrendCycle.d.ts.map +1 -0
  271. package/dist/indicators/schaffTrendCycle.js +70 -0
  272. package/dist/indicators/schaffTrendCycle.js.map +1 -0
  273. package/dist/indicators/stochRSI.d.ts +24 -0
  274. package/dist/indicators/stochRSI.d.ts.map +1 -0
  275. package/dist/indicators/stochRSI.js +86 -0
  276. package/dist/indicators/stochRSI.js.map +1 -0
  277. package/dist/indicators/t3.d.ts +31 -0
  278. package/dist/indicators/t3.d.ts.map +1 -0
  279. package/dist/indicators/t3.js +63 -0
  280. package/dist/indicators/t3.js.map +1 -0
  281. package/dist/indicators/ultimateOscillator.d.ts +26 -0
  282. package/dist/indicators/ultimateOscillator.d.ts.map +1 -0
  283. package/dist/indicators/ultimateOscillator.js +59 -0
  284. package/dist/indicators/ultimateOscillator.js.map +1 -0
  285. package/dist/indicators/vidya.d.ts +24 -0
  286. package/dist/indicators/vidya.d.ts.map +1 -0
  287. package/dist/indicators/vidya.js +54 -0
  288. package/dist/indicators/vidya.js.map +1 -0
  289. package/dist/indicators/zlema.d.ts +16 -0
  290. package/dist/indicators/zlema.d.ts.map +1 -0
  291. package/dist/indicators/zlema.js +26 -0
  292. package/dist/indicators/zlema.js.map +1 -0
  293. package/dist/input/gesture.d.ts +125 -0
  294. package/dist/input/gesture.d.ts.map +1 -0
  295. package/dist/input/gesture.js +249 -0
  296. package/dist/input/gesture.js.map +1 -0
  297. package/dist/input/index.d.ts +9 -0
  298. package/dist/input/index.d.ts.map +1 -0
  299. package/dist/input/index.js +9 -0
  300. package/dist/input/index.js.map +1 -0
  301. package/dist/input/keyboard.d.ts +140 -0
  302. package/dist/input/keyboard.d.ts.map +1 -0
  303. package/dist/input/keyboard.js +260 -0
  304. package/dist/input/keyboard.js.map +1 -0
  305. package/dist/mcp/chartBridge.d.ts +2 -2
  306. package/dist/mcp/chartBridge.d.ts.map +1 -1
  307. package/dist/mcp/chartBridge.js +27 -21
  308. package/dist/mcp/chartBridge.js.map +1 -1
  309. package/dist/plugin/PluginHost.d.ts +0 -3
  310. package/dist/plugin/PluginHost.d.ts.map +1 -1
  311. package/dist/plugin/PluginHost.js +7 -3
  312. package/dist/plugin/PluginHost.js.map +1 -1
  313. package/dist/plugin/PluginRegistry.d.ts +0 -3
  314. package/dist/plugin/PluginRegistry.d.ts.map +1 -1
  315. package/dist/plugin/PluginRegistry.js +5 -1
  316. package/dist/plugin/PluginRegistry.js.map +1 -1
  317. package/dist/render/Renderer.d.ts +116 -0
  318. package/dist/render/Renderer.d.ts.map +1 -0
  319. package/dist/render/Renderer.js +31 -0
  320. package/dist/render/Renderer.js.map +1 -0
  321. package/dist/render/SurfaceBackend.d.ts +83 -0
  322. package/dist/render/SurfaceBackend.d.ts.map +1 -0
  323. package/dist/render/SurfaceBackend.js +27 -0
  324. package/dist/render/SurfaceBackend.js.map +1 -0
  325. package/dist/render/index.d.ts +12 -0
  326. package/dist/render/index.d.ts.map +1 -0
  327. package/dist/render/index.js +11 -0
  328. package/dist/render/index.js.map +1 -0
  329. package/dist/renderer-tier/detectRendererTier.d.ts +57 -0
  330. package/dist/renderer-tier/detectRendererTier.d.ts.map +1 -0
  331. package/dist/renderer-tier/detectRendererTier.js +143 -0
  332. package/dist/renderer-tier/detectRendererTier.js.map +1 -0
  333. package/dist/renderer-tier/index.d.ts +12 -0
  334. package/dist/renderer-tier/index.d.ts.map +1 -0
  335. package/dist/renderer-tier/index.js +12 -0
  336. package/dist/renderer-tier/index.js.map +1 -0
  337. package/dist/renderer-tier/selectBackend.d.ts +106 -0
  338. package/dist/renderer-tier/selectBackend.d.ts.map +1 -0
  339. package/dist/renderer-tier/selectBackend.js +113 -0
  340. package/dist/renderer-tier/selectBackend.js.map +1 -0
  341. package/dist/renderer-tier/types.d.ts +50 -0
  342. package/dist/renderer-tier/types.d.ts.map +1 -0
  343. package/dist/renderer-tier/types.js +24 -0
  344. package/dist/renderer-tier/types.js.map +1 -0
  345. package/dist/replay/createReplayController.d.ts +3 -0
  346. package/dist/replay/createReplayController.d.ts.map +1 -0
  347. package/dist/replay/createReplayController.js +251 -0
  348. package/dist/replay/createReplayController.js.map +1 -0
  349. package/dist/replay/index.d.ts +5 -0
  350. package/dist/replay/index.d.ts.map +1 -0
  351. package/dist/replay/index.js +3 -0
  352. package/dist/replay/index.js.map +1 -0
  353. package/dist/replay/timeline.d.ts +50 -0
  354. package/dist/replay/timeline.d.ts.map +1 -0
  355. package/dist/replay/timeline.js +104 -0
  356. package/dist/replay/timeline.js.map +1 -0
  357. package/dist/replay/types.d.ts +94 -0
  358. package/dist/replay/types.d.ts.map +1 -0
  359. package/dist/replay/types.js +21 -0
  360. package/dist/replay/types.js.map +1 -0
  361. package/dist/scale/anchoredZoom.d.ts +64 -0
  362. package/dist/scale/anchoredZoom.d.ts.map +1 -0
  363. package/dist/scale/anchoredZoom.js +67 -0
  364. package/dist/scale/anchoredZoom.js.map +1 -0
  365. package/dist/scale/createPriceScale.d.ts +49 -0
  366. package/dist/scale/createPriceScale.d.ts.map +1 -0
  367. package/dist/scale/createPriceScale.js +175 -0
  368. package/dist/scale/createPriceScale.js.map +1 -0
  369. package/dist/scale/createTimeScale.d.ts +27 -0
  370. package/dist/scale/createTimeScale.d.ts.map +1 -0
  371. package/dist/scale/createTimeScale.js +139 -0
  372. package/dist/scale/createTimeScale.js.map +1 -0
  373. package/dist/scale/index.d.ts +6 -0
  374. package/dist/scale/index.d.ts.map +1 -0
  375. package/dist/scale/index.js +5 -0
  376. package/dist/scale/index.js.map +1 -0
  377. package/dist/scale/originShift.d.ts +69 -0
  378. package/dist/scale/originShift.d.ts.map +1 -0
  379. package/dist/scale/originShift.js +41 -0
  380. package/dist/scale/originShift.js.map +1 -0
  381. package/dist/scale/types.d.ts +90 -0
  382. package/dist/scale/types.d.ts.map +1 -0
  383. package/dist/scale/types.js +17 -0
  384. package/dist/scale/types.js.map +1 -0
  385. package/dist/scene/createScene.d.ts +22 -0
  386. package/dist/scene/createScene.d.ts.map +1 -0
  387. package/dist/scene/createScene.js +114 -0
  388. package/dist/scene/createScene.js.map +1 -0
  389. package/dist/scene/index.d.ts +13 -0
  390. package/dist/scene/index.d.ts.map +1 -0
  391. package/dist/scene/index.js +11 -0
  392. package/dist/scene/index.js.map +1 -0
  393. package/dist/scene/layerRegistry.d.ts +83 -0
  394. package/dist/scene/layerRegistry.d.ts.map +1 -0
  395. package/dist/scene/layerRegistry.js +43 -0
  396. package/dist/scene/layerRegistry.js.map +1 -0
  397. package/dist/scene/types.d.ts +128 -0
  398. package/dist/scene/types.d.ts.map +1 -0
  399. package/dist/scene/types.js +21 -0
  400. package/dist/scene/types.js.map +1 -0
  401. package/dist/scheduler/createFrameBudget.d.ts +91 -0
  402. package/dist/scheduler/createFrameBudget.d.ts.map +1 -0
  403. package/dist/scheduler/createFrameBudget.js +232 -0
  404. package/dist/scheduler/createFrameBudget.js.map +1 -0
  405. package/dist/scheduler/index.d.ts +2 -0
  406. package/dist/scheduler/index.d.ts.map +1 -0
  407. package/dist/scheduler/index.js +2 -0
  408. package/dist/scheduler/index.js.map +1 -0
  409. package/dist/tokens/themeToCssVars.d.ts.map +1 -1
  410. package/dist/tokens/themeToCssVars.js +2 -28
  411. package/dist/tokens/themeToCssVars.js.map +1 -1
  412. package/dist/version.d.ts +1 -1
  413. package/dist/version.d.ts.map +1 -1
  414. package/dist/version.js +1 -1
  415. package/dist/version.js.map +1 -1
  416. package/package.json +1 -1
  417. package/src/__bench__/indicators.bench.ts +215 -0
  418. package/src/__bench__/orderBookHeatmap.bench.ts +68 -0
  419. package/src/__bench__/scale.bench.ts +80 -0
  420. package/src/__bench__/signal.bench.ts +41 -0
  421. package/src/__bench__/volumeProfile.bench.ts +66 -0
  422. package/src/__tests__/errors-help.test.ts +184 -0
  423. package/src/__tests__/errors.test.ts +187 -0
  424. package/src/alerts/__tests__/controller.test.ts +231 -0
  425. package/src/alerts/__tests__/predicates.test.ts +374 -0
  426. package/src/alerts/__tests__/ruleSchema.test.ts +180 -0
  427. package/src/alerts/createAlertController.ts +312 -0
  428. package/src/alerts/index.ts +18 -0
  429. package/src/alerts/predicates.ts +231 -0
  430. package/src/alerts/rollingVolume.ts +51 -0
  431. package/src/alerts/ruleSchema.ts +278 -0
  432. package/src/alerts/types.ts +177 -0
  433. package/src/chartTypes/__tests__/heikinAshi.test.ts +122 -0
  434. package/src/chartTypes/__tests__/pointAndFigure.test.ts +167 -0
  435. package/src/chartTypes/__tests__/rangeBars.test.ts +146 -0
  436. package/src/chartTypes/__tests__/renko.test.ts +160 -0
  437. package/src/chartTypes/heikinAshi.ts +116 -0
  438. package/src/chartTypes/index.ts +5 -0
  439. package/src/chartTypes/pointAndFigure.ts +278 -0
  440. package/src/chartTypes/rangeBars.ts +303 -0
  441. package/src/chartTypes/renko.ts +311 -0
  442. package/src/chartTypes/types.ts +99 -0
  443. package/src/components/anchoredVwap/__tests__/computeAnchoredVwap.test.ts +331 -0
  444. package/src/components/anchoredVwap/__tests__/controller.test.ts +430 -0
  445. package/src/components/anchoredVwap/computeAnchoredVwap.ts +174 -0
  446. package/src/components/anchoredVwap/createAnchoredVwapController.ts +358 -0
  447. package/src/components/anchoredVwap/index.ts +17 -0
  448. package/src/components/anchoredVwap/types.ts +187 -0
  449. package/src/components/crosshairSync/__tests__/crosshairSync.test.ts +261 -0
  450. package/src/components/crosshairSync/createCrosshairSync.ts +187 -0
  451. package/src/components/crosshairSync/index.ts +5 -0
  452. package/src/components/footprint/__tests__/aggressor.test.ts +127 -0
  453. package/src/components/footprint/__tests__/controller.test.ts +130 -0
  454. package/src/components/footprint/__tests__/perBarStats.test.ts +114 -0
  455. package/src/components/footprint/aggressor.ts +165 -0
  456. package/src/components/footprint/createFootprintController.ts +338 -0
  457. package/src/components/footprint/index.ts +21 -0
  458. package/src/components/footprint/perBarStats.ts +137 -0
  459. package/src/components/footprint/types.ts +232 -0
  460. package/src/components/mtfOverlay/__tests__/alignToBaseIndex.test.ts +103 -0
  461. package/src/components/mtfOverlay/__tests__/controller.test.ts +172 -0
  462. package/src/components/mtfOverlay/__tests__/resampleBars.test.ts +106 -0
  463. package/src/components/mtfOverlay/alignToBaseIndex.ts +108 -0
  464. package/src/components/mtfOverlay/createMtfController.ts +180 -0
  465. package/src/components/mtfOverlay/index.ts +26 -0
  466. package/src/components/mtfOverlay/resampleBars.ts +134 -0
  467. package/src/components/mtfOverlay/types.ts +148 -0
  468. package/src/components/orderBookHeatmap/__tests__/controller.test.ts +237 -0
  469. package/src/components/orderBookHeatmap/__tests__/deltaArchive.test.ts +88 -0
  470. package/src/components/orderBookHeatmap/__tests__/logColorScale.test.ts +69 -0
  471. package/src/components/orderBookHeatmap/__tests__/orderBookState.test.ts +113 -0
  472. package/src/components/orderBookHeatmap/__tests__/snapshotRing.test.ts +53 -0
  473. package/src/components/orderBookHeatmap/computeShader.wgsl.md +130 -0
  474. package/src/components/orderBookHeatmap/createHeatmapController.ts +273 -0
  475. package/src/components/orderBookHeatmap/createOrderBookState.ts +116 -0
  476. package/src/components/orderBookHeatmap/deltaArchive.ts +113 -0
  477. package/src/components/orderBookHeatmap/index.ts +25 -0
  478. package/src/components/orderBookHeatmap/logColorScale.ts +77 -0
  479. package/src/components/orderBookHeatmap/snapshotRing.ts +65 -0
  480. package/src/components/orderBookHeatmap/types.ts +168 -0
  481. package/src/components/volumeProfile/__tests__/binning.test.ts +133 -0
  482. package/src/components/volumeProfile/__tests__/poc.test.ts +44 -0
  483. package/src/components/volumeProfile/__tests__/valueArea.test.ts +177 -0
  484. package/src/components/volumeProfile/binning.ts +133 -0
  485. package/src/components/volumeProfile/createVolumeProfileController.ts +213 -0
  486. package/src/components/volumeProfile/index.ts +12 -0
  487. package/src/components/volumeProfile/poc.ts +53 -0
  488. package/src/components/volumeProfile/types.ts +148 -0
  489. package/src/components/volumeProfile/valueArea.ts +187 -0
  490. package/src/controllers/createChartController.ts +23 -10
  491. package/src/controllers/types.ts +5 -1
  492. package/src/data-fetchers/baostock.ts +2 -1
  493. package/src/data-fetchers/dataBuffer.effects.ts +3 -1
  494. package/src/data-fetchers/fetcherDefinitionRegistry.ts +2 -1
  495. package/src/data-fetchers/gotdx.ts +4 -3
  496. package/src/data-fetchers/router.ts +6 -3
  497. package/src/data-fetchers/tradingview.ts +3 -2
  498. package/src/engine/chart.ts +126 -3
  499. package/src/engine/data/chartDataManager.ts +26 -4
  500. package/src/engine/drawing/toolConfig.ts +2 -1
  501. package/src/engine/indicators/chartIndicatorManager.ts +2 -1
  502. package/src/engine/indicators/indicatorDefinitionRegistry.ts +2 -1
  503. package/src/engine/indicators/indicatorMetadata.ts +2 -1
  504. package/src/engine/indicators/indicatorRegistry.ts +6 -5
  505. package/src/engine/indicators/registerBuiltins.ts +2 -1
  506. package/src/engine/indicators/scheduler.ts +15 -0
  507. package/src/engine/indicators/soa.ts +2 -1
  508. package/src/engine/indicators/stateComposer.ts +2 -1
  509. package/src/engine/subPaneManager.ts +2 -1
  510. package/src/engine/utils/chartZoomController.ts +7 -1
  511. package/src/errors-help.ts +218 -0
  512. package/src/errors.ts +128 -0
  513. package/src/index.ts +37 -0
  514. package/src/indicators/__tests__/maFamily.test.ts +159 -0
  515. package/src/indicators/__tests__/oscillators.test.ts +150 -0
  516. package/src/indicators/alma.ts +61 -0
  517. package/src/indicators/awesomeOscillator.ts +54 -0
  518. package/src/indicators/dpo.ts +37 -0
  519. package/src/indicators/fisherTransform.ts +63 -0
  520. package/src/indicators/frama.ts +87 -0
  521. package/src/indicators/index.ts +39 -0
  522. package/src/indicators/lsma.ts +58 -0
  523. package/src/indicators/schaffTrendCycle.ts +92 -0
  524. package/src/indicators/stochRSI.ts +108 -0
  525. package/src/indicators/t3.ts +96 -0
  526. package/src/indicators/ultimateOscillator.ts +83 -0
  527. package/src/indicators/vidya.ts +80 -0
  528. package/src/indicators/zlema.ts +41 -0
  529. package/src/input/__tests__/gesture.test.ts +271 -0
  530. package/src/input/__tests__/keyboard.test.ts +317 -0
  531. package/src/input/gesture.ts +357 -0
  532. package/src/input/index.ts +26 -0
  533. package/src/input/keyboard.ts +373 -0
  534. package/src/mcp/chartBridge.ts +98 -72
  535. package/src/plugin/PluginHost.ts +4 -3
  536. package/src/plugin/PluginRegistry.ts +2 -1
  537. package/src/render/Renderer.ts +127 -0
  538. package/src/render/SurfaceBackend.ts +94 -0
  539. package/src/render/__tests__/contract.test.ts +176 -0
  540. package/src/render/index.ts +27 -0
  541. package/src/renderer-tier/__tests__/detectRendererTier.test.ts +180 -0
  542. package/src/renderer-tier/__tests__/selectBackend.test.ts +253 -0
  543. package/src/renderer-tier/detectRendererTier.ts +168 -0
  544. package/src/renderer-tier/index.ts +30 -0
  545. package/src/renderer-tier/selectBackend.ts +201 -0
  546. package/src/renderer-tier/types.ts +59 -0
  547. package/src/replay/__tests__/controller.test.ts +309 -0
  548. package/src/replay/__tests__/timeline.test.ts +99 -0
  549. package/src/replay/createReplayController.ts +302 -0
  550. package/src/replay/index.ts +15 -0
  551. package/src/replay/timeline.ts +106 -0
  552. package/src/replay/types.ts +107 -0
  553. package/src/scale/__tests__/anchoredZoom.test.ts +125 -0
  554. package/src/scale/__tests__/originShift.test.ts +97 -0
  555. package/src/scale/__tests__/priceScale.test.ts +219 -0
  556. package/src/scale/__tests__/timeScale.test.ts +119 -0
  557. package/src/scale/anchoredZoom.ts +104 -0
  558. package/src/scale/createPriceScale.ts +226 -0
  559. package/src/scale/createTimeScale.ts +150 -0
  560. package/src/scale/index.ts +9 -0
  561. package/src/scale/originShift.ts +111 -0
  562. package/src/scale/types.ts +100 -0
  563. package/src/scene/__tests__/layerRegistry.test.ts +207 -0
  564. package/src/scene/__tests__/scene.test.ts +411 -0
  565. package/src/scene/createScene.ts +117 -0
  566. package/src/scene/index.ts +29 -0
  567. package/src/scene/layerRegistry.ts +117 -0
  568. package/src/scene/types.ts +143 -0
  569. package/src/scheduler/__tests__/createFrameBudget.test.ts +315 -0
  570. package/src/scheduler/createFrameBudget.ts +316 -0
  571. package/src/scheduler/index.ts +7 -0
  572. package/src/tokens/themeToCssVars.ts +3 -1
  573. package/src/version.ts +1 -1
  574. package/dist/data-fetchers/gotdx/gotdx.d.ts +0 -7
  575. package/dist/data-fetchers/gotdx/gotdx.d.ts.map +0 -1
  576. package/dist/data-fetchers/gotdx/gotdx.js +0 -7
  577. package/dist/data-fetchers/gotdx/gotdx.js.map +0 -1
  578. package/src/data-fetchers/gotdx/gotdx.ts +0 -6
@@ -0,0 +1,338 @@
1
+ /**
2
+ * FootprintController — framework-agnostic, signal-based.
3
+ *
4
+ * Streams trades in, materialises a `FootprintBar[]` out. Composes:
5
+ *
6
+ * - `classifyExplicit` (try exchange flag first)
7
+ * - `classifyTickRule` / `classifyLeeReady` (fallback per config)
8
+ * - `computeDelta`, `computeDiagonalImbalances`, `computeCumulativeDelta`
9
+ *
10
+ * Internal storage is hot-path-friendly:
11
+ *
12
+ * buckets: Map<barIndex, Map<priceTickKey, { askVol, bidVol }>>
13
+ *
14
+ * Materialisation (sorting + array build) is deferred to `bars` / `cumulativeDelta`
15
+ * signal reads. A `dirty` flag invalidates the cache on every `ingestTrade`.
16
+ *
17
+ * Classifier state carry-over: the `TickRuleState` / `LeeReadyState` records
18
+ * are MAINTAINED ACROSS BAR BOUNDARIES — i.e. the last trade's price/side of
19
+ * bar N is used as the prior for the first trade of bar N+1. This is the
20
+ * documented choice (see ROADMAP §3.3): per-bar reset would flag every bar's
21
+ * first trade as `unknown`, which inflates dropped volume and breaks the
22
+ * Lee-Ready zero-tick fallback at every minute boundary. The tested behaviour
23
+ * relies on this carry-over.
24
+ *
25
+ * Dispose-guard pattern mirrors `createIndicatorSelectorController.ts`.
26
+ */
27
+
28
+ import { createSignal, type Signal } from '../../reactivity'
29
+ import { KLineChartError } from '../../errors'
30
+ import {
31
+ classifyExplicit,
32
+ classifyLeeReady,
33
+ classifyTickRule,
34
+ type AggressorResult,
35
+ type LeeReadyState,
36
+ type TickRuleState,
37
+ } from './aggressor'
38
+ import {
39
+ computeCumulativeDelta,
40
+ computeDelta,
41
+ computeDiagonalImbalances,
42
+ } from './perBarStats'
43
+ import type {
44
+ FootprintBar,
45
+ FootprintBarCell,
46
+ FootprintConfig,
47
+ FootprintController,
48
+ FootprintImbalance,
49
+ TradeWithFlag,
50
+ } from './types'
51
+
52
+ // ---------------------------------------------------------------------------
53
+ // Defaults & validation
54
+ // ---------------------------------------------------------------------------
55
+
56
+ const DEFAULT_CONFIG: FootprintConfig = {
57
+ tickSize: 0.01,
58
+ barIntervalMs: 60_000,
59
+ imbalanceRatio: 3,
60
+ fallbackClassifier: 'tick-rule',
61
+ }
62
+
63
+ function validateConfig(c: FootprintConfig): void {
64
+ if (!(c.tickSize > 0)) {
65
+ throw new KLineChartError('FOOTPRINT_TICKSIZE_INVALID', 'FootprintController: tickSize must be > 0')
66
+ }
67
+ if (!(c.barIntervalMs > 0) || !Number.isFinite(c.barIntervalMs)) {
68
+ throw new KLineChartError('FOOTPRINT_BAR_INTERVAL_INVALID', 'FootprintController: barIntervalMs must be > 0')
69
+ }
70
+ if (!(c.imbalanceRatio > 0)) {
71
+ throw new KLineChartError('FOOTPRINT_RATIO_INVALID', 'FootprintController: imbalanceRatio must be > 0')
72
+ }
73
+ }
74
+
75
+ // ---------------------------------------------------------------------------
76
+ // Internal cell shape (mutable counterpart of the readonly public cell)
77
+ // ---------------------------------------------------------------------------
78
+
79
+ interface MutableCell {
80
+ askVol: number
81
+ bidVol: number
82
+ }
83
+
84
+ // ---------------------------------------------------------------------------
85
+ // Factory
86
+ // ---------------------------------------------------------------------------
87
+
88
+ export function createFootprintController(
89
+ init: Partial<FootprintConfig>,
90
+ ): FootprintController {
91
+ const initialConfig: FootprintConfig = { ...DEFAULT_CONFIG, ...init }
92
+ validateConfig(initialConfig)
93
+
94
+ const config: Signal<FootprintConfig> = createSignal(initialConfig)
95
+ const bars: Signal<ReadonlyArray<FootprintBar>> = createSignal<
96
+ ReadonlyArray<FootprintBar>
97
+ >([])
98
+ const cumulativeDelta: Signal<ReadonlyArray<number>> = createSignal<
99
+ ReadonlyArray<number>
100
+ >([])
101
+
102
+ // ---- Internal state ------------------------------------------------
103
+
104
+ /**
105
+ * barIndex → (priceTickKey → mutable cell).
106
+ *
107
+ * We use Maps so insertion order is preserved per-bar (for debug-time
108
+ * inspection); the public materialisation sorts deterministically.
109
+ */
110
+ let buckets: Map<number, Map<number, MutableCell>> = new Map()
111
+
112
+ /**
113
+ * Classifier carry-over. One record shared by tick rule and Lee-Ready —
114
+ * they have the same field surface. NEVER reset on bar boundary
115
+ * (see header comment).
116
+ */
117
+ const tickState: TickRuleState & LeeReadyState = {
118
+ prevPrice: null,
119
+ prevSide: null,
120
+ }
121
+
122
+ /** Set to true on every successful `ingestTrade`; cleared on materialise. */
123
+ let dirty = false
124
+ /** Disposal guard. */
125
+ let disposed = false
126
+
127
+ // ---- Helpers -------------------------------------------------------
128
+
129
+ function classify(
130
+ trade: TradeWithFlag,
131
+ bid: number | undefined,
132
+ ask: number | undefined,
133
+ ): AggressorResult {
134
+ // 1. Try the explicit exchange flag first (zero error).
135
+ const explicit = classifyExplicit(trade)
136
+ if (explicit !== null) {
137
+ // Even when we don't consume the heuristic, advance the
138
+ // carry-over so a later fallback-classified trade still has a
139
+ // useful prevPrice/prevSide. We commit prevSide only for known
140
+ // explicit sides.
141
+ tickState.prevPrice = trade.price
142
+ tickState.prevSide = explicit.side === 'unknown' ? null : explicit.side
143
+ return explicit
144
+ }
145
+ // 2. Fall back to the configured heuristic.
146
+ const mode = config.peek().fallbackClassifier
147
+ if (mode === 'lee-ready') {
148
+ // If quotes are missing, classifyLeeReady will degrade to the
149
+ // tick rule itself — same state record.
150
+ const b = bid ?? Number.NaN
151
+ const a = ask ?? Number.NaN
152
+ return classifyLeeReady(tickState, trade, b, a)
153
+ }
154
+ return classifyTickRule(tickState, trade)
155
+ }
156
+
157
+ function bucketFor(barIndex: number): Map<number, MutableCell> {
158
+ let bar = buckets.get(barIndex)
159
+ if (bar === undefined) {
160
+ bar = new Map()
161
+ buckets.set(barIndex, bar)
162
+ }
163
+ return bar
164
+ }
165
+
166
+ function cellFor(
167
+ bar: Map<number, MutableCell>,
168
+ priceTickKey: number,
169
+ ): MutableCell {
170
+ let cell = bar.get(priceTickKey)
171
+ if (cell === undefined) {
172
+ cell = { askVol: 0, bidVol: 0 }
173
+ bar.set(priceTickKey, cell)
174
+ }
175
+ return cell
176
+ }
177
+
178
+ /**
179
+ * Build the materialised view from `buckets`. Sorts bars ascending by
180
+ * barIndex; within each bar, sorts cells ascending by price.
181
+ */
182
+ function materialise(): {
183
+ bars: FootprintBar[]
184
+ cumulative: number[]
185
+ } {
186
+ const cfg = config.peek()
187
+ const sortedBarIndices = [...buckets.keys()].sort((a, b) => a - b)
188
+
189
+ const outBars: FootprintBar[] = []
190
+ const perBarDeltas: number[] = []
191
+
192
+ for (const barIndex of sortedBarIndices) {
193
+ const internal = buckets.get(barIndex)
194
+ if (internal === undefined) continue
195
+
196
+ const sortedKeys = [...internal.keys()].sort((a, b) => a - b)
197
+ const cells: FootprintBarCell[] = sortedKeys.map((k) => {
198
+ const c = internal.get(k) as MutableCell
199
+ return {
200
+ price: k * cfg.tickSize,
201
+ askVol: c.askVol,
202
+ bidVol: c.bidVol,
203
+ }
204
+ })
205
+
206
+ const delta = computeDelta(cells)
207
+ let totalVolume = 0
208
+ for (let i = 0; i < cells.length; i++) {
209
+ const cell = cells[i]
210
+ if (cell === undefined) continue
211
+ totalVolume += cell.askVol + cell.bidVol
212
+ }
213
+
214
+ const imbalances: ReadonlyArray<FootprintImbalance> =
215
+ computeDiagonalImbalances(cells, cfg.imbalanceRatio)
216
+
217
+ const startTime = barIndex * cfg.barIntervalMs
218
+ const endTime = startTime + cfg.barIntervalMs - 1
219
+
220
+ outBars.push({
221
+ barIndex,
222
+ startTime,
223
+ endTime,
224
+ cells,
225
+ delta,
226
+ totalVolume,
227
+ imbalances,
228
+ })
229
+ perBarDeltas.push(delta)
230
+ }
231
+
232
+ return { bars: outBars, cumulative: computeCumulativeDelta(perBarDeltas) }
233
+ }
234
+
235
+ function publishIfDirty(): void {
236
+ if (!dirty) return
237
+ const { bars: nextBars, cumulative } = materialise()
238
+ bars.set(nextBars)
239
+ cumulativeDelta.set(cumulative)
240
+ dirty = false
241
+ }
242
+
243
+ // ---- Mutators ------------------------------------------------------
244
+
245
+ function ingestTrade(
246
+ trade: TradeWithFlag,
247
+ bid?: number,
248
+ ask?: number,
249
+ ): void {
250
+ if (disposed) return
251
+ // Defensive: reject malformed trades. We do not throw — a single bad
252
+ // print should not poison the live stream.
253
+ if (!Number.isFinite(trade.price) || !Number.isFinite(trade.size)) {
254
+ return
255
+ }
256
+ if (!Number.isFinite(trade.timestamp)) return
257
+ if (trade.size <= 0) return
258
+
259
+ const result = classify(trade, bid, ask)
260
+ if (result.side === 'unknown') {
261
+ // Drop from the aggregate (the documented contract). We've still
262
+ // updated tickState inside `classify` so the next trade has
263
+ // context.
264
+ return
265
+ }
266
+
267
+ const cfg = config.peek()
268
+ const barIndex = Math.floor(trade.timestamp / cfg.barIntervalMs)
269
+ const priceTickKey = Math.round(trade.price / cfg.tickSize)
270
+
271
+ const bar = bucketFor(barIndex)
272
+ const cell = cellFor(bar, priceTickKey)
273
+ if (result.side === 'buy') {
274
+ cell.askVol += trade.size
275
+ } else {
276
+ cell.bidVol += trade.size
277
+ }
278
+ dirty = true
279
+ publishIfDirty()
280
+ }
281
+
282
+ function setConfig(next: Partial<FootprintConfig>): void {
283
+ if (disposed) return
284
+ const cur = config.peek()
285
+ const merged: FootprintConfig = { ...cur, ...next }
286
+ validateConfig(merged)
287
+
288
+ // Changing tickSize or barIntervalMs invalidates the buckets — the
289
+ // priceTickKey and barIndex of every accumulated cell would be wrong
290
+ // under the new partitioning. Clear them and let the caller re-feed
291
+ // history if needed.
292
+ const partitionChanged =
293
+ merged.tickSize !== cur.tickSize ||
294
+ merged.barIntervalMs !== cur.barIntervalMs
295
+ if (partitionChanged) {
296
+ buckets = new Map()
297
+ // We do NOT reset tickState — the next trade's carry-over is
298
+ // still valid because the classifier only depends on price
299
+ // history, not on the bucket partitioning.
300
+ }
301
+ config.set(merged)
302
+ // Re-materialise. If partition changed, bars/cumulative now empty.
303
+ // If only imbalanceRatio changed, we still want to re-flag.
304
+ dirty = true
305
+ publishIfDirty()
306
+ }
307
+
308
+ function reset(): void {
309
+ if (disposed) return
310
+ buckets = new Map()
311
+ tickState.prevPrice = null
312
+ tickState.prevSide = null
313
+ bars.set([])
314
+ cumulativeDelta.set([])
315
+ dirty = false
316
+ }
317
+
318
+ function dispose(): void {
319
+ if (disposed) return
320
+ disposed = true
321
+ // Mutators check `disposed` so no further writes will fire — existing
322
+ // subscribers receive no further notifications.
323
+ }
324
+
325
+ return {
326
+ config,
327
+ bars,
328
+ cumulativeDelta,
329
+ // Canonical verb (API audit BLOCKER-001 harmonisation across
330
+ // VolumeProfile / OrderBookHeatmap / Footprint). Wired to the same
331
+ // implementation as `ingestTrade` so existing consumers keep working.
332
+ ingest: ingestTrade,
333
+ ingestTrade,
334
+ setConfig,
335
+ reset,
336
+ dispose,
337
+ }
338
+ }
@@ -0,0 +1,21 @@
1
+ export type {
2
+ AggressorSide,
3
+ Trade,
4
+ TradeWithFlag,
5
+ FootprintBar,
6
+ FootprintConfig,
7
+ FootprintController,
8
+ } from './types'
9
+ export type { AggressorResult, TickRuleState, LeeReadyState } from './aggressor'
10
+ export {
11
+ classifyExplicit,
12
+ classifyTickRule,
13
+ classifyLeeReady,
14
+ } from './aggressor'
15
+ export type { FootprintBarCell, FootprintImbalance } from './perBarStats'
16
+ export {
17
+ computeDelta,
18
+ computeCumulativeDelta,
19
+ computeDiagonalImbalances,
20
+ } from './perBarStats'
21
+ export { createFootprintController } from './createFootprintController'
@@ -0,0 +1,137 @@
1
+ /**
2
+ * Per-bar derived statistics for the footprint data model.
3
+ *
4
+ * - `computeDelta` — Σ(askVol − bidVol) across a bar's cells
5
+ * - `computeCumulativeDelta` — running sum of per-bar deltas
6
+ * - `computeDiagonalImbalances` — Bookmap/Sierra-style 3× diagonal flags
7
+ *
8
+ * These are the lightweight CPU-side helpers. The compute-shader path
9
+ * (`computeShader.wgsl.md`) parallelises them per-bar in a single dispatch
10
+ * for the heavy historical scan; the values produced here are byte-identical
11
+ * to that GPU path's eventual output.
12
+ *
13
+ * See `docs/ROADMAP.md` §3.3 for the diagonal-imbalance rationale.
14
+ */
15
+
16
+ import type { FootprintBarCell, FootprintImbalance } from './types'
17
+
18
+ export type { FootprintBarCell, FootprintImbalance }
19
+
20
+ // ---------------------------------------------------------------------------
21
+ // Delta and cumulative delta
22
+ // ---------------------------------------------------------------------------
23
+
24
+ /**
25
+ * Net buy-vs-sell volume for one bar. Positive values are buyer-dominated.
26
+ *
27
+ * Iterates the cells once; the order of cells does not affect the result.
28
+ * An empty cell list yields 0 (the additive identity, sensible for a no-trade
29
+ * bar so it does not break the running cumulative sum downstream).
30
+ */
31
+ export function computeDelta(cells: ReadonlyArray<FootprintBarCell>): number {
32
+ let sum = 0
33
+ for (let i = 0; i < cells.length; i++) {
34
+ const c = cells[i]
35
+ if (c === undefined) continue
36
+ sum += c.askVol - c.bidVol
37
+ }
38
+ return sum
39
+ }
40
+
41
+ /**
42
+ * Running sum of per-bar deltas. `result[i] = Σ deltas[0..i]`.
43
+ *
44
+ * Empty input yields an empty array. We allocate a fresh array (not a typed
45
+ * array) so consumers can splice/copy cheaply at the controller boundary.
46
+ */
47
+ export function computeCumulativeDelta(
48
+ perBarDeltas: ReadonlyArray<number>,
49
+ ): number[] {
50
+ const out: number[] = new Array(perBarDeltas.length)
51
+ let running = 0
52
+ for (let i = 0; i < perBarDeltas.length; i++) {
53
+ running += perBarDeltas[i] ?? 0
54
+ out[i] = running
55
+ }
56
+ return out
57
+ }
58
+
59
+ // ---------------------------------------------------------------------------
60
+ // Diagonal imbalance
61
+ // ---------------------------------------------------------------------------
62
+
63
+ /**
64
+ * Diagonal imbalance detection.
65
+ *
66
+ * Aggressive buyers eat the ASK at a price they cross — the ASK at price
67
+ * p is filled by buyers who were willing to pay p, and conversely, sellers
68
+ * who hit the BID at price p-1 (one tick below) were also "leaning"
69
+ * against that same level. So the right comparison is *diagonal*:
70
+ *
71
+ * buy-imbalance at cell i:
72
+ * cell[i].askVol >= ratio * cell[i-1].bidVol AND cell[i-1].bidVol > 0
73
+ *
74
+ * sell-imbalance at cell i:
75
+ * cell[i].bidVol >= ratio * cell[i+1].askVol AND cell[i+1].askVol > 0
76
+ *
77
+ * Edge handling: a buy-imbalance at i=0 has no `i-1` so it is never reported;
78
+ * a sell-imbalance at the last index has no `i+1` so it is never reported.
79
+ *
80
+ * The `priceIndex` in the result is the index of the *dominant* cell — the
81
+ * one carrying the heavy volume — not its diagonal counterpart.
82
+ *
83
+ * `ratio` is `dominant / weaker`, capped at `Number.POSITIVE_INFINITY` when
84
+ * the weaker side is zero (caller can choose to render that as "∞").
85
+ *
86
+ * Default threshold: 3.0 (Bookmap / Sierra Chart convention). Pass any
87
+ * positive ratio. A ratio of 1.0 would degenerate to "every diagonal pair
88
+ * with non-zero asymmetry is an imbalance" — usually too noisy for display.
89
+ *
90
+ * @param cells bar cells, ascending by price
91
+ * @param ratioThreshold minimum dominant/weaker ratio to flag
92
+ */
93
+ export function computeDiagonalImbalances(
94
+ cells: ReadonlyArray<FootprintBarCell>,
95
+ ratioThreshold: number,
96
+ ): ReadonlyArray<FootprintImbalance> {
97
+ const out: FootprintImbalance[] = []
98
+ const n = cells.length
99
+ if (n === 0) return out
100
+
101
+ for (let i = 0; i < n; i++) {
102
+ const c = cells[i]
103
+ if (c === undefined) continue
104
+
105
+ // Buy imbalance: compare ask at i to bid at i-1 (the diagonal below).
106
+ if (i > 0) {
107
+ const below = cells[i - 1]
108
+ if (below !== undefined && below.bidVol > 0) {
109
+ const ratio = c.askVol / below.bidVol
110
+ if (ratio >= ratioThreshold) {
111
+ out.push({
112
+ priceIndex: i,
113
+ direction: 'buy-imbalance',
114
+ ratio,
115
+ })
116
+ }
117
+ }
118
+ }
119
+
120
+ // Sell imbalance: compare bid at i to ask at i+1 (the diagonal above).
121
+ if (i < n - 1) {
122
+ const above = cells[i + 1]
123
+ if (above !== undefined && above.askVol > 0) {
124
+ const ratio = c.bidVol / above.askVol
125
+ if (ratio >= ratioThreshold) {
126
+ out.push({
127
+ priceIndex: i,
128
+ direction: 'sell-imbalance',
129
+ ratio,
130
+ })
131
+ }
132
+ }
133
+ }
134
+ }
135
+
136
+ return out
137
+ }