@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,167 @@
1
+ import { describe, it, expect } from 'vitest'
2
+ import { createPointAndFigure } from '../pointAndFigure'
3
+ import type { OHLCV } from '../types'
4
+
5
+ const bar = (i: number, o: number, h: number, l: number, c: number, v = 100): OHLCV => ({
6
+ timestamp: 1_700_000_000_000 + i * 60_000,
7
+ open: o,
8
+ high: h,
9
+ low: l,
10
+ close: c,
11
+ volume: v,
12
+ })
13
+
14
+ describe('pointAndFigure', () => {
15
+ it('simple uptrend produces a single X column (batch includes in-progress)', () => {
16
+ const pf = createPointAndFigure()
17
+ const out = pf.transform(
18
+ [
19
+ bar(0, 100, 100, 100, 100),
20
+ bar(1, 100, 110, 100, 110),
21
+ bar(2, 110, 120, 110, 120),
22
+ bar(3, 120, 130, 120, 130),
23
+ ],
24
+ { boxSize: 10, reversal: 3 },
25
+ )
26
+ expect(out).toHaveLength(1)
27
+ expect(out[0]!.meta?.direction).toBe('up')
28
+ expect(out[0]!.high).toBeGreaterThan(out[0]!.low)
29
+ })
30
+
31
+ it('a 3-box reversal closes the X column and opens an O column', () => {
32
+ const pf = createPointAndFigure()
33
+ const out = pf.transform(
34
+ [
35
+ bar(0, 100, 100, 100, 100),
36
+ bar(1, 100, 130, 100, 130), // big X column up to 130
37
+ bar(2, 130, 130, 90, 90), // drops 40 (4 boxes), reversal of 3 met
38
+ ],
39
+ { boxSize: 10, reversal: 3 },
40
+ )
41
+ const directions = out.map((b) => b.meta?.direction)
42
+ expect(directions).toContain('up')
43
+ expect(directions).toContain('down')
44
+ // First (closed) column is the X.
45
+ expect(out[0]!.meta?.direction).toBe('up')
46
+ })
47
+
48
+ it('a 2-box reversal stays in the same X column (no flip)', () => {
49
+ const pf = createPointAndFigure()
50
+ const out = pf.transform(
51
+ [
52
+ bar(0, 100, 100, 100, 100),
53
+ bar(1, 100, 130, 100, 130),
54
+ bar(2, 130, 130, 115, 115), // only 1.5 boxes down — below threshold
55
+ ],
56
+ { boxSize: 10, reversal: 3 },
57
+ )
58
+ // Only the in-progress X column should be present.
59
+ expect(out).toHaveLength(1)
60
+ expect(out[0]!.meta?.direction).toBe('up')
61
+ })
62
+
63
+ it('alternating chop emits multiple columns at the reversal threshold', () => {
64
+ const pf = createPointAndFigure()
65
+ const out = pf.transform(
66
+ [
67
+ bar(0, 100, 100, 100, 100),
68
+ bar(1, 100, 130, 100, 130), // X up to 130
69
+ bar(2, 130, 130, 90, 90), // O down (reverse, 4 boxes)
70
+ bar(3, 90, 130, 90, 130), // X back up (reverse from O, 4 boxes)
71
+ bar(4, 130, 130, 90, 90), // O down again
72
+ ],
73
+ { boxSize: 10, reversal: 3 },
74
+ )
75
+ const closed = out.filter((b) => b.sourceBarIndexEnd < 4)
76
+ // Expect at least 3 alternating-direction closed columns.
77
+ expect(closed.length).toBeGreaterThanOrEqual(3)
78
+ const dirs = closed.map((b) => b.meta?.direction)
79
+ // No two consecutive closed columns have the same direction.
80
+ for (let i = 1; i < dirs.length; i++) {
81
+ expect(dirs[i]).not.toBe(dirs[i - 1])
82
+ }
83
+ })
84
+
85
+ it('first bar seeds an X column with low/high snapped to box boundaries', () => {
86
+ const pf = createPointAndFigure()
87
+ const out = pf.transform([bar(0, 103, 117, 102, 115)], { boxSize: 5, reversal: 3 })
88
+ expect(out).toHaveLength(1)
89
+ // low 102 -> 100 (floor of 5), high 117 -> 115 (floor of 5).
90
+ expect(out[0]!.low).toBeCloseTo(100, 10)
91
+ expect(out[0]!.high).toBeCloseTo(115, 10)
92
+ expect(out[0]!.meta?.direction).toBe('up')
93
+ })
94
+
95
+ it('column open and close match the column endpoints', () => {
96
+ const pf = createPointAndFigure()
97
+ const out = pf.transform(
98
+ [bar(0, 100, 100, 100, 100), bar(1, 100, 130, 100, 130)],
99
+ { boxSize: 10, reversal: 3 },
100
+ )
101
+ const col = out[0]!
102
+ // X column: open = start price, close = end price = high.
103
+ expect(col.open).toBeLessThanOrEqual(col.close)
104
+ expect(col.close).toBe(col.high)
105
+ })
106
+
107
+ it('reversal exactly at threshold triggers a flip (>=, not >)', () => {
108
+ const pf = createPointAndFigure()
109
+ const out = pf.transform(
110
+ [
111
+ bar(0, 100, 100, 100, 100),
112
+ bar(1, 100, 130, 100, 130),
113
+ bar(2, 130, 130, 100, 100), // exactly 3 boxes (30) down — at threshold
114
+ ],
115
+ { boxSize: 10, reversal: 3 },
116
+ )
117
+ const dirs = out.map((b) => b.meta?.direction)
118
+ expect(dirs).toContain('up')
119
+ expect(dirs).toContain('down')
120
+ })
121
+
122
+ it('empty input yields empty output', () => {
123
+ const pf = createPointAndFigure()
124
+ const out = pf.transform([], { boxSize: 10, reversal: 3 })
125
+ expect(out).toEqual([])
126
+ })
127
+
128
+ it('throws on invalid config', () => {
129
+ expect(() => createPointAndFigure().transform([], { boxSize: 0, reversal: 3 })).toThrow()
130
+ expect(() => createPointAndFigure().transform([], { boxSize: 10, reversal: 0 })).toThrow()
131
+ })
132
+
133
+ it('incremental closed columns match batch closed columns', () => {
134
+ const series: OHLCV[] = [
135
+ bar(0, 100, 100, 100, 100),
136
+ bar(1, 100, 130, 100, 130),
137
+ bar(2, 130, 130, 90, 90),
138
+ bar(3, 90, 130, 90, 130),
139
+ bar(4, 130, 130, 100, 100),
140
+ bar(5, 100, 140, 100, 140),
141
+ ]
142
+ const batch = createPointAndFigure().transform(series, { boxSize: 10, reversal: 3 })
143
+ const inc = createPointAndFigure()
144
+ inc.transform([], { boxSize: 10, reversal: 3 })
145
+ const incremental: ReturnType<typeof inc.transform> = []
146
+ for (const b of series) {
147
+ for (const out of inc.appendBar!(b)) incremental.push(out)
148
+ }
149
+ // Batch may include a final in-progress column. Compare CLOSED prefix.
150
+ const batchClosed = batch.slice(0, incremental.length)
151
+ expect(incremental.length).toBe(batchClosed.length)
152
+ for (let i = 0; i < batchClosed.length; i++) {
153
+ expect(batchClosed[i]!.open).toBeCloseTo(incremental[i]!.open, 10)
154
+ expect(batchClosed[i]!.close).toBeCloseTo(incremental[i]!.close, 10)
155
+ expect(batchClosed[i]!.meta?.direction).toBe(incremental[i]!.meta?.direction)
156
+ }
157
+ })
158
+
159
+ it('reset() returns to a seed state', () => {
160
+ const pf = createPointAndFigure()
161
+ pf.transform([bar(0, 100, 130, 100, 130)], { boxSize: 10, reversal: 3 })
162
+ pf.reset!()
163
+ const out = pf.appendBar!(bar(1, 200, 215, 200, 215))
164
+ // No closed columns yet; in-progress is now an X anchored at 200/215.
165
+ expect(out).toEqual([])
166
+ })
167
+ })
@@ -0,0 +1,146 @@
1
+ import { describe, it, expect } from 'vitest'
2
+ import { createRangeBars } from '../rangeBars'
3
+ import type { OHLCV } from '../types'
4
+
5
+ const bar = (i: number, o: number, h: number, l: number, c: number, v = 100): OHLCV => ({
6
+ timestamp: 1_700_000_000_000 + i * 60_000,
7
+ open: o,
8
+ high: h,
9
+ low: l,
10
+ close: c,
11
+ volume: v,
12
+ })
13
+
14
+ describe('rangeBars', () => {
15
+ it('simple trending input produces range bars whose span = range', () => {
16
+ const r = createRangeBars()
17
+ const out = r.transform(
18
+ [
19
+ bar(0, 100, 102, 99, 101),
20
+ bar(1, 101, 105, 100, 104),
21
+ bar(2, 104, 110, 103, 109),
22
+ bar(3, 109, 115, 108, 114),
23
+ ],
24
+ { range: 5 },
25
+ )
26
+ // The closed bars must each have span === 5 (within fp tolerance).
27
+ const closedBars = out.slice(0, -1)
28
+ for (const b of closedBars) {
29
+ expect(b.high - b.low).toBeCloseTo(5, 8)
30
+ }
31
+ })
32
+
33
+ it('sideways input within range emits no closed bars', () => {
34
+ const r = createRangeBars()
35
+ const out = r.transform(
36
+ [bar(0, 100, 101, 99, 100), bar(1, 100, 102, 99, 101), bar(2, 101, 102, 99, 100)],
37
+ { range: 10 },
38
+ )
39
+ // Only the in-progress bar should be present.
40
+ expect(out).toHaveLength(1)
41
+ })
42
+
43
+ it('first bar establishes the first range', () => {
44
+ const r = createRangeBars()
45
+ const out = r.transform([bar(0, 100, 101, 99, 100)], { range: 10 })
46
+ expect(out).toHaveLength(1)
47
+ expect(out[0]!.open).toBe(100)
48
+ })
49
+
50
+ it('input bar exceeding range splits into multiple output bars', () => {
51
+ const r = createRangeBars()
52
+ // A wide input bar spanning 50 units with range 10 should split into ~5 bars.
53
+ const out = r.transform([bar(0, 100, 150, 100, 150)], { range: 10 })
54
+ const closed = out.filter((b) => Math.abs(b.high - b.low - 10) < 1e-6)
55
+ expect(closed.length).toBeGreaterThanOrEqual(4)
56
+ })
57
+
58
+ it('exact-range boundary triggers immediate close', () => {
59
+ const r = createRangeBars()
60
+ // Single bar with H - L == 10 exactly.
61
+ const out = r.transform([bar(0, 100, 110, 100, 110)], { range: 10 })
62
+ // At least one bar must have closed.
63
+ const closed = out.filter((_, i, arr) => i < arr.length - 1)
64
+ expect(closed.length).toBeGreaterThanOrEqual(1)
65
+ })
66
+
67
+ it('volume is aggregated across input bars within one range bar', () => {
68
+ const r = createRangeBars()
69
+ // Three sideways bars accumulate into one open range bar.
70
+ const out = r.transform(
71
+ [bar(0, 100, 101, 99, 100, 50), bar(1, 100, 102, 99, 101, 60), bar(2, 101, 102, 99, 100, 70)],
72
+ { range: 10 },
73
+ )
74
+ // The only present bar (the open one) should hold the summed volume.
75
+ expect(out).toHaveLength(1)
76
+ expect(out[0]!.volume).toBe(50 + 60 + 70)
77
+ })
78
+
79
+ it('split input bar distributes volume proportionally (no spike on first)', () => {
80
+ const r = createRangeBars()
81
+ const out = r.transform([bar(0, 100, 150, 100, 150, 500)], { range: 10 })
82
+ const closed = out.slice(0, -1)
83
+ expect(closed.length).toBeGreaterThan(1)
84
+ // No single closed bar should hold all the volume.
85
+ for (const b of closed) {
86
+ expect(b.volume).toBeLessThan(500)
87
+ }
88
+ // The sum across closed + open should not exceed the input volume.
89
+ const total = out.reduce((s, b) => s + b.volume, 0)
90
+ expect(total).toBeLessThanOrEqual(500 + 1e-6)
91
+ })
92
+
93
+ it('empty input yields empty output', () => {
94
+ const r = createRangeBars()
95
+ const out = r.transform([], { range: 5 })
96
+ expect(out).toEqual([])
97
+ })
98
+
99
+ it('throws on invalid range', () => {
100
+ expect(() => createRangeBars().transform([], { range: 0 })).toThrow()
101
+ expect(() => createRangeBars().transform([], { range: -1 })).toThrow()
102
+ })
103
+
104
+ it('incremental closed bars match batch closed bars on a random series', () => {
105
+ let seed = 7
106
+ const rand = () => {
107
+ seed = (seed * 1103515245 + 12345) & 0x7fffffff
108
+ return seed / 0x7fffffff
109
+ }
110
+ const series: OHLCV[] = []
111
+ let price = 100
112
+ for (let i = 0; i < 30; i++) {
113
+ const drift = (rand() - 0.5) * 4
114
+ const close = price + drift
115
+ const high = Math.max(price, close) + rand() * 1.5
116
+ const low = Math.min(price, close) - rand() * 1.5
117
+ series.push(bar(i, price, high, low, close, Math.floor(rand() * 100)))
118
+ price = close
119
+ }
120
+ const batch = createRangeBars().transform(series, { range: 3 })
121
+ const inc = createRangeBars()
122
+ inc.transform([], { range: 3 })
123
+ const incremental: ReturnType<typeof inc.transform> = []
124
+ for (const b of series) {
125
+ for (const out of inc.appendBar!(b)) incremental.push(out)
126
+ }
127
+ // Batch includes the final in-progress bar. Compare closed prefix.
128
+ const batchClosed = batch.slice(0, incremental.length)
129
+ expect(incremental.length).toBe(batchClosed.length)
130
+ for (let i = 0; i < batchClosed.length; i++) {
131
+ expect(batchClosed[i]!.open).toBeCloseTo(incremental[i]!.open, 8)
132
+ expect(batchClosed[i]!.close).toBeCloseTo(incremental[i]!.close, 8)
133
+ // Span equals range within fp tolerance for every closed bar.
134
+ expect(Math.abs(incremental[i]!.high - incremental[i]!.low - 3)).toBeLessThan(1e-6)
135
+ }
136
+ })
137
+
138
+ it('reset() drops state so the next series starts clean', () => {
139
+ const r = createRangeBars()
140
+ r.transform([bar(0, 100, 110, 100, 110)], { range: 10 })
141
+ r.reset!()
142
+ const out = r.appendBar!(bar(1, 200, 201, 199, 200))
143
+ // First post-reset bar should not have closed anything (range not met).
144
+ expect(out).toEqual([])
145
+ })
146
+ })
@@ -0,0 +1,160 @@
1
+ import { describe, it, expect } from 'vitest'
2
+ import { createRenko } from '../renko'
3
+ import type { OHLCV } from '../types'
4
+
5
+ const bar = (i: number, o: number, h: number, l: number, c: number, v = 100): OHLCV => ({
6
+ timestamp: 1_700_000_000_000 + i * 60_000,
7
+ open: o,
8
+ high: h,
9
+ low: l,
10
+ close: c,
11
+ volume: v,
12
+ })
13
+
14
+ describe('renko', () => {
15
+ it('rising prices emit up-bricks', () => {
16
+ const r = createRenko()
17
+ // Anchor at close 100, then push close up 30 (3 bricks of 10).
18
+ const out = r.transform([bar(0, 100, 100, 100, 100), bar(1, 100, 130, 100, 130)], { brickSize: 10 })
19
+ expect(out).toHaveLength(3)
20
+ for (const b of out) {
21
+ expect(b.meta?.direction).toBe('up')
22
+ expect(b.close).toBeGreaterThan(b.open)
23
+ }
24
+ // Brick closes form a 10-unit ladder.
25
+ expect(out[0]!.close - out[0]!.open).toBeCloseTo(10, 10)
26
+ expect(out[2]!.close).toBeCloseTo(130, 10)
27
+ })
28
+
29
+ it('falling prices emit down-bricks', () => {
30
+ const r = createRenko()
31
+ const out = r.transform([bar(0, 100, 100, 100, 100), bar(1, 100, 100, 70, 70)], { brickSize: 10 })
32
+ expect(out).toHaveLength(3)
33
+ for (const b of out) {
34
+ expect(b.meta?.direction).toBe('down')
35
+ expect(b.close).toBeLessThan(b.open)
36
+ }
37
+ expect(out[2]!.close).toBeCloseTo(70, 10)
38
+ })
39
+
40
+ it('sideways prices within brickSize emit no bricks', () => {
41
+ const r = createRenko()
42
+ const out = r.transform(
43
+ [
44
+ bar(0, 100, 100, 100, 100),
45
+ bar(1, 100, 105, 95, 103),
46
+ bar(2, 103, 106, 98, 102),
47
+ bar(3, 102, 109, 100, 108),
48
+ ],
49
+ { brickSize: 10 },
50
+ )
51
+ expect(out).toHaveLength(0)
52
+ })
53
+
54
+ it('reversal requires 2x brickSize after an up-brick', () => {
55
+ const r = createRenko()
56
+ // Anchor at 100, push up to 110 (one up-brick from 100->110).
57
+ // Then a 1x brickSize move down (to 100) should NOT reverse.
58
+ const out1 = r.transform(
59
+ [bar(0, 100, 100, 100, 100), bar(1, 100, 110, 100, 110), bar(2, 110, 110, 100, 100)],
60
+ { brickSize: 10 },
61
+ )
62
+ // Only the original up-brick should be emitted.
63
+ expect(out1).toHaveLength(1)
64
+ expect(out1[0]!.meta?.direction).toBe('up')
65
+
66
+ // 2x brickSize move down DOES reverse (down to 90 = 110 - 20).
67
+ const r2 = createRenko()
68
+ const out2 = r2.transform(
69
+ [bar(0, 100, 100, 100, 100), bar(1, 100, 110, 100, 110), bar(2, 110, 110, 90, 90)],
70
+ { brickSize: 10 },
71
+ )
72
+ expect(out2.length).toBeGreaterThanOrEqual(2)
73
+ expect(out2[0]!.meta?.direction).toBe('up')
74
+ expect(out2[1]!.meta?.direction).toBe('down')
75
+ })
76
+
77
+ it('ATR mode produces brick size from rolling ATR (no bricks until window fills)', () => {
78
+ const r = createRenko()
79
+ // ATR period 3 — no bricks until the third bar's TR fills the window.
80
+ const series: OHLCV[] = [
81
+ bar(0, 100, 102, 99, 101),
82
+ bar(1, 101, 103, 100, 102),
83
+ bar(2, 102, 104, 101, 103),
84
+ bar(3, 103, 120, 102, 119),
85
+ ]
86
+ const out = r.transform(series, { useATR: { period: 3 } })
87
+ // After bar 3 the window has 4 TR values; brickSize is the rolling mean
88
+ // of the last 3. Should emit at least one up-brick from the +16 move.
89
+ expect(out.length).toBeGreaterThan(0)
90
+ for (const b of out) {
91
+ expect(b.meta?.direction).toBe('up')
92
+ expect(b.meta?.brickSize).toBeGreaterThan(0)
93
+ }
94
+ })
95
+
96
+ it('incremental mode matches batch mode on a random series', () => {
97
+ let seed = 99
98
+ const rand = () => {
99
+ seed = (seed * 1103515245 + 12345) & 0x7fffffff
100
+ return seed / 0x7fffffff
101
+ }
102
+ const series: OHLCV[] = []
103
+ let price = 100
104
+ for (let i = 0; i < 30; i++) {
105
+ const drift = (rand() - 0.5) * 6
106
+ const close = price + drift
107
+ const high = Math.max(price, close) + rand() * 2
108
+ const low = Math.min(price, close) - rand() * 2
109
+ series.push(bar(i, price, high, low, close, Math.floor(rand() * 100)))
110
+ price = close
111
+ }
112
+ const batch = createRenko().transform(series, { brickSize: 3 })
113
+ const inc = createRenko()
114
+ const incremental: ReturnType<typeof inc.transform> = []
115
+ // Prime config via transform on empty array (sets activeConfig)…
116
+ inc.transform([], { brickSize: 3 })
117
+ for (const b of series) {
118
+ for (const out of inc.appendBar!(b)) incremental.push(out)
119
+ }
120
+ expect(incremental.length).toBe(batch.length)
121
+ for (let i = 0; i < batch.length; i++) {
122
+ expect(batch[i]!.open).toBeCloseTo(incremental[i]!.open, 10)
123
+ expect(batch[i]!.close).toBeCloseTo(incremental[i]!.close, 10)
124
+ expect(batch[i]!.meta?.direction).toBe(incremental[i]!.meta?.direction)
125
+ }
126
+ })
127
+
128
+ it('large gap close emits multiple bricks from one input bar', () => {
129
+ const r = createRenko()
130
+ const out = r.transform([bar(0, 100, 100, 100, 100), bar(1, 100, 200, 100, 200)], { brickSize: 10 })
131
+ // 100 -> 200 across one bar should emit 10 up-bricks.
132
+ expect(out).toHaveLength(10)
133
+ // Only the first brick from that source bar carries its volume; the
134
+ // rest are zero (see file header comment).
135
+ expect(out[0]!.volume).toBe(100)
136
+ expect(out[1]!.volume).toBe(0)
137
+ expect(out[9]!.close).toBeCloseTo(200, 10)
138
+ })
139
+
140
+ it('empty input yields empty output', () => {
141
+ const r = createRenko()
142
+ const out = r.transform([], { brickSize: 5 })
143
+ expect(out).toEqual([])
144
+ })
145
+
146
+ it('throws on invalid config', () => {
147
+ expect(() => createRenko().transform([], { brickSize: 0 })).toThrow()
148
+ expect(() => createRenko().transform([], {})).toThrow()
149
+ expect(() => createRenko().transform([], { useATR: { period: 0 } })).toThrow()
150
+ })
151
+
152
+ it('reset() drops state so the next series starts fresh', () => {
153
+ const r = createRenko()
154
+ r.transform([bar(0, 100, 100, 100, 100), bar(1, 100, 150, 100, 150)], { brickSize: 10 })
155
+ r.reset!()
156
+ // After reset the next bar anchors the new series — no bricks yet.
157
+ const out = r.appendBar!(bar(2, 200, 200, 200, 200))
158
+ expect(out).toHaveLength(0)
159
+ })
160
+ })
@@ -0,0 +1,116 @@
1
+ /**
2
+ * Heikin Ashi — "average bar" smoothing of an OHLCV series.
3
+ *
4
+ * Heikin Ashi (平均足) was popularised by Munehisa Homma; the modern formula
5
+ * is the one taught by Dan Valcu. It produces a one-to-one transform — each
6
+ * input bar yields exactly one output bar — but the values are smoothed so
7
+ * trends visually persist through noise.
8
+ *
9
+ * ## Formula
10
+ *
11
+ * HA_close[i] = (O[i] + H[i] + L[i] + C[i]) / 4
12
+ * HA_open[i] = (HA_open[i-1] + HA_close[i-1]) / 2 for i >= 1
13
+ * HA_open[0] = (O[0] + C[0]) / 2 (seed)
14
+ * HA_high[i] = max(H[i], HA_open[i], HA_close[i])
15
+ * HA_low[i] = min(L[i], HA_open[i], HA_close[i])
16
+ * HA_volume[i] = V[i] (unchanged)
17
+ *
18
+ * The seed for `HA_open[0]` is the standard convention used by all major
19
+ * charting platforms (TradingView, MetaTrader). An alternative seed of
20
+ * `O[0]` exists in some older books but produces a slightly different shape
21
+ * for the first bar; we follow the modern convention.
22
+ *
23
+ * ## Trade-offs
24
+ *
25
+ * - Volume is **not** smoothed. Smoothing volume distorts indicators that
26
+ * consume the derived series (OBV, VWAP, CMF), so we keep it raw. This
27
+ * matches TradingView's behaviour.
28
+ * - Output `timestamp` equals input `timestamp` — Heikin Ashi does not
29
+ * re-bucket time.
30
+ *
31
+ * ## Statefulness
32
+ *
33
+ * The transform carries `HA_open[i-1]` and `HA_close[i-1]` between calls so
34
+ * `appendBar` produces the same result as a batch `transform` over the same
35
+ * series. The `reset()` method clears that carry.
36
+ */
37
+
38
+ import type { ChartTypeTransform, OHLCV, TransformedBar } from './types'
39
+
40
+ /** Heikin Ashi has no configuration. The empty type makes the contract explicit. */
41
+ export type HeikinAshiConfig = Record<string, never>
42
+
43
+ interface HAState {
44
+ /** Previous HA_open. */
45
+ prevOpen: number
46
+ /** Previous HA_close. */
47
+ prevClose: number
48
+ /** Index of the next input bar (i.e. count of bars consumed so far). */
49
+ nextIndex: number
50
+ }
51
+
52
+ /**
53
+ * Build a Heikin Ashi transform. The returned object is stateful — `transform`
54
+ * resets state before running, `appendBar` mutates state, `reset` clears it.
55
+ *
56
+ * The factory pattern (rather than a singleton) matches the controller style
57
+ * elsewhere in this package — multiple panes can each hold their own
58
+ * independent transform without crossed state.
59
+ */
60
+ export function createHeikinAshi(): ChartTypeTransform<HeikinAshiConfig> {
61
+ let state: HAState | null = null
62
+
63
+ /**
64
+ * Compute one HA bar. `prev` is `null` for the very first bar in a series,
65
+ * which triggers the seed `HA_open = (O + C) / 2`.
66
+ */
67
+ const computeBar = (
68
+ bar: OHLCV,
69
+ prev: { prevOpen: number; prevClose: number } | null,
70
+ sourceIndex: number,
71
+ ): TransformedBar => {
72
+ const haClose = (bar.open + bar.high + bar.low + bar.close) / 4
73
+ const haOpen = prev === null ? (bar.open + bar.close) / 2 : (prev.prevOpen + prev.prevClose) / 2
74
+ const haHigh = Math.max(bar.high, haOpen, haClose)
75
+ const haLow = Math.min(bar.low, haOpen, haClose)
76
+ return {
77
+ timestamp: bar.timestamp,
78
+ open: haOpen,
79
+ high: haHigh,
80
+ low: haLow,
81
+ close: haClose,
82
+ volume: bar.volume,
83
+ sourceBarIndexStart: sourceIndex,
84
+ sourceBarIndexEnd: sourceIndex,
85
+ }
86
+ }
87
+
88
+ return {
89
+ typeId: 'heikin-ashi',
90
+
91
+ transform(input: ReadonlyArray<OHLCV>): ReadonlyArray<TransformedBar> {
92
+ state = null
93
+ const out: TransformedBar[] = []
94
+ for (let i = 0; i < input.length; i++) {
95
+ const bar = input[i]
96
+ if (!bar) continue
97
+ const ha = computeBar(bar, state === null ? null : { prevOpen: state.prevOpen, prevClose: state.prevClose }, i)
98
+ out.push(ha)
99
+ state = { prevOpen: ha.open, prevClose: ha.close, nextIndex: i + 1 }
100
+ }
101
+ return out
102
+ },
103
+
104
+ appendBar(bar: OHLCV): ReadonlyArray<TransformedBar> {
105
+ const prev = state === null ? null : { prevOpen: state.prevOpen, prevClose: state.prevClose }
106
+ const nextIndex = state === null ? 0 : state.nextIndex
107
+ const ha = computeBar(bar, prev, nextIndex)
108
+ state = { prevOpen: ha.open, prevClose: ha.close, nextIndex: nextIndex + 1 }
109
+ return [ha]
110
+ },
111
+
112
+ reset(): void {
113
+ state = null
114
+ },
115
+ }
116
+ }
@@ -0,0 +1,5 @@
1
+ export type { OHLCV, TransformedBar, ChartTypeTransform } from './types'
2
+ export { createHeikinAshi } from './heikinAshi'
3
+ export { createRenko, type RenkoConfig } from './renko'
4
+ export { createPointAndFigure, type PointAndFigureConfig } from './pointAndFigure'
5
+ export { createRangeBars, type RangeBarsConfig } from './rangeBars'