@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,226 @@
1
+ /**
2
+ * PriceScale factory — price ↔ screen Y (ROADMAP §1.2) + origin-shift policy
3
+ * (ROADMAP §2.5).
4
+ *
5
+ * Linear mapping (top-origin, Y grows downward):
6
+ *
7
+ * t = (p - visibleMin) / (visibleMax - visibleMin)
8
+ * y = height - t * height
9
+ * inverse: p = visibleMin + (1 - y / height) * (visibleMax - visibleMin)
10
+ *
11
+ * Log mapping (only valid for strictly positive ranges):
12
+ *
13
+ * t = (ln(p) - ln(visibleMin)) / (ln(visibleMax) - ln(visibleMin))
14
+ * y = height - t * height
15
+ * inverse: p = exp(ln(visibleMin) + (1 - y / height) * (ln(visibleMax) - ln(visibleMin)))
16
+ *
17
+ * Origin-shift policy: lives inside this scale and is consulted on every
18
+ * `setVisibleRange`. It is intentionally in **linear-price space**, applied
19
+ * *before* the log transform — that matches the existing engine and keeps the
20
+ * "shift is just a translation" mental model clean. (Log-space shift is also
21
+ * mathematically valid; it would compose better with sub-cent log-axis zoom on
22
+ * astronomically high prices, but we have no such use case and this keeps
23
+ * parity with the legacy renderer.)
24
+ *
25
+ * Degenerate range handling: when `visibleMin === visibleMax`, `priceToY` and
26
+ * `yToPrice` would divide by zero. We pin the output to `height / 2` (the
27
+ * geometric center) and document that the caller should treat this as
28
+ * "everything at the same price"; this is preferred over throwing because
29
+ * mid-frame `setVisibleRange(p, p)` is reachable from external data feeds and
30
+ * we don't want one bad row to crash the chart.
31
+ */
32
+
33
+ import { createSignal } from '../reactivity/signal'
34
+ import { KLineChartError } from '../errors'
35
+ import type { Signal } from '../reactivity/signal'
36
+ import { createOriginShiftPolicy, type OriginShiftPolicy } from './originShift'
37
+ import type { PriceScale, ScaleMode } from './types'
38
+
39
+ export interface PriceScaleConfig {
40
+ /** Initial mode. Default `'linear'`. */
41
+ initialMode?: ScaleMode
42
+ /** Initial visibleMin. Default 0. (Must be > 0 if initialMode === 'log'.) */
43
+ initialVisibleMin?: number
44
+ /** Initial visibleMax. Default 100. */
45
+ initialVisibleMax?: number
46
+ /** Initial canvas height in logical px. Default 480. */
47
+ initialHeight?: number
48
+ /**
49
+ * Threshold for the origin-shift rebaseline policy. Default 0.01 (1% of
50
+ * visible range). See `originShift.ts` for the rationale.
51
+ */
52
+ originShiftThreshold?: number
53
+ }
54
+
55
+ export function createPriceScale(config: PriceScaleConfig = {}): PriceScale {
56
+ const initialMode: ScaleMode = config.initialMode ?? 'linear'
57
+ const initialVisibleMin = config.initialVisibleMin ?? 0
58
+ const initialVisibleMax = config.initialVisibleMax ?? 100
59
+ const initialHeight = config.initialHeight ?? 480
60
+
61
+ if (!(initialVisibleMax >= initialVisibleMin)) {
62
+ throw new KLineChartError(
63
+ 'SCALE_RANGE_INVALID',
64
+ `createPriceScale: initialVisibleMax (${initialVisibleMax}) must be >= initialVisibleMin (${initialVisibleMin})`,
65
+ )
66
+ }
67
+ if (initialMode === 'log' && !(initialVisibleMin > 0)) {
68
+ throw new KLineChartError(
69
+ 'SCALE_LOG_REQUIRES_POSITIVE',
70
+ `createPriceScale: log mode requires visibleMin > 0, got ${initialVisibleMin}`,
71
+ )
72
+ }
73
+ if (!(initialHeight > 0)) {
74
+ throw new KLineChartError('SCALE_HEIGHT_INVALID', `createPriceScale: initialHeight must be > 0, got ${initialHeight}`)
75
+ }
76
+
77
+ const mode = createSignal<ScaleMode>(initialMode)
78
+ const visibleMin = createSignal(initialVisibleMin)
79
+ const visibleMax = createSignal(initialVisibleMax)
80
+ const height = createSignal(initialHeight)
81
+
82
+ const initialRef = (initialVisibleMin + initialVisibleMax) / 2
83
+ const policy: OriginShiftPolicy = createOriginShiftPolicy(
84
+ initialRef,
85
+ config.originShiftThreshold,
86
+ )
87
+ const originShiftRef = createSignal(policy.ref)
88
+
89
+ let disposed = false
90
+ /**
91
+ * Post-dispose: mutator calls become silent no-ops. See createTimeScale.ts
92
+ * for the rationale + API audit BLOCKER-004 reference. Returns `true` when
93
+ * the operation should proceed.
94
+ */
95
+ const guard = (): boolean => !disposed
96
+
97
+ /**
98
+ * Run `policy.maybeRebaseline` with the latest visible range and, if it
99
+ * rebased, mirror the new value into the reactive `originShiftRef` signal
100
+ * so subscribers (uniform updaters, GPU buffer uploaders) can pick it up.
101
+ */
102
+ const syncOriginShift = (): void => {
103
+ const min = visibleMin.peek()
104
+ const max = visibleMax.peek()
105
+ const range = max - min
106
+ const mid = (min + max) / 2
107
+ if (policy.maybeRebaseline(mid, range)) {
108
+ originShiftRef.set(policy.ref)
109
+ }
110
+ }
111
+
112
+ const priceToYLinear = (p: number): number => {
113
+ const min = visibleMin.peek()
114
+ const max = visibleMax.peek()
115
+ const h = height.peek()
116
+ const span = max - min
117
+ if (span <= 0) return h / 2
118
+ const t = (p - min) / span
119
+ return h - t * h
120
+ }
121
+
122
+ const priceToYLog = (p: number): number => {
123
+ const min = visibleMin.peek()
124
+ const max = visibleMax.peek()
125
+ const h = height.peek()
126
+ // Defensive — setMode('log') already rejects bad ranges, but we keep
127
+ // priceToY total so a stray p<=0 doesn't NaN out the whole chart.
128
+ if (p <= 0 || min <= 0 || max <= 0 || max <= min) return h / 2
129
+ const t = (Math.log(p) - Math.log(min)) / (Math.log(max) - Math.log(min))
130
+ return h - t * h
131
+ }
132
+
133
+ const yToPriceLinear = (y: number): number => {
134
+ const min = visibleMin.peek()
135
+ const max = visibleMax.peek()
136
+ const h = height.peek()
137
+ const span = max - min
138
+ if (span <= 0) return min
139
+ return min + (1 - y / h) * span
140
+ }
141
+
142
+ const yToPriceLog = (y: number): number => {
143
+ const min = visibleMin.peek()
144
+ const max = visibleMax.peek()
145
+ const h = height.peek()
146
+ if (min <= 0 || max <= 0 || max <= min) return min
147
+ const lmin = Math.log(min)
148
+ const lmax = Math.log(max)
149
+ const ly = lmin + (1 - y / h) * (lmax - lmin)
150
+ return Math.exp(ly)
151
+ }
152
+
153
+ const scale: PriceScale = {
154
+ mode,
155
+ visibleMin,
156
+ visibleMax,
157
+ height,
158
+ originShiftRef: originShiftRef as Signal<number>,
159
+
160
+ priceToY(p: number): number {
161
+ return mode.peek() === 'log' ? priceToYLog(p) : priceToYLinear(p)
162
+ },
163
+
164
+ yToPrice(y: number): number {
165
+ return mode.peek() === 'log' ? yToPriceLog(y) : yToPriceLinear(y)
166
+ },
167
+
168
+ setMode(next: ScaleMode): void {
169
+ if (!guard()) return
170
+ if (next === 'log') {
171
+ const min = visibleMin.peek()
172
+ const max = visibleMax.peek()
173
+ if (!(min > 0) || !(max > 0)) {
174
+ throw new KLineChartError(
175
+ 'SCALE_LOG_REQUIRES_POSITIVE',
176
+ `PriceScale.setMode('log'): requires visibleMin > 0 and visibleMax > 0, got min=${min}, max=${max}`,
177
+ )
178
+ }
179
+ }
180
+ mode.set(next)
181
+ },
182
+
183
+ setVisibleRange(min: number, max: number): void {
184
+ if (!guard()) return
185
+ if (!Number.isFinite(min) || !Number.isFinite(max)) {
186
+ throw new KLineChartError(
187
+ 'SCALE_RANGE_INVALID',
188
+ `PriceScale.setVisibleRange: both bounds must be finite, got min=${min}, max=${max}`,
189
+ )
190
+ }
191
+ if (max < min) {
192
+ throw new KLineChartError(
193
+ 'SCALE_RANGE_INVALID',
194
+ `PriceScale.setVisibleRange: max (${max}) must be >= min (${min})`,
195
+ )
196
+ }
197
+ if (mode.peek() === 'log' && !(min > 0)) {
198
+ throw new KLineChartError(
199
+ 'SCALE_LOG_REQUIRES_POSITIVE',
200
+ `PriceScale.setVisibleRange: log mode requires min > 0, got ${min}`,
201
+ )
202
+ }
203
+ visibleMin.set(min)
204
+ visibleMax.set(max)
205
+ syncOriginShift()
206
+ },
207
+
208
+ setHeight(h: number): void {
209
+ if (!guard()) return
210
+ if (!(h > 0)) {
211
+ throw new KLineChartError('SCALE_HEIGHT_INVALID', `PriceScale.setHeight: height must be > 0, got ${h}`)
212
+ }
213
+ height.set(h)
214
+ },
215
+
216
+ toShiftedFp32(p: number): number {
217
+ return policy.shift(p)
218
+ },
219
+
220
+ dispose(): void {
221
+ disposed = true
222
+ },
223
+ }
224
+
225
+ return scale
226
+ }
@@ -0,0 +1,150 @@
1
+ /**
2
+ * TimeScale factory — discrete bar-index ↔ screen X mapping (ROADMAP §1.1).
3
+ *
4
+ * The math is one-line in each direction; the value of this factory is the
5
+ * reactive plumbing (signals so adapters can subscribe) and the optional
6
+ * wall-clock calendar that maps bar indices ↔ timestamps.
7
+ *
8
+ * forward: x(i) = (i - firstVisibleIndex) * barWidth + leftPadding
9
+ * inverse: i(x) = (x - leftPadding) / barWidth + firstVisibleIndex
10
+ *
11
+ * Calendar semantics: when the user attaches a `barTimestamps` array, we treat
12
+ * bar index `i` as the array index. Integer indices map directly; fractional
13
+ * indices linearly interpolate between neighboring timestamps. Anything
14
+ * outside `[0, N-1]` returns `null` — the caller decides whether to clamp,
15
+ * extrapolate, or display a "—" label.
16
+ */
17
+
18
+ import { createSignal } from '../reactivity/signal'
19
+ import { KLineChartError } from '../errors'
20
+ import type { TimeScale } from './types'
21
+
22
+ export interface TimeScaleConfig {
23
+ /** Default firstVisibleIndex. Fractional/negative allowed. Default 0. */
24
+ initialFirstVisibleIndex?: number
25
+ /** Default barWidth in logical px. Must be > 0. Default 8. */
26
+ initialBarWidth?: number
27
+ /** Default leftPadding in logical px. Default 0. */
28
+ initialLeftPadding?: number
29
+ }
30
+
31
+ export function createTimeScale(config: TimeScaleConfig = {}): TimeScale {
32
+ const initialFirstVisibleIndex = config.initialFirstVisibleIndex ?? 0
33
+ const initialBarWidth = config.initialBarWidth ?? 8
34
+ const initialLeftPadding = config.initialLeftPadding ?? 0
35
+
36
+ if (!(initialBarWidth > 0)) {
37
+ throw new KLineChartError('SCALE_BAR_WIDTH_INVALID', `createTimeScale: initialBarWidth must be > 0, got ${initialBarWidth}`)
38
+ }
39
+
40
+ const firstVisibleIndex = createSignal(initialFirstVisibleIndex)
41
+ const barWidth = createSignal(initialBarWidth)
42
+ const leftPadding = createSignal(initialLeftPadding)
43
+
44
+ let calendar: { barTimestamps: ReadonlyArray<number> } | null = null
45
+ let disposed = false
46
+
47
+ /**
48
+ * Post-dispose: mutator calls become silent no-ops. This matches the
49
+ * convention used by every other controller in @klinechart-quant/core
50
+ * (IndicatorSelector, Toolbar, Drawing, Alerts, Replay, VolumeProfile,
51
+ * Footprint, OrderBookHeatmap, AnchoredVwap, MtfOverlay). Throwing on
52
+ * stale references — as the original implementation did — was the API
53
+ * audit BLOCKER-004 (docs/audit/API_REVIEW.md) divergence; harmonized
54
+ * to silent-no-op here.
55
+ *
56
+ * Returns `true` when the operation should proceed (controller live),
57
+ * `false` when it should be skipped (post-dispose).
58
+ */
59
+ const guard = (): boolean => !disposed
60
+
61
+ const scale: TimeScale = {
62
+ firstVisibleIndex,
63
+ barWidth,
64
+ leftPadding,
65
+
66
+ xToBarIndex(x: number): number {
67
+ // We deliberately read with `.peek()` here — these methods are pure
68
+ // queries, they must not register the caller as a reactive subscriber.
69
+ const lp = leftPadding.peek()
70
+ const bw = barWidth.peek()
71
+ const fvi = firstVisibleIndex.peek()
72
+ return (x - lp) / bw + fvi
73
+ },
74
+
75
+ barIndexToX(i: number): number {
76
+ const lp = leftPadding.peek()
77
+ const bw = barWidth.peek()
78
+ const fvi = firstVisibleIndex.peek()
79
+ return (i - fvi) * bw + lp
80
+ },
81
+
82
+ setFirstVisibleIndex(i: number): void {
83
+ if (!guard()) return
84
+ firstVisibleIndex.set(i)
85
+ },
86
+
87
+ setBarWidth(w: number): void {
88
+ if (!guard()) return
89
+ if (!(w > 0)) {
90
+ throw new KLineChartError('SCALE_BAR_WIDTH_INVALID', `TimeScale.setBarWidth: barWidth must be > 0, got ${w}`)
91
+ }
92
+ barWidth.set(w)
93
+ },
94
+
95
+ setLeftPadding(p: number): void {
96
+ if (!guard()) return
97
+ leftPadding.set(p)
98
+ },
99
+
100
+ setCalendar(c) {
101
+ if (!guard()) return
102
+ calendar = c
103
+ },
104
+
105
+ timeToBarIndex(timestamp: number): number | null {
106
+ if (calendar === null) return null
107
+ const ts = calendar.barTimestamps
108
+ const n = ts.length
109
+ if (n === 0) return null
110
+ // Binary search for the upper bound of `timestamp` in `ts`.
111
+ // Returns the fractional index that interpolates linearly between
112
+ // bracketing bars. Outside the calendar → null.
113
+ if (timestamp < ts[0] || timestamp > ts[n - 1]) return null
114
+ if (timestamp === ts[n - 1]) return n - 1
115
+ let lo = 0
116
+ let hi = n - 1
117
+ while (hi - lo > 1) {
118
+ const mid = (lo + hi) >>> 1
119
+ if (ts[mid] <= timestamp) lo = mid
120
+ else hi = mid
121
+ }
122
+ const span = ts[hi] - ts[lo]
123
+ if (span <= 0) return lo
124
+ return lo + (timestamp - ts[lo]) / span
125
+ },
126
+
127
+ barIndexToTime(i: number): number | null {
128
+ if (calendar === null) return null
129
+ const ts = calendar.barTimestamps
130
+ const n = ts.length
131
+ if (n === 0) return null
132
+ if (i < 0 || i > n - 1) return null
133
+ const lo = Math.floor(i)
134
+ const hi = Math.min(lo + 1, n - 1)
135
+ if (lo === hi) return ts[lo]
136
+ const frac = i - lo
137
+ return ts[lo] + (ts[hi] - ts[lo]) * frac
138
+ },
139
+
140
+ dispose(): void {
141
+ // Signals don't allocate listeners we own; we just mark the
142
+ // instance as dead so writes throw and tests can assert dispose
143
+ // semantics. Reads remain functional as pure math.
144
+ disposed = true
145
+ calendar = null
146
+ },
147
+ }
148
+
149
+ return scale
150
+ }
@@ -0,0 +1,9 @@
1
+ export type { ScaleMode, TimeScale, PriceScale } from './types'
2
+ export { createTimeScale, type TimeScaleConfig } from './createTimeScale'
3
+ export { createPriceScale, type PriceScaleConfig } from './createPriceScale'
4
+ export {
5
+ computeAnchoredZoom,
6
+ type AnchoredZoomOptions,
7
+ type AnchoredZoomResult,
8
+ } from './anchoredZoom'
9
+ export { createOriginShiftPolicy, type OriginShiftPolicy } from './originShift'
@@ -0,0 +1,111 @@
1
+ import { KLineChartError } from '../errors'
2
+ /**
3
+ * Origin-shift policy — ROADMAP §2.5, refined per the upstream PR feedback
4
+ * about *rebaseline drift*.
5
+ *
6
+ * Background. GPUs run fp32 (~7 decimal digits of precision). At BTC-tier
7
+ * prices (~67,000) and tick sizes (~0.01) the absolute price burns most of
8
+ * the mantissa, and a subtraction like `(p - pMin)` inside a zoomed-in
9
+ * sub-dollar range produces catastrophic cancellation. The cheap fix is to
10
+ * subtract a "reference value" `ref` on the CPU (which is fp64 and can spare
11
+ * it) before uploading, so the GPU only ever sees relative deltas in the
12
+ * 0.1-or-so range.
13
+ *
14
+ * Why this is its own policy object, and why **threshold-based**:
15
+ *
16
+ * The naive implementation — "every frame, set `ref = midpoint of current
17
+ * visible range`" — looks right but is actively harmful on pan. Every time
18
+ * the user drags one logical pixel, `ref` changes by one logical-pixel-of-
19
+ * price, and *all* prices get re-quantized to a slightly different fp32
20
+ * rounding. The result is a continuous, sub-pixel **shimmer** of the entire
21
+ * chart that the eye perceives as soft jitter even when no actual data has
22
+ * changed. (This is the bug I flagged on the upstream PR.)
23
+ *
24
+ * The fix is to keep `ref` *stable* until the visible-range center has
25
+ * drifted far enough that the fp32 budget is at risk of being exhausted —
26
+ * then rebaseline once, deliberately. The visible artifact becomes a single
27
+ * imperceptible discrete snap, instead of a continuous wobble.
28
+ *
29
+ * In practice 1% of the visible range works well: at a 100-dollar range you
30
+ * tolerate `ref` being 1 dollar off-center before re-snapping, which is
31
+ * nowhere near the fp32 cliff but cuts rebaselines from "every frame" to
32
+ * a handful per pan gesture.
33
+ *
34
+ * Edge cases worth documenting:
35
+ *
36
+ * - `threshold === 0` forces a rebaseline on *every* call where the midpoint
37
+ * differs from `ref` at all — this is the legacy "naive" behaviour, kept
38
+ * for parity tests against the bug we're avoiding.
39
+ *
40
+ * - `threshold >= 1` effectively disables rebaselining, useful when an
41
+ * adapter wants to manage `ref` externally.
42
+ *
43
+ * - A `currentRange` of zero (degenerate, visibleMin === visibleMax) is
44
+ * treated as "no signal" — we don't rebaseline because we cannot compute a
45
+ * meaningful normalized drift. The caller is responsible for handling the
46
+ * degenerate range elsewhere.
47
+ */
48
+
49
+ export interface OriginShiftPolicy {
50
+ /** Current reference value. Subtract this from any price before upload. */
51
+ readonly ref: number
52
+ /** Subtract `ref` from `value`. The fp32-safe number to upload. */
53
+ shift(value: number): number
54
+ /**
55
+ * Maybe rebaseline. Returns `true` iff `ref` was updated.
56
+ *
57
+ * Policy: rebaseline only when
58
+ * `|currentMid - ref| / currentRange > threshold`.
59
+ * On rebaseline, `ref` becomes `currentMid`.
60
+ */
61
+ maybeRebaseline(currentMid: number, currentRange: number): boolean
62
+ }
63
+
64
+ const DEFAULT_THRESHOLD = 0.01
65
+
66
+ /**
67
+ * @internal — building block used by `createPriceScale`. Reachable today
68
+ * via the top-level `@klinechart-quant/core` barrel but **NOT
69
+ * part of the supported public API**. typedoc / api-extractor
70
+ * hide it from generated docs. Prefer the controller factory
71
+ * for stable user code. Closes API audit BLOCKER-002.
72
+ */
73
+ export function createOriginShiftPolicy(
74
+ initialRef: number,
75
+ threshold: number = DEFAULT_THRESHOLD,
76
+ ): OriginShiftPolicy {
77
+ if (!Number.isFinite(initialRef)) {
78
+ throw new KLineChartError('INVALID_PARAM', `createOriginShiftPolicy: initialRef must be finite, got ${initialRef}`)
79
+ }
80
+ if (!Number.isFinite(threshold) || threshold < 0) {
81
+ throw new KLineChartError('INVALID_PARAM', `createOriginShiftPolicy: threshold must be >= 0, got ${threshold}`)
82
+ }
83
+
84
+ let ref = initialRef
85
+
86
+ const policy: OriginShiftPolicy = {
87
+ get ref() {
88
+ return ref
89
+ },
90
+ shift(value: number): number {
91
+ return value - ref
92
+ },
93
+ maybeRebaseline(currentMid: number, currentRange: number): boolean {
94
+ // Degenerate range — refuse to rebaseline. Caller handles this elsewhere.
95
+ if (!Number.isFinite(currentMid) || !Number.isFinite(currentRange) || currentRange <= 0) {
96
+ return false
97
+ }
98
+
99
+ const drift = Math.abs(currentMid - ref)
100
+ const normalized = drift / currentRange
101
+
102
+ if (normalized > threshold) {
103
+ ref = currentMid
104
+ return true
105
+ }
106
+ return false
107
+ },
108
+ }
109
+
110
+ return policy
111
+ }
@@ -0,0 +1,100 @@
1
+ /**
2
+ * Coordinate-system interfaces for the headless core.
3
+ *
4
+ * The `TimeScale` maps **bar index** (a discrete-but-fractional sequence number)
5
+ * to a screen X position, per ROADMAP §1.1. Wall-clock time is a secondary
6
+ * label, available only when a calendar is attached.
7
+ *
8
+ * The `PriceScale` maps a (possibly very narrow) price range to screen Y per
9
+ * ROADMAP §1.2 — and additionally exposes an origin-shift policy so adapters
10
+ * can keep GPU uploads in safe fp32 territory (ROADMAP §2.5).
11
+ *
12
+ * Both scales are **reactive**: their core state is exposed as signals so the
13
+ * React/Vue/Angular adapter layer can subscribe without re-implementing the
14
+ * change-detection plumbing.
15
+ */
16
+
17
+ import type { Signal } from '../reactivity/signal'
18
+
19
+ /** Linear (arithmetic) or logarithmic Y mapping. */
20
+ export type ScaleMode = 'linear' | 'log'
21
+
22
+ /**
23
+ * Discrete bar-index ↔ screen X mapping (ROADMAP §1.1).
24
+ *
25
+ * Forward equation (the only equation a renderer needs to know):
26
+ *
27
+ * x(i) = (i - firstVisibleIndex) * barWidth + leftPadding
28
+ *
29
+ * Inverse, used by anchored zoom and hit-testing:
30
+ *
31
+ * i(x) = (x - leftPadding) / barWidth + firstVisibleIndex
32
+ *
33
+ * `firstVisibleIndex` is allowed to be **fractional, negative, or > N**;
34
+ * this is what lets the user pan to "half a bar" or scroll into the future.
35
+ */
36
+ export interface TimeScale {
37
+ /** Inverse: screen X (logical px) → fractional bar index. */
38
+ xToBarIndex(x: number): number
39
+ /** Forward: fractional bar index → screen X (logical px). */
40
+ barIndexToX(i: number): number
41
+
42
+ /** Fractional, may be negative or > N. */
43
+ readonly firstVisibleIndex: Signal<number>
44
+ /** Logical pixels per bar. Clamped by the caller (e.g. zoom) not the scale. */
45
+ readonly barWidth: Signal<number>
46
+ /** Logical pixels added on the left edge before bar 0. */
47
+ readonly leftPadding: Signal<number>
48
+
49
+ setFirstVisibleIndex(i: number): void
50
+ setBarWidth(w: number): void
51
+ setLeftPadding(p: number): void
52
+
53
+ /**
54
+ * Attach (or detach with `null`) a wall-clock calendar so the scale can
55
+ * answer `timeToBarIndex` / `barIndexToTime`. Bar indices not covered by
56
+ * the calendar return `null` — *time is a label, not a coordinate*.
57
+ */
58
+ setCalendar(c: { barTimestamps: ReadonlyArray<number> } | null): void
59
+
60
+ /** wall-clock ms → fractional bar index; `null` if no calendar / out of range. */
61
+ timeToBarIndex(timestamp: number): number | null
62
+ /** fractional bar index → wall-clock ms; `null` if no calendar / out of range. */
63
+ barIndexToTime(i: number): number | null
64
+
65
+ /** Detach signal subscribers and release any internal listeners. */
66
+ dispose(): void
67
+ }
68
+
69
+ /**
70
+ * Price → screen Y mapping (ROADMAP §1.2) plus an origin-shift policy
71
+ * (ROADMAP §2.5) so adapters can upload fp32-safe values to the GPU.
72
+ *
73
+ * Coordinate convention: top-origin, Y increases downward (DOM standard).
74
+ * A price ≥ `visibleMax` maps to y = 0, a price ≤ `visibleMin` maps to
75
+ * y = `height`.
76
+ */
77
+ export interface PriceScale {
78
+ /** Forward: price → screen Y (top-origin, increases downward). */
79
+ priceToY(p: number): number
80
+ /** Inverse: screen Y → price. */
81
+ yToPrice(y: number): number
82
+
83
+ readonly mode: Signal<ScaleMode>
84
+ readonly visibleMin: Signal<number>
85
+ readonly visibleMax: Signal<number>
86
+ readonly height: Signal<number>
87
+
88
+ /** Set `'linear'` or `'log'`; throws on `'log'` if `visibleMin <= 0`. */
89
+ setMode(mode: ScaleMode): void
90
+ /** Update visible range. Triggers the origin-shift rebaseline check. */
91
+ setVisibleRange(min: number, max: number): void
92
+ setHeight(h: number): void
93
+
94
+ /** Origin-shift reference; managed automatically but exposed for tests. */
95
+ readonly originShiftRef: Signal<number>
96
+ /** Returns `p - originShiftRef.peek()` — what to upload to the GPU as fp32. */
97
+ toShiftedFp32(p: number): number
98
+
99
+ dispose(): void
100
+ }