@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,108 @@
1
+ import { KLineChartError } from '../../errors'
2
+ /**
3
+ * Forward-fill a higher-timeframe series onto the base bar index, with strict
4
+ * no-lookahead semantics.
5
+ *
6
+ * The rule, restated:
7
+ * A higher-tf bar opens at `hbar.timestamp` and covers the half-open
8
+ * interval `[hbar.timestamp, hbar.timestamp + targetIntervalMs)`. The
9
+ * higher-tf value at that bar is available to every base bar whose
10
+ * timestamp falls inside that interval — and only those base bars.
11
+ *
12
+ * Forward fill is implicit: because higher-tf bars are contiguous in time
13
+ * (within the input series), a base bar at time `t` reads the value of the
14
+ * higher-tf bar whose half-open interval contains `t`. If no such bar exists
15
+ * (i.e. `t` is before the first higher-tf bar's open), the output is `null`.
16
+ *
17
+ * Gap handling: if the higher-tf series has a hole (bar N+1's open is more
18
+ * than `targetIntervalMs` after bar N's open), base bars in that hole get the
19
+ * value of bar N. This matches the forward-fill intuition users have — once
20
+ * a higher-tf value exists, it stays visible until the next bucket opens.
21
+ *
22
+ * Lookahead-bias test (spelled out so it survives regressions):
23
+ * - hbar opens at 09:00 with value 100, targetIntervalMs = 1h.
24
+ * - base bar at 09:00 → value 100 (open of the bucket).
25
+ * - base bar at 09:59 → value 100 (still inside the bucket).
26
+ * - base bar at 08:55 → null (before the bucket opens — using 100 here
27
+ * would be lookahead).
28
+ *
29
+ * Performance: O(B + H) using a synced two-pointer walk (both inputs are
30
+ * sorted by timestamp). Callers typically have B ≫ H (many fine bars per
31
+ * coarse bar), so we step through `baseBars` linearly while advancing the
32
+ * higher-tf cursor whenever the next bucket opens at or before `t`.
33
+ */
34
+
35
+ /**
36
+ * @internal — building block used by `createMtfController`. Reachable today
37
+ * via the top-level `@klinechart-quant/core` barrel but **NOT
38
+ * part of the supported public API**. typedoc / api-extractor
39
+ * hide it from generated docs. Prefer the controller factory
40
+ * for stable user code. Closes API audit BLOCKER-002.
41
+ */
42
+ export function alignToBaseIndex<TValue>(
43
+ baseBars: ReadonlyArray<{ timestamp: number }>,
44
+ higherTfBars: ReadonlyArray<{ timestamp: number }>,
45
+ higherTfValues: ReadonlyArray<TValue>,
46
+ targetIntervalMs: number,
47
+ ): ReadonlyArray<TValue | null> {
48
+ if (!Number.isFinite(targetIntervalMs) || targetIntervalMs <= 0) {
49
+ throw new KLineChartError(
50
+ 'MTF_CONFIG_INVALID',
51
+ 'alignToBaseIndex: targetIntervalMs must be a positive finite number',
52
+ )
53
+ }
54
+ if (higherTfBars.length !== higherTfValues.length) {
55
+ throw new KLineChartError(
56
+ 'MTF_CONFIG_INVALID',
57
+ `alignToBaseIndex: higherTfBars.length (${higherTfBars.length}) must ` +
58
+ `equal higherTfValues.length (${higherTfValues.length})`,
59
+ )
60
+ }
61
+
62
+ const B = baseBars.length
63
+ const H = higherTfBars.length
64
+ const out: (TValue | null)[] = new Array(B)
65
+
66
+ if (B === 0) return out
67
+ if (H === 0) {
68
+ for (let i = 0; i < B; i++) out[i] = null
69
+ return out
70
+ }
71
+
72
+ // Two-pointer walk. `h` is the index of the higher-tf bar that COULD
73
+ // cover the current base bar — meaning `higherTfBars[h].timestamp <= t`.
74
+ // We advance `h` greedily as base bars march forward.
75
+ let h = -1 // -1 ≡ "no higher-tf bar has opened yet"
76
+
77
+ for (let i = 0; i < B; i++) {
78
+ const t = baseBars[i].timestamp
79
+
80
+ // Advance `h` to the latest higher-tf bar whose open is ≤ t. This is
81
+ // the "no lookahead" gate: a bar whose open > t is invisible to us.
82
+ while (h + 1 < H && higherTfBars[h + 1].timestamp <= t) {
83
+ h++
84
+ }
85
+
86
+ if (h < 0) {
87
+ // No higher-tf bar has opened at or before t → leading null.
88
+ out[i] = null
89
+ continue
90
+ }
91
+
92
+ // We have a candidate bar `h`. Final check: is t still inside its
93
+ // half-open interval? If `higherTfBars[h+1]` exists and its open is
94
+ // ≤ t, the while loop above would have advanced — so we only need to
95
+ // check the upper bound for the last bar, or in a gap.
96
+ const bucketStart = higherTfBars[h].timestamp
97
+ if (t < bucketStart + targetIntervalMs) {
98
+ out[i] = higherTfValues[h]
99
+ } else {
100
+ // t falls into a gap after bar h's closed interval and before
101
+ // the next bar opens (or after the end of the series). Forward
102
+ // fill: keep bar h's value visible.
103
+ out[i] = higherTfValues[h]
104
+ }
105
+ }
106
+
107
+ return out
108
+ }
@@ -0,0 +1,180 @@
1
+ import { KLineChartError } from '../../errors'
2
+ /**
3
+ * Multi-Timeframe overlay controller.
4
+ *
5
+ * Composes `resampleBars` + `alignToBaseIndex` + a user-supplied `compute`
6
+ * function per series. Holds the base bar buffer + base interval + a Map of
7
+ * active series, exposes a single reactive `series` signal.
8
+ *
9
+ * v1 implementation: full re-resample + full compute on every mutation. The
10
+ * incremental "only re-do the last bucket on `appendBaseBar`" optimization
11
+ * is documented as a follow-up — landing it does not change observable
12
+ * behavior, only frame-time cost. Tests pin the observable shape.
13
+ */
14
+
15
+ import { createSignal } from '../../reactivity'
16
+ import type { Signal } from '../../reactivity'
17
+ import { resampleBars } from './resampleBars'
18
+ import { alignToBaseIndex } from './alignToBaseIndex'
19
+ import type {
20
+ ActiveMtfSeries,
21
+ BaseBar,
22
+ MtfController,
23
+ MtfSeriesDefinition,
24
+ ResampledBar,
25
+ } from './types'
26
+
27
+ export interface CreateMtfControllerInit {
28
+ initialBars?: ReadonlyArray<BaseBar>
29
+ baseIntervalMs?: number
30
+ }
31
+
32
+ export function createMtfController(init: CreateMtfControllerInit = {}): MtfController {
33
+ let disposed = false
34
+ let baseBars: ReadonlyArray<BaseBar> = init.initialBars ?? []
35
+ let baseIntervalMs: number | null = init.baseIntervalMs ?? null
36
+
37
+ const definitions = new Map<string, MtfSeriesDefinition>()
38
+ const seriesSignal = createSignal<ReadonlyArray<ActiveMtfSeries>>([])
39
+
40
+ const computeOne = (def: MtfSeriesDefinition): ActiveMtfSeries => {
41
+ // No bars or no base interval set → empty aligned values (length 0,
42
+ // matching the empty base buffer).
43
+ if (baseBars.length === 0 || baseIntervalMs === null) {
44
+ return { definition: def, alignedValues: [] }
45
+ }
46
+ const resampled: ReadonlyArray<ResampledBar> = resampleBars(
47
+ baseBars,
48
+ baseIntervalMs,
49
+ def.targetIntervalMs,
50
+ )
51
+ const values = def.compute(resampled)
52
+ if (values.length !== resampled.length) {
53
+ throw new KLineChartError(
54
+ 'MTF_CONFIG_INVALID',
55
+ `MtfController: compute fn for series "${def.id}" returned ` +
56
+ `${values.length} values for ${resampled.length} resampled bars; ` +
57
+ `length must match`,
58
+ )
59
+ }
60
+ const aligned = alignToBaseIndex(
61
+ baseBars,
62
+ resampled,
63
+ values,
64
+ def.targetIntervalMs,
65
+ )
66
+ return { definition: def, alignedValues: aligned }
67
+ }
68
+
69
+ const recomputeAll = (): void => {
70
+ const all: ActiveMtfSeries[] = []
71
+ for (const def of definitions.values()) {
72
+ all.push(computeOne(def))
73
+ }
74
+ seriesSignal.set(all)
75
+ }
76
+
77
+ const guard = (): boolean => !disposed
78
+
79
+ const validateInterval = (targetMs: number): void => {
80
+ if (!Number.isFinite(targetMs) || targetMs <= 0) {
81
+ throw new KLineChartError('MTF_CONFIG_INVALID', 'MtfController: targetIntervalMs must be > 0')
82
+ }
83
+ if (baseIntervalMs !== null && targetMs % baseIntervalMs !== 0) {
84
+ throw new KLineChartError(
85
+ 'MTF_CONFIG_INVALID',
86
+ `MtfController: targetIntervalMs (${targetMs}) must be an ` +
87
+ `integer multiple of baseIntervalMs (${baseIntervalMs})`,
88
+ )
89
+ }
90
+ }
91
+
92
+ const inner: {
93
+ series: Signal<ReadonlyArray<ActiveMtfSeries>>
94
+ setBaseBars(bars: ReadonlyArray<BaseBar>, intervalMs: number): void
95
+ addSeries(def: MtfSeriesDefinition): string
96
+ removeSeries(id: string): boolean
97
+ updateSeries(id: string, patch: Partial<Omit<MtfSeriesDefinition, 'id'>>): boolean
98
+ appendBaseBar(bar: BaseBar): void
99
+ dispose(): void
100
+ } = {
101
+ series: seriesSignal,
102
+
103
+ setBaseBars(bars: ReadonlyArray<BaseBar>, intervalMs: number): void {
104
+ if (!guard()) return
105
+ if (!Number.isFinite(intervalMs) || intervalMs <= 0) {
106
+ throw new KLineChartError('MTF_CONFIG_INVALID', 'MtfController.setBaseBars: baseIntervalMs must be > 0')
107
+ }
108
+ // If any series has a target that no longer cleanly divides, throw
109
+ // up front rather than letting resampleBars throw later.
110
+ for (const def of definitions.values()) {
111
+ if (def.targetIntervalMs % intervalMs !== 0) {
112
+ throw new KLineChartError(
113
+ 'MTF_CONFIG_INVALID',
114
+ `MtfController.setBaseBars: existing series "${def.id}" ` +
115
+ `targetIntervalMs (${def.targetIntervalMs}) does not cleanly ` +
116
+ `divide new baseIntervalMs (${intervalMs})`,
117
+ )
118
+ }
119
+ }
120
+ baseBars = bars
121
+ baseIntervalMs = intervalMs
122
+ recomputeAll()
123
+ },
124
+
125
+ addSeries(def): string {
126
+ if (!guard()) return def.id
127
+ if (definitions.has(def.id)) {
128
+ throw new KLineChartError('MTF_CONFIG_INVALID', `MtfController.addSeries: id "${def.id}" already in use`)
129
+ }
130
+ validateInterval(def.targetIntervalMs)
131
+ definitions.set(def.id, def)
132
+ recomputeAll()
133
+ return def.id
134
+ },
135
+
136
+ removeSeries(id): boolean {
137
+ if (!guard()) return false
138
+ const had = definitions.delete(id)
139
+ if (had) recomputeAll()
140
+ return had
141
+ },
142
+
143
+ updateSeries(id, patch): boolean {
144
+ if (!guard()) return false
145
+ const existing = definitions.get(id)
146
+ if (existing === undefined) return false
147
+ const next: MtfSeriesDefinition = {
148
+ ...existing,
149
+ ...patch,
150
+ id: existing.id, // protect against accidental id mutation
151
+ }
152
+ if (patch.targetIntervalMs !== undefined) {
153
+ validateInterval(patch.targetIntervalMs)
154
+ }
155
+ definitions.set(id, next)
156
+ recomputeAll()
157
+ return true
158
+ },
159
+
160
+ appendBaseBar(bar): void {
161
+ if (!guard()) return
162
+ baseBars = [...baseBars, bar]
163
+ recomputeAll()
164
+ },
165
+
166
+ dispose(): void {
167
+ disposed = true
168
+ definitions.clear()
169
+ },
170
+ }
171
+
172
+ // Canonical verbs (API audit BLOCKER-001): `setData` for full
173
+ // replacement, `append` for single-item extension. Old names
174
+ // preserved as aliases on the inner object for the deprecation window.
175
+ return {
176
+ ...inner,
177
+ setData: inner.setBaseBars,
178
+ append: inner.appendBaseBar,
179
+ }
180
+ }
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Multi-Timeframe (MTF) overlay barrel.
3
+ *
4
+ * Public surface:
5
+ * - `resampleBars`: aggregate base-tf bars into higher-tf buckets
6
+ * - `alignToBaseIndex`: forward-fill higher-tf values onto base-bar indices
7
+ * (no-lookahead semantics, see file docstring)
8
+ * - `createMtfController`: composes the above + a user-supplied `compute`
9
+ * into a reactive multi-series controller
10
+ *
11
+ * The controller is intentionally indicator-agnostic — any indicator (EMA,
12
+ * RSI, custom) can be lifted to MTF by passing a `compute` fn that takes
13
+ * resampled bars and returns one number per bar.
14
+ */
15
+
16
+ export type {
17
+ BaseBar,
18
+ ResampledBar,
19
+ MtfSeriesDefinition,
20
+ ActiveMtfSeries,
21
+ MtfController,
22
+ } from './types'
23
+
24
+ export { resampleBars } from './resampleBars'
25
+ export { alignToBaseIndex } from './alignToBaseIndex'
26
+ export { createMtfController, type CreateMtfControllerInit } from './createMtfController'
@@ -0,0 +1,134 @@
1
+ import { KLineChartError } from '../../errors'
2
+ /**
3
+ * Resample a base-timeframe bar series to a higher timeframe.
4
+ *
5
+ * Two design choices worth pinning:
6
+ *
7
+ * 1. We bucket by **floor(timestamp / targetIntervalMs) * targetIntervalMs**,
8
+ * not by counting base bars. This is robust to gaps in the input — a
9
+ * 1-minute series that skips 09:33 (the bar simply isn't there) will still
10
+ * correctly group 09:30..09:34 into one 5m bucket and produce no synthetic
11
+ * bar for 09:33.
12
+ *
13
+ * 2. The final bucket is allowed to be **partial** (contain fewer base bars
14
+ * than `targetIntervalMs / baseIntervalMs`). This is the right default for
15
+ * live charts: the forming bar must appear in the output so its EMA / RSI
16
+ * can be plotted. Callers that want "closed bars only" should drop the
17
+ * last element if `bucketEnd > lastBucketStart + targetIntervalMs - baseIntervalMs`
18
+ * (or equivalently, if `sourceEnd - sourceStart + 1 < bucketSize`).
19
+ *
20
+ * Aggregation rules:
21
+ * - timestamp = floor(firstBar.timestamp / targetIntervalMs) * targetIntervalMs
22
+ * - open = firstBar.open
23
+ * - close = lastBar.close
24
+ * - high = max over [start, end]
25
+ * - low = min over [start, end]
26
+ * - volume = sum over [start, end]
27
+ * - sourceStart, sourceEnd = inclusive base-index range
28
+ */
29
+
30
+ import type { BaseBar, ResampledBar } from './types'
31
+
32
+ /**
33
+ * @internal — building block used by `createMtfController`. Reachable today
34
+ * via the top-level `@klinechart-quant/core` barrel but **NOT
35
+ * part of the supported public API**. typedoc / api-extractor
36
+ * hide it from generated docs. Prefer the controller factory
37
+ * for stable user code. Closes API audit BLOCKER-002.
38
+ */
39
+ export function resampleBars(
40
+ bars: ReadonlyArray<BaseBar>,
41
+ baseIntervalMs: number,
42
+ targetIntervalMs: number,
43
+ ): ReadonlyArray<ResampledBar> {
44
+ if (!Number.isFinite(baseIntervalMs) || baseIntervalMs <= 0) {
45
+ throw new KLineChartError('MTF_CONFIG_INVALID', 'resampleBars: baseIntervalMs must be a positive finite number')
46
+ }
47
+ if (!Number.isFinite(targetIntervalMs) || targetIntervalMs <= 0) {
48
+ throw new KLineChartError('MTF_CONFIG_INVALID', 'resampleBars: targetIntervalMs must be a positive finite number')
49
+ }
50
+ if (targetIntervalMs % baseIntervalMs !== 0) {
51
+ throw new KLineChartError(
52
+ 'MTF_CONFIG_INVALID',
53
+ `resampleBars: targetIntervalMs (${targetIntervalMs}) must be an integer ` +
54
+ `multiple of baseIntervalMs (${baseIntervalMs}); got remainder ` +
55
+ `${targetIntervalMs % baseIntervalMs}`,
56
+ )
57
+ }
58
+
59
+ if (bars.length === 0) return []
60
+
61
+ // Fast path: no aggregation required. Caller may still want shape parity
62
+ // (each base bar gets sourceStart === sourceEnd === its own index), so we
63
+ // wrap each base bar as a 1-source-bar `ResampledBar`.
64
+ if (targetIntervalMs === baseIntervalMs) {
65
+ const out: ResampledBar[] = new Array(bars.length)
66
+ for (let i = 0; i < bars.length; i++) {
67
+ const b = bars[i]
68
+ out[i] = {
69
+ timestamp: b.timestamp,
70
+ open: b.open,
71
+ high: b.high,
72
+ low: b.low,
73
+ close: b.close,
74
+ volume: b.volume,
75
+ sourceStart: i,
76
+ sourceEnd: i,
77
+ }
78
+ }
79
+ return out
80
+ }
81
+
82
+ const out: ResampledBar[] = []
83
+
84
+ let bucketStart = -1 // inclusive index in `bars`
85
+ let bucketTs = 0
86
+ let open = 0
87
+ let high = -Infinity
88
+ let low = Infinity
89
+ let close = 0
90
+ let volume = 0
91
+
92
+ const flush = (endIdx: number): void => {
93
+ if (bucketStart < 0) return
94
+ out.push({
95
+ timestamp: bucketTs,
96
+ open,
97
+ high,
98
+ low,
99
+ close,
100
+ volume,
101
+ sourceStart: bucketStart,
102
+ sourceEnd: endIdx,
103
+ })
104
+ }
105
+
106
+ for (let i = 0; i < bars.length; i++) {
107
+ const bar = bars[i]
108
+ const ts = Math.floor(bar.timestamp / targetIntervalMs) * targetIntervalMs
109
+
110
+ if (bucketStart < 0 || ts !== bucketTs) {
111
+ // Boundary crossed (or first iteration). Flush the previous bucket.
112
+ if (bucketStart >= 0) flush(i - 1)
113
+ bucketStart = i
114
+ bucketTs = ts
115
+ open = bar.open
116
+ high = bar.high
117
+ low = bar.low
118
+ close = bar.close
119
+ volume = bar.volume
120
+ continue
121
+ }
122
+
123
+ // Same bucket: fold this bar in.
124
+ if (bar.high > high) high = bar.high
125
+ if (bar.low < low) low = bar.low
126
+ close = bar.close
127
+ volume += bar.volume
128
+ }
129
+
130
+ // Final bucket — may be partial (fewer than targetIntervalMs/baseIntervalMs bars).
131
+ flush(bars.length - 1)
132
+
133
+ return out
134
+ }
@@ -0,0 +1,148 @@
1
+ /**
2
+ * Public types for the Multi-Timeframe (MTF) overlay module.
3
+ *
4
+ * Naming: "base" = the chart's primary timeframe (e.g. 5m), "higher tf" =
5
+ * the resampled timeframe an MTF series lives on (e.g. 1h). The module never
6
+ * downscales — you can only lift values from a coarser tf onto a finer one.
7
+ *
8
+ * Time semantics:
9
+ * - Every `timestamp` is in milliseconds since the Unix epoch.
10
+ * - A base bar's `timestamp` is the OPEN of that bar's interval (aligned
11
+ * to `baseIntervalMs` boundary, implicitly).
12
+ * - A resampled (higher-tf) bar's `timestamp` is the OPEN of its bucket,
13
+ * computed as `floor(firstBaseBar.timestamp / targetIntervalMs) * targetIntervalMs`.
14
+ * - A higher-tf bar's interval is `[timestamp, timestamp + targetIntervalMs)`.
15
+ *
16
+ * The MTF controller does NOT bring its own indicator math. The caller
17
+ * supplies a `compute` function that takes resampled bars and returns one
18
+ * number per resampled bar. Any indicator (EMA, RSI, custom) can be lifted
19
+ * to MTF by writing such a compute fn.
20
+ */
21
+
22
+ import type { Signal } from '../../reactivity'
23
+
24
+ /**
25
+ * One bar of the BASE timeframe (the chart's primary candle stream).
26
+ *
27
+ * `timestamp` is the bar's OPEN, expected to be aligned to `baseIntervalMs`.
28
+ * The module does not enforce alignment — it trusts the caller's stream.
29
+ */
30
+ export interface BaseBar {
31
+ timestamp: number
32
+ open: number
33
+ high: number
34
+ low: number
35
+ close: number
36
+ volume: number
37
+ }
38
+
39
+ /**
40
+ * A bar produced by aggregating `[sourceStart, sourceEnd]` (inclusive
41
+ * indices into the input base-bar array) up to a higher timeframe.
42
+ *
43
+ * `sourceEnd === sourceStart` is allowed (single-base-bar bucket) — see
44
+ * the "partial last bucket" semantics in `resampleBars`.
45
+ */
46
+ export interface ResampledBar extends BaseBar {
47
+ /** First base-bar index aggregated into this bucket (inclusive). */
48
+ sourceStart: number
49
+ /** Last base-bar index aggregated into this bucket (inclusive). */
50
+ sourceEnd: number
51
+ }
52
+
53
+ /**
54
+ * Definition of one MTF series. The controller owns the resampling and the
55
+ * alignment; the caller owns the indicator math (`compute`).
56
+ */
57
+ export interface MtfSeriesDefinition {
58
+ /** Stable user-facing identifier. Re-using an existing id is rejected. */
59
+ id: string
60
+ /** Display label, e.g. `"EMA(20) 1h"`. The controller never reads this. */
61
+ label: string
62
+ /** Higher-tf bucket size in ms. Must be a positive multiple of base tf. */
63
+ targetIntervalMs: number
64
+ /**
65
+ * Pure function: resampled bars → per-bar value array of the same length.
66
+ * Called once per `setBaseBars`, `addSeries`, `updateSeries`, and once per
67
+ * `appendBaseBar`. MUST NOT mutate the input.
68
+ */
69
+ compute: (resampledBars: ReadonlyArray<ResampledBar>) => ReadonlyArray<number>
70
+ }
71
+
72
+ /**
73
+ * One active MTF series in the controller's snapshot.
74
+ *
75
+ * `alignedValues.length === baseBars.length` always holds after any state
76
+ * transition. Leading entries are `null` for base bars that fall before the
77
+ * first higher-tf bucket opens.
78
+ */
79
+ export interface ActiveMtfSeries {
80
+ definition: MtfSeriesDefinition
81
+ /**
82
+ * Forward-filled values aligned to the base bar index. Same length as the
83
+ * controller's base-bar buffer. `null` only where no higher-tf bar covers
84
+ * the base bar's timestamp (i.e. before the first bucket opens).
85
+ */
86
+ alignedValues: ReadonlyArray<number | null>
87
+ }
88
+
89
+ /**
90
+ * Reactive MTF controller. The `series` signal updates synchronously on every
91
+ * state-mutating call (`setBaseBars`, `addSeries`, `removeSeries`,
92
+ * `updateSeries`, `appendBaseBar`). After `dispose()`, mutation calls become
93
+ * no-ops and the signal stops firing.
94
+ */
95
+ export interface MtfController {
96
+ /** Current snapshot of every series with aligned values. */
97
+ readonly series: Signal<ReadonlyArray<ActiveMtfSeries>>
98
+
99
+ /**
100
+ * Replace the base bar buffer in one shot and recompute every series —
101
+ * canonical method, aligned with the cross-controller `setData()`
102
+ * convention (AnchoredVwapController). Closes API audit BLOCKER-001.
103
+ * `baseIntervalMs` must evenly divide every series' `targetIntervalMs`.
104
+ */
105
+ setData(bars: ReadonlyArray<BaseBar>, baseIntervalMs: number): void
106
+
107
+ /**
108
+ * @deprecated since 0.1.0-alpha.1 — use {@link MtfController.setData}.
109
+ * Preserved as a non-removing alias for at least 6 months.
110
+ */
111
+ setBaseBars(bars: ReadonlyArray<BaseBar>, baseIntervalMs: number): void
112
+
113
+ /**
114
+ * Register a new series. Returns the series id.
115
+ * Throws if `def.id` is already in use or `targetIntervalMs` is not a
116
+ * positive multiple of the current `baseIntervalMs` (when bars are set).
117
+ */
118
+ addSeries(def: MtfSeriesDefinition): string
119
+
120
+ /** Remove a series by id. Returns true if removed, false if not found. */
121
+ removeSeries(id: string): boolean
122
+
123
+ /**
124
+ * Patch a series in place. Returns true if found.
125
+ * Re-runs `compute` whenever `targetIntervalMs` or `compute` changes.
126
+ */
127
+ updateSeries(
128
+ id: string,
129
+ patch: Partial<Omit<MtfSeriesDefinition, 'id'>>,
130
+ ): boolean
131
+
132
+ /**
133
+ * Append one base bar at the tail — canonical method, aligned with the
134
+ * cross-controller `append()` convention (AnchoredVwapController).
135
+ * Triggers a single per-series compute over the updated resampled
136
+ * bars — NOT a from-scratch recompute over the whole base buffer.
137
+ */
138
+ append(bar: BaseBar): void
139
+
140
+ /**
141
+ * @deprecated since 0.1.0-alpha.1 — use {@link MtfController.append}.
142
+ * Preserved as a non-removing alias for at least 6 months.
143
+ */
144
+ appendBaseBar(bar: BaseBar): void
145
+
146
+ /** Tear down. After this, all mutators are no-ops; the signal stops. */
147
+ dispose(): void
148
+ }