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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (578) hide show
  1. package/dist/alerts/createAlertController.d.ts +30 -0
  2. package/dist/alerts/createAlertController.d.ts.map +1 -0
  3. package/dist/alerts/createAlertController.js +261 -0
  4. package/dist/alerts/createAlertController.js.map +1 -0
  5. package/dist/alerts/index.d.ts +5 -0
  6. package/dist/alerts/index.d.ts.map +1 -0
  7. package/dist/alerts/index.js +4 -0
  8. package/dist/alerts/index.js.map +1 -0
  9. package/dist/alerts/predicates.d.ts +28 -0
  10. package/dist/alerts/predicates.d.ts.map +1 -0
  11. package/dist/alerts/predicates.js +211 -0
  12. package/dist/alerts/predicates.js.map +1 -0
  13. package/dist/alerts/rollingVolume.d.ts +15 -0
  14. package/dist/alerts/rollingVolume.d.ts.map +1 -0
  15. package/dist/alerts/rollingVolume.js +42 -0
  16. package/dist/alerts/rollingVolume.js.map +1 -0
  17. package/dist/alerts/ruleSchema.d.ts +42 -0
  18. package/dist/alerts/ruleSchema.d.ts.map +1 -0
  19. package/dist/alerts/ruleSchema.js +240 -0
  20. package/dist/alerts/ruleSchema.js.map +1 -0
  21. package/dist/alerts/types.d.ts +169 -0
  22. package/dist/alerts/types.d.ts.map +1 -0
  23. package/dist/alerts/types.js +24 -0
  24. package/dist/alerts/types.js.map +1 -0
  25. package/dist/chartTypes/heikinAshi.d.ts +49 -0
  26. package/dist/chartTypes/heikinAshi.d.ts.map +1 -0
  27. package/dist/chartTypes/heikinAshi.js +94 -0
  28. package/dist/chartTypes/heikinAshi.js.map +1 -0
  29. package/dist/chartTypes/index.d.ts +6 -0
  30. package/dist/chartTypes/index.d.ts.map +1 -0
  31. package/dist/chartTypes/index.js +5 -0
  32. package/dist/chartTypes/index.js.map +1 -0
  33. package/dist/chartTypes/pointAndFigure.d.ts +83 -0
  34. package/dist/chartTypes/pointAndFigure.d.ts.map +1 -0
  35. package/dist/chartTypes/pointAndFigure.js +159 -0
  36. package/dist/chartTypes/pointAndFigure.js.map +1 -0
  37. package/dist/chartTypes/rangeBars.d.ts +61 -0
  38. package/dist/chartTypes/rangeBars.d.ts.map +1 -0
  39. package/dist/chartTypes/rangeBars.js +181 -0
  40. package/dist/chartTypes/rangeBars.js.map +1 -0
  41. package/dist/chartTypes/renko.d.ts +94 -0
  42. package/dist/chartTypes/renko.d.ts.map +1 -0
  43. package/dist/chartTypes/renko.js +207 -0
  44. package/dist/chartTypes/renko.js.map +1 -0
  45. package/dist/chartTypes/types.d.ts +97 -0
  46. package/dist/chartTypes/types.d.ts.map +1 -0
  47. package/dist/chartTypes/types.js +39 -0
  48. package/dist/chartTypes/types.js.map +1 -0
  49. package/dist/components/anchoredVwap/computeAnchoredVwap.d.ts +76 -0
  50. package/dist/components/anchoredVwap/computeAnchoredVwap.d.ts.map +1 -0
  51. package/dist/components/anchoredVwap/computeAnchoredVwap.js +155 -0
  52. package/dist/components/anchoredVwap/computeAnchoredVwap.js.map +1 -0
  53. package/dist/components/anchoredVwap/createAnchoredVwapController.d.ts +28 -0
  54. package/dist/components/anchoredVwap/createAnchoredVwapController.d.ts.map +1 -0
  55. package/dist/components/anchoredVwap/createAnchoredVwapController.js +282 -0
  56. package/dist/components/anchoredVwap/createAnchoredVwapController.js.map +1 -0
  57. package/dist/components/anchoredVwap/index.d.ts +11 -0
  58. package/dist/components/anchoredVwap/index.d.ts.map +1 -0
  59. package/dist/components/anchoredVwap/index.js +10 -0
  60. package/dist/components/anchoredVwap/index.js.map +1 -0
  61. package/dist/components/anchoredVwap/types.d.ts +171 -0
  62. package/dist/components/anchoredVwap/types.d.ts.map +1 -0
  63. package/dist/components/anchoredVwap/types.js +25 -0
  64. package/dist/components/anchoredVwap/types.js.map +1 -0
  65. package/dist/components/crosshairSync/createCrosshairSync.d.ts +94 -0
  66. package/dist/components/crosshairSync/createCrosshairSync.d.ts.map +1 -0
  67. package/dist/components/crosshairSync/createCrosshairSync.js +118 -0
  68. package/dist/components/crosshairSync/createCrosshairSync.js.map +1 -0
  69. package/dist/components/crosshairSync/index.d.ts +2 -0
  70. package/dist/components/crosshairSync/index.d.ts.map +1 -0
  71. package/dist/components/crosshairSync/index.js +2 -0
  72. package/dist/components/crosshairSync/index.js.map +1 -0
  73. package/dist/components/footprint/aggressor.d.ts +89 -0
  74. package/dist/components/footprint/aggressor.d.ts.map +1 -0
  75. package/dist/components/footprint/aggressor.js +106 -0
  76. package/dist/components/footprint/aggressor.js.map +1 -0
  77. package/dist/components/footprint/createFootprintController.d.ts +29 -0
  78. package/dist/components/footprint/createFootprintController.d.ts.map +1 -0
  79. package/dist/components/footprint/createFootprintController.js +264 -0
  80. package/dist/components/footprint/createFootprintController.js.map +1 -0
  81. package/dist/components/footprint/index.d.ts +7 -0
  82. package/dist/components/footprint/index.d.ts.map +1 -0
  83. package/dist/components/footprint/index.js +4 -0
  84. package/dist/components/footprint/index.js.map +1 -0
  85. package/dist/components/footprint/perBarStats.d.ts +63 -0
  86. package/dist/components/footprint/perBarStats.d.ts.map +1 -0
  87. package/dist/components/footprint/perBarStats.js +123 -0
  88. package/dist/components/footprint/perBarStats.js.map +1 -0
  89. package/dist/components/footprint/types.d.ts +197 -0
  90. package/dist/components/footprint/types.d.ts.map +1 -0
  91. package/dist/components/footprint/types.js +23 -0
  92. package/dist/components/footprint/types.js.map +1 -0
  93. package/dist/components/mtfOverlay/alignToBaseIndex.d.ts +45 -0
  94. package/dist/components/mtfOverlay/alignToBaseIndex.d.ts.map +1 -0
  95. package/dist/components/mtfOverlay/alignToBaseIndex.js +92 -0
  96. package/dist/components/mtfOverlay/alignToBaseIndex.js.map +1 -0
  97. package/dist/components/mtfOverlay/createMtfController.d.ts +7 -0
  98. package/dist/components/mtfOverlay/createMtfController.d.ts.map +1 -0
  99. package/dist/components/mtfOverlay/createMtfController.js +134 -0
  100. package/dist/components/mtfOverlay/createMtfController.js.map +1 -0
  101. package/dist/components/mtfOverlay/index.d.ts +19 -0
  102. package/dist/components/mtfOverlay/index.d.ts.map +1 -0
  103. package/dist/components/mtfOverlay/index.js +18 -0
  104. package/dist/components/mtfOverlay/index.js.map +1 -0
  105. package/dist/components/mtfOverlay/resampleBars.d.ts +37 -0
  106. package/dist/components/mtfOverlay/resampleBars.d.ts.map +1 -0
  107. package/dist/components/mtfOverlay/resampleBars.js +93 -0
  108. package/dist/components/mtfOverlay/resampleBars.js.map +1 -0
  109. package/dist/components/mtfOverlay/types.d.ts +132 -0
  110. package/dist/components/mtfOverlay/types.d.ts.map +1 -0
  111. package/dist/components/mtfOverlay/types.js +22 -0
  112. package/dist/components/mtfOverlay/types.js.map +1 -0
  113. package/dist/components/orderBookHeatmap/createHeatmapController.d.ts +21 -0
  114. package/dist/components/orderBookHeatmap/createHeatmapController.d.ts.map +1 -0
  115. package/dist/components/orderBookHeatmap/createHeatmapController.js +234 -0
  116. package/dist/components/orderBookHeatmap/createHeatmapController.js.map +1 -0
  117. package/dist/components/orderBookHeatmap/createOrderBookState.d.ts +18 -0
  118. package/dist/components/orderBookHeatmap/createOrderBookState.d.ts.map +1 -0
  119. package/dist/components/orderBookHeatmap/createOrderBookState.js +102 -0
  120. package/dist/components/orderBookHeatmap/createOrderBookState.js.map +1 -0
  121. package/dist/components/orderBookHeatmap/deltaArchive.d.ts +25 -0
  122. package/dist/components/orderBookHeatmap/deltaArchive.d.ts.map +1 -0
  123. package/dist/components/orderBookHeatmap/deltaArchive.js +106 -0
  124. package/dist/components/orderBookHeatmap/deltaArchive.js.map +1 -0
  125. package/dist/components/orderBookHeatmap/index.d.ts +13 -0
  126. package/dist/components/orderBookHeatmap/index.d.ts.map +1 -0
  127. package/dist/components/orderBookHeatmap/index.js +12 -0
  128. package/dist/components/orderBookHeatmap/index.js.map +1 -0
  129. package/dist/components/orderBookHeatmap/logColorScale.d.ts +20 -0
  130. package/dist/components/orderBookHeatmap/logColorScale.d.ts.map +1 -0
  131. package/dist/components/orderBookHeatmap/logColorScale.js +71 -0
  132. package/dist/components/orderBookHeatmap/logColorScale.js.map +1 -0
  133. package/dist/components/orderBookHeatmap/snapshotRing.d.ts +16 -0
  134. package/dist/components/orderBookHeatmap/snapshotRing.d.ts.map +1 -0
  135. package/dist/components/orderBookHeatmap/snapshotRing.js +61 -0
  136. package/dist/components/orderBookHeatmap/snapshotRing.js.map +1 -0
  137. package/dist/components/orderBookHeatmap/types.d.ts +128 -0
  138. package/dist/components/orderBookHeatmap/types.d.ts.map +1 -0
  139. package/dist/components/orderBookHeatmap/types.js +16 -0
  140. package/dist/components/orderBookHeatmap/types.js.map +1 -0
  141. package/dist/components/volumeProfile/binning.d.ts +54 -0
  142. package/dist/components/volumeProfile/binning.d.ts.map +1 -0
  143. package/dist/components/volumeProfile/binning.js +123 -0
  144. package/dist/components/volumeProfile/binning.js.map +1 -0
  145. package/dist/components/volumeProfile/createVolumeProfileController.d.ts +31 -0
  146. package/dist/components/volumeProfile/createVolumeProfileController.d.ts.map +1 -0
  147. package/dist/components/volumeProfile/createVolumeProfileController.js +179 -0
  148. package/dist/components/volumeProfile/createVolumeProfileController.js.map +1 -0
  149. package/dist/components/volumeProfile/index.d.ts +6 -0
  150. package/dist/components/volumeProfile/index.d.ts.map +1 -0
  151. package/dist/components/volumeProfile/index.js +5 -0
  152. package/dist/components/volumeProfile/index.js.map +1 -0
  153. package/dist/components/volumeProfile/poc.d.ts +35 -0
  154. package/dist/components/volumeProfile/poc.d.ts.map +1 -0
  155. package/dist/components/volumeProfile/poc.js +51 -0
  156. package/dist/components/volumeProfile/poc.js.map +1 -0
  157. package/dist/components/volumeProfile/types.d.ts +138 -0
  158. package/dist/components/volumeProfile/types.d.ts.map +1 -0
  159. package/dist/components/volumeProfile/types.js +19 -0
  160. package/dist/components/volumeProfile/types.js.map +1 -0
  161. package/dist/components/volumeProfile/valueArea.d.ts +58 -0
  162. package/dist/components/volumeProfile/valueArea.d.ts.map +1 -0
  163. package/dist/components/volumeProfile/valueArea.js +172 -0
  164. package/dist/components/volumeProfile/valueArea.js.map +1 -0
  165. package/dist/controllers/createChartController.d.ts.map +1 -1
  166. package/dist/controllers/createChartController.js +22 -11
  167. package/dist/controllers/createChartController.js.map +1 -1
  168. package/dist/controllers/types.d.ts +3 -1
  169. package/dist/controllers/types.d.ts.map +1 -1
  170. package/dist/data-fetchers/baostock.d.ts.map +1 -1
  171. package/dist/data-fetchers/baostock.js +2 -1
  172. package/dist/data-fetchers/baostock.js.map +1 -1
  173. package/dist/data-fetchers/dataBuffer.effects.d.ts.map +1 -1
  174. package/dist/data-fetchers/dataBuffer.effects.js +2 -1
  175. package/dist/data-fetchers/dataBuffer.effects.js.map +1 -1
  176. package/dist/data-fetchers/fetcherDefinitionRegistry.d.ts.map +1 -1
  177. package/dist/data-fetchers/fetcherDefinitionRegistry.js +2 -1
  178. package/dist/data-fetchers/fetcherDefinitionRegistry.js.map +1 -1
  179. package/dist/data-fetchers/gotdx.js +4 -3
  180. package/dist/data-fetchers/gotdx.js.map +1 -1
  181. package/dist/data-fetchers/router.d.ts.map +1 -1
  182. package/dist/data-fetchers/router.js +4 -3
  183. package/dist/data-fetchers/router.js.map +1 -1
  184. package/dist/data-fetchers/tradingview.js +3 -2
  185. package/dist/data-fetchers/tradingview.js.map +1 -1
  186. package/dist/engine/chart.d.ts +13 -0
  187. package/dist/engine/chart.d.ts.map +1 -1
  188. package/dist/engine/chart.js +109 -0
  189. package/dist/engine/chart.js.map +1 -1
  190. package/dist/engine/data/chartDataManager.d.ts +1 -0
  191. package/dist/engine/data/chartDataManager.d.ts.map +1 -1
  192. package/dist/engine/data/chartDataManager.js +27 -4
  193. package/dist/engine/data/chartDataManager.js.map +1 -1
  194. package/dist/engine/drawing/toolConfig.d.ts.map +1 -1
  195. package/dist/engine/drawing/toolConfig.js +2 -1
  196. package/dist/engine/drawing/toolConfig.js.map +1 -1
  197. package/dist/engine/indicators/chartIndicatorManager.d.ts.map +1 -1
  198. package/dist/engine/indicators/chartIndicatorManager.js +2 -1
  199. package/dist/engine/indicators/chartIndicatorManager.js.map +1 -1
  200. package/dist/engine/indicators/indicatorDefinitionRegistry.d.ts.map +1 -1
  201. package/dist/engine/indicators/indicatorDefinitionRegistry.js +2 -1
  202. package/dist/engine/indicators/indicatorDefinitionRegistry.js.map +1 -1
  203. package/dist/engine/indicators/indicatorMetadata.d.ts.map +1 -1
  204. package/dist/engine/indicators/indicatorMetadata.js +2 -1
  205. package/dist/engine/indicators/indicatorMetadata.js.map +1 -1
  206. package/dist/engine/indicators/indicatorRegistry.d.ts.map +1 -1
  207. package/dist/engine/indicators/indicatorRegistry.js +6 -5
  208. package/dist/engine/indicators/indicatorRegistry.js.map +1 -1
  209. package/dist/engine/indicators/registerBuiltins.d.ts.map +1 -1
  210. package/dist/engine/indicators/registerBuiltins.js +2 -1
  211. package/dist/engine/indicators/registerBuiltins.js.map +1 -1
  212. package/dist/engine/indicators/scheduler.d.ts +6 -0
  213. package/dist/engine/indicators/scheduler.d.ts.map +1 -1
  214. package/dist/engine/indicators/scheduler.js +12 -0
  215. package/dist/engine/indicators/scheduler.js.map +1 -1
  216. package/dist/engine/indicators/soa.d.ts.map +1 -1
  217. package/dist/engine/indicators/soa.js +2 -1
  218. package/dist/engine/indicators/soa.js.map +1 -1
  219. package/dist/engine/indicators/stateComposer.d.ts.map +1 -1
  220. package/dist/engine/indicators/stateComposer.js +2 -1
  221. package/dist/engine/indicators/stateComposer.js.map +1 -1
  222. package/dist/engine/subPaneManager.d.ts.map +1 -1
  223. package/dist/engine/subPaneManager.js +2 -1
  224. package/dist/engine/subPaneManager.js.map +1 -1
  225. package/dist/engine/utils/chartZoomController.d.ts +2 -0
  226. package/dist/engine/utils/chartZoomController.d.ts.map +1 -1
  227. package/dist/engine/utils/chartZoomController.js +5 -1
  228. package/dist/engine/utils/chartZoomController.js.map +1 -1
  229. package/dist/errors-help.d.ts +72 -0
  230. package/dist/errors-help.d.ts.map +1 -0
  231. package/dist/errors-help.js +149 -0
  232. package/dist/errors-help.js.map +1 -0
  233. package/dist/errors.d.ts +64 -0
  234. package/dist/errors.d.ts.map +1 -0
  235. package/dist/errors.js +61 -0
  236. package/dist/errors.js.map +1 -0
  237. package/dist/index.d.ts +18 -0
  238. package/dist/index.d.ts.map +1 -1
  239. package/dist/index.js +22 -0
  240. package/dist/index.js.map +1 -1
  241. package/dist/indicators/alma.d.ts +27 -0
  242. package/dist/indicators/alma.d.ts.map +1 -0
  243. package/dist/indicators/alma.js +36 -0
  244. package/dist/indicators/alma.js.map +1 -0
  245. package/dist/indicators/awesomeOscillator.d.ts +19 -0
  246. package/dist/indicators/awesomeOscillator.d.ts.map +1 -0
  247. package/dist/indicators/awesomeOscillator.js +36 -0
  248. package/dist/indicators/awesomeOscillator.js.map +1 -0
  249. package/dist/indicators/dpo.d.ts +17 -0
  250. package/dist/indicators/dpo.d.ts.map +1 -0
  251. package/dist/indicators/dpo.js +24 -0
  252. package/dist/indicators/dpo.js.map +1 -0
  253. package/dist/indicators/fisherTransform.d.ts +26 -0
  254. package/dist/indicators/fisherTransform.d.ts.map +1 -0
  255. package/dist/indicators/fisherTransform.js +44 -0
  256. package/dist/indicators/fisherTransform.js.map +1 -0
  257. package/dist/indicators/frama.d.ts +25 -0
  258. package/dist/indicators/frama.d.ts.map +1 -0
  259. package/dist/indicators/frama.js +61 -0
  260. package/dist/indicators/frama.js.map +1 -0
  261. package/dist/indicators/index.d.ts +24 -0
  262. package/dist/indicators/index.d.ts.map +1 -0
  263. package/dist/indicators/index.js +26 -0
  264. package/dist/indicators/index.js.map +1 -0
  265. package/dist/indicators/lsma.d.ts +21 -0
  266. package/dist/indicators/lsma.d.ts.map +1 -0
  267. package/dist/indicators/lsma.js +37 -0
  268. package/dist/indicators/lsma.js.map +1 -0
  269. package/dist/indicators/schaffTrendCycle.d.ts +24 -0
  270. package/dist/indicators/schaffTrendCycle.d.ts.map +1 -0
  271. package/dist/indicators/schaffTrendCycle.js +70 -0
  272. package/dist/indicators/schaffTrendCycle.js.map +1 -0
  273. package/dist/indicators/stochRSI.d.ts +24 -0
  274. package/dist/indicators/stochRSI.d.ts.map +1 -0
  275. package/dist/indicators/stochRSI.js +86 -0
  276. package/dist/indicators/stochRSI.js.map +1 -0
  277. package/dist/indicators/t3.d.ts +31 -0
  278. package/dist/indicators/t3.d.ts.map +1 -0
  279. package/dist/indicators/t3.js +63 -0
  280. package/dist/indicators/t3.js.map +1 -0
  281. package/dist/indicators/ultimateOscillator.d.ts +26 -0
  282. package/dist/indicators/ultimateOscillator.d.ts.map +1 -0
  283. package/dist/indicators/ultimateOscillator.js +59 -0
  284. package/dist/indicators/ultimateOscillator.js.map +1 -0
  285. package/dist/indicators/vidya.d.ts +24 -0
  286. package/dist/indicators/vidya.d.ts.map +1 -0
  287. package/dist/indicators/vidya.js +54 -0
  288. package/dist/indicators/vidya.js.map +1 -0
  289. package/dist/indicators/zlema.d.ts +16 -0
  290. package/dist/indicators/zlema.d.ts.map +1 -0
  291. package/dist/indicators/zlema.js +26 -0
  292. package/dist/indicators/zlema.js.map +1 -0
  293. package/dist/input/gesture.d.ts +125 -0
  294. package/dist/input/gesture.d.ts.map +1 -0
  295. package/dist/input/gesture.js +249 -0
  296. package/dist/input/gesture.js.map +1 -0
  297. package/dist/input/index.d.ts +9 -0
  298. package/dist/input/index.d.ts.map +1 -0
  299. package/dist/input/index.js +9 -0
  300. package/dist/input/index.js.map +1 -0
  301. package/dist/input/keyboard.d.ts +140 -0
  302. package/dist/input/keyboard.d.ts.map +1 -0
  303. package/dist/input/keyboard.js +260 -0
  304. package/dist/input/keyboard.js.map +1 -0
  305. package/dist/mcp/chartBridge.d.ts +2 -2
  306. package/dist/mcp/chartBridge.d.ts.map +1 -1
  307. package/dist/mcp/chartBridge.js +27 -21
  308. package/dist/mcp/chartBridge.js.map +1 -1
  309. package/dist/plugin/PluginHost.d.ts +0 -3
  310. package/dist/plugin/PluginHost.d.ts.map +1 -1
  311. package/dist/plugin/PluginHost.js +7 -3
  312. package/dist/plugin/PluginHost.js.map +1 -1
  313. package/dist/plugin/PluginRegistry.d.ts +0 -3
  314. package/dist/plugin/PluginRegistry.d.ts.map +1 -1
  315. package/dist/plugin/PluginRegistry.js +5 -1
  316. package/dist/plugin/PluginRegistry.js.map +1 -1
  317. package/dist/render/Renderer.d.ts +116 -0
  318. package/dist/render/Renderer.d.ts.map +1 -0
  319. package/dist/render/Renderer.js +31 -0
  320. package/dist/render/Renderer.js.map +1 -0
  321. package/dist/render/SurfaceBackend.d.ts +83 -0
  322. package/dist/render/SurfaceBackend.d.ts.map +1 -0
  323. package/dist/render/SurfaceBackend.js +27 -0
  324. package/dist/render/SurfaceBackend.js.map +1 -0
  325. package/dist/render/index.d.ts +12 -0
  326. package/dist/render/index.d.ts.map +1 -0
  327. package/dist/render/index.js +11 -0
  328. package/dist/render/index.js.map +1 -0
  329. package/dist/renderer-tier/detectRendererTier.d.ts +57 -0
  330. package/dist/renderer-tier/detectRendererTier.d.ts.map +1 -0
  331. package/dist/renderer-tier/detectRendererTier.js +143 -0
  332. package/dist/renderer-tier/detectRendererTier.js.map +1 -0
  333. package/dist/renderer-tier/index.d.ts +12 -0
  334. package/dist/renderer-tier/index.d.ts.map +1 -0
  335. package/dist/renderer-tier/index.js +12 -0
  336. package/dist/renderer-tier/index.js.map +1 -0
  337. package/dist/renderer-tier/selectBackend.d.ts +106 -0
  338. package/dist/renderer-tier/selectBackend.d.ts.map +1 -0
  339. package/dist/renderer-tier/selectBackend.js +113 -0
  340. package/dist/renderer-tier/selectBackend.js.map +1 -0
  341. package/dist/renderer-tier/types.d.ts +50 -0
  342. package/dist/renderer-tier/types.d.ts.map +1 -0
  343. package/dist/renderer-tier/types.js +24 -0
  344. package/dist/renderer-tier/types.js.map +1 -0
  345. package/dist/replay/createReplayController.d.ts +3 -0
  346. package/dist/replay/createReplayController.d.ts.map +1 -0
  347. package/dist/replay/createReplayController.js +251 -0
  348. package/dist/replay/createReplayController.js.map +1 -0
  349. package/dist/replay/index.d.ts +5 -0
  350. package/dist/replay/index.d.ts.map +1 -0
  351. package/dist/replay/index.js +3 -0
  352. package/dist/replay/index.js.map +1 -0
  353. package/dist/replay/timeline.d.ts +50 -0
  354. package/dist/replay/timeline.d.ts.map +1 -0
  355. package/dist/replay/timeline.js +104 -0
  356. package/dist/replay/timeline.js.map +1 -0
  357. package/dist/replay/types.d.ts +94 -0
  358. package/dist/replay/types.d.ts.map +1 -0
  359. package/dist/replay/types.js +21 -0
  360. package/dist/replay/types.js.map +1 -0
  361. package/dist/scale/anchoredZoom.d.ts +64 -0
  362. package/dist/scale/anchoredZoom.d.ts.map +1 -0
  363. package/dist/scale/anchoredZoom.js +67 -0
  364. package/dist/scale/anchoredZoom.js.map +1 -0
  365. package/dist/scale/createPriceScale.d.ts +49 -0
  366. package/dist/scale/createPriceScale.d.ts.map +1 -0
  367. package/dist/scale/createPriceScale.js +175 -0
  368. package/dist/scale/createPriceScale.js.map +1 -0
  369. package/dist/scale/createTimeScale.d.ts +27 -0
  370. package/dist/scale/createTimeScale.d.ts.map +1 -0
  371. package/dist/scale/createTimeScale.js +139 -0
  372. package/dist/scale/createTimeScale.js.map +1 -0
  373. package/dist/scale/index.d.ts +6 -0
  374. package/dist/scale/index.d.ts.map +1 -0
  375. package/dist/scale/index.js +5 -0
  376. package/dist/scale/index.js.map +1 -0
  377. package/dist/scale/originShift.d.ts +69 -0
  378. package/dist/scale/originShift.d.ts.map +1 -0
  379. package/dist/scale/originShift.js +41 -0
  380. package/dist/scale/originShift.js.map +1 -0
  381. package/dist/scale/types.d.ts +90 -0
  382. package/dist/scale/types.d.ts.map +1 -0
  383. package/dist/scale/types.js +17 -0
  384. package/dist/scale/types.js.map +1 -0
  385. package/dist/scene/createScene.d.ts +22 -0
  386. package/dist/scene/createScene.d.ts.map +1 -0
  387. package/dist/scene/createScene.js +114 -0
  388. package/dist/scene/createScene.js.map +1 -0
  389. package/dist/scene/index.d.ts +13 -0
  390. package/dist/scene/index.d.ts.map +1 -0
  391. package/dist/scene/index.js +11 -0
  392. package/dist/scene/index.js.map +1 -0
  393. package/dist/scene/layerRegistry.d.ts +83 -0
  394. package/dist/scene/layerRegistry.d.ts.map +1 -0
  395. package/dist/scene/layerRegistry.js +43 -0
  396. package/dist/scene/layerRegistry.js.map +1 -0
  397. package/dist/scene/types.d.ts +128 -0
  398. package/dist/scene/types.d.ts.map +1 -0
  399. package/dist/scene/types.js +21 -0
  400. package/dist/scene/types.js.map +1 -0
  401. package/dist/scheduler/createFrameBudget.d.ts +91 -0
  402. package/dist/scheduler/createFrameBudget.d.ts.map +1 -0
  403. package/dist/scheduler/createFrameBudget.js +232 -0
  404. package/dist/scheduler/createFrameBudget.js.map +1 -0
  405. package/dist/scheduler/index.d.ts +2 -0
  406. package/dist/scheduler/index.d.ts.map +1 -0
  407. package/dist/scheduler/index.js +2 -0
  408. package/dist/scheduler/index.js.map +1 -0
  409. package/dist/tokens/themeToCssVars.d.ts.map +1 -1
  410. package/dist/tokens/themeToCssVars.js +2 -28
  411. package/dist/tokens/themeToCssVars.js.map +1 -1
  412. package/dist/version.d.ts +1 -1
  413. package/dist/version.d.ts.map +1 -1
  414. package/dist/version.js +1 -1
  415. package/dist/version.js.map +1 -1
  416. package/package.json +1 -1
  417. package/src/__bench__/indicators.bench.ts +215 -0
  418. package/src/__bench__/orderBookHeatmap.bench.ts +68 -0
  419. package/src/__bench__/scale.bench.ts +80 -0
  420. package/src/__bench__/signal.bench.ts +41 -0
  421. package/src/__bench__/volumeProfile.bench.ts +66 -0
  422. package/src/__tests__/errors-help.test.ts +184 -0
  423. package/src/__tests__/errors.test.ts +187 -0
  424. package/src/alerts/__tests__/controller.test.ts +231 -0
  425. package/src/alerts/__tests__/predicates.test.ts +374 -0
  426. package/src/alerts/__tests__/ruleSchema.test.ts +180 -0
  427. package/src/alerts/createAlertController.ts +312 -0
  428. package/src/alerts/index.ts +18 -0
  429. package/src/alerts/predicates.ts +231 -0
  430. package/src/alerts/rollingVolume.ts +51 -0
  431. package/src/alerts/ruleSchema.ts +278 -0
  432. package/src/alerts/types.ts +177 -0
  433. package/src/chartTypes/__tests__/heikinAshi.test.ts +122 -0
  434. package/src/chartTypes/__tests__/pointAndFigure.test.ts +167 -0
  435. package/src/chartTypes/__tests__/rangeBars.test.ts +146 -0
  436. package/src/chartTypes/__tests__/renko.test.ts +160 -0
  437. package/src/chartTypes/heikinAshi.ts +116 -0
  438. package/src/chartTypes/index.ts +5 -0
  439. package/src/chartTypes/pointAndFigure.ts +278 -0
  440. package/src/chartTypes/rangeBars.ts +303 -0
  441. package/src/chartTypes/renko.ts +311 -0
  442. package/src/chartTypes/types.ts +99 -0
  443. package/src/components/anchoredVwap/__tests__/computeAnchoredVwap.test.ts +331 -0
  444. package/src/components/anchoredVwap/__tests__/controller.test.ts +430 -0
  445. package/src/components/anchoredVwap/computeAnchoredVwap.ts +174 -0
  446. package/src/components/anchoredVwap/createAnchoredVwapController.ts +358 -0
  447. package/src/components/anchoredVwap/index.ts +17 -0
  448. package/src/components/anchoredVwap/types.ts +187 -0
  449. package/src/components/crosshairSync/__tests__/crosshairSync.test.ts +261 -0
  450. package/src/components/crosshairSync/createCrosshairSync.ts +187 -0
  451. package/src/components/crosshairSync/index.ts +5 -0
  452. package/src/components/footprint/__tests__/aggressor.test.ts +127 -0
  453. package/src/components/footprint/__tests__/controller.test.ts +130 -0
  454. package/src/components/footprint/__tests__/perBarStats.test.ts +114 -0
  455. package/src/components/footprint/aggressor.ts +165 -0
  456. package/src/components/footprint/createFootprintController.ts +338 -0
  457. package/src/components/footprint/index.ts +21 -0
  458. package/src/components/footprint/perBarStats.ts +137 -0
  459. package/src/components/footprint/types.ts +232 -0
  460. package/src/components/mtfOverlay/__tests__/alignToBaseIndex.test.ts +103 -0
  461. package/src/components/mtfOverlay/__tests__/controller.test.ts +172 -0
  462. package/src/components/mtfOverlay/__tests__/resampleBars.test.ts +106 -0
  463. package/src/components/mtfOverlay/alignToBaseIndex.ts +108 -0
  464. package/src/components/mtfOverlay/createMtfController.ts +180 -0
  465. package/src/components/mtfOverlay/index.ts +26 -0
  466. package/src/components/mtfOverlay/resampleBars.ts +134 -0
  467. package/src/components/mtfOverlay/types.ts +148 -0
  468. package/src/components/orderBookHeatmap/__tests__/controller.test.ts +237 -0
  469. package/src/components/orderBookHeatmap/__tests__/deltaArchive.test.ts +88 -0
  470. package/src/components/orderBookHeatmap/__tests__/logColorScale.test.ts +69 -0
  471. package/src/components/orderBookHeatmap/__tests__/orderBookState.test.ts +113 -0
  472. package/src/components/orderBookHeatmap/__tests__/snapshotRing.test.ts +53 -0
  473. package/src/components/orderBookHeatmap/computeShader.wgsl.md +130 -0
  474. package/src/components/orderBookHeatmap/createHeatmapController.ts +273 -0
  475. package/src/components/orderBookHeatmap/createOrderBookState.ts +116 -0
  476. package/src/components/orderBookHeatmap/deltaArchive.ts +113 -0
  477. package/src/components/orderBookHeatmap/index.ts +25 -0
  478. package/src/components/orderBookHeatmap/logColorScale.ts +77 -0
  479. package/src/components/orderBookHeatmap/snapshotRing.ts +65 -0
  480. package/src/components/orderBookHeatmap/types.ts +168 -0
  481. package/src/components/volumeProfile/__tests__/binning.test.ts +133 -0
  482. package/src/components/volumeProfile/__tests__/poc.test.ts +44 -0
  483. package/src/components/volumeProfile/__tests__/valueArea.test.ts +177 -0
  484. package/src/components/volumeProfile/binning.ts +133 -0
  485. package/src/components/volumeProfile/createVolumeProfileController.ts +213 -0
  486. package/src/components/volumeProfile/index.ts +12 -0
  487. package/src/components/volumeProfile/poc.ts +53 -0
  488. package/src/components/volumeProfile/types.ts +148 -0
  489. package/src/components/volumeProfile/valueArea.ts +187 -0
  490. package/src/controllers/createChartController.ts +23 -10
  491. package/src/controllers/types.ts +5 -1
  492. package/src/data-fetchers/baostock.ts +2 -1
  493. package/src/data-fetchers/dataBuffer.effects.ts +3 -1
  494. package/src/data-fetchers/fetcherDefinitionRegistry.ts +2 -1
  495. package/src/data-fetchers/gotdx.ts +4 -3
  496. package/src/data-fetchers/router.ts +6 -3
  497. package/src/data-fetchers/tradingview.ts +3 -2
  498. package/src/engine/chart.ts +126 -3
  499. package/src/engine/data/chartDataManager.ts +26 -4
  500. package/src/engine/drawing/toolConfig.ts +2 -1
  501. package/src/engine/indicators/chartIndicatorManager.ts +2 -1
  502. package/src/engine/indicators/indicatorDefinitionRegistry.ts +2 -1
  503. package/src/engine/indicators/indicatorMetadata.ts +2 -1
  504. package/src/engine/indicators/indicatorRegistry.ts +6 -5
  505. package/src/engine/indicators/registerBuiltins.ts +2 -1
  506. package/src/engine/indicators/scheduler.ts +15 -0
  507. package/src/engine/indicators/soa.ts +2 -1
  508. package/src/engine/indicators/stateComposer.ts +2 -1
  509. package/src/engine/subPaneManager.ts +2 -1
  510. package/src/engine/utils/chartZoomController.ts +7 -1
  511. package/src/errors-help.ts +218 -0
  512. package/src/errors.ts +128 -0
  513. package/src/index.ts +37 -0
  514. package/src/indicators/__tests__/maFamily.test.ts +159 -0
  515. package/src/indicators/__tests__/oscillators.test.ts +150 -0
  516. package/src/indicators/alma.ts +61 -0
  517. package/src/indicators/awesomeOscillator.ts +54 -0
  518. package/src/indicators/dpo.ts +37 -0
  519. package/src/indicators/fisherTransform.ts +63 -0
  520. package/src/indicators/frama.ts +87 -0
  521. package/src/indicators/index.ts +39 -0
  522. package/src/indicators/lsma.ts +58 -0
  523. package/src/indicators/schaffTrendCycle.ts +92 -0
  524. package/src/indicators/stochRSI.ts +108 -0
  525. package/src/indicators/t3.ts +96 -0
  526. package/src/indicators/ultimateOscillator.ts +83 -0
  527. package/src/indicators/vidya.ts +80 -0
  528. package/src/indicators/zlema.ts +41 -0
  529. package/src/input/__tests__/gesture.test.ts +271 -0
  530. package/src/input/__tests__/keyboard.test.ts +317 -0
  531. package/src/input/gesture.ts +357 -0
  532. package/src/input/index.ts +26 -0
  533. package/src/input/keyboard.ts +373 -0
  534. package/src/mcp/chartBridge.ts +98 -72
  535. package/src/plugin/PluginHost.ts +4 -3
  536. package/src/plugin/PluginRegistry.ts +2 -1
  537. package/src/render/Renderer.ts +127 -0
  538. package/src/render/SurfaceBackend.ts +94 -0
  539. package/src/render/__tests__/contract.test.ts +176 -0
  540. package/src/render/index.ts +27 -0
  541. package/src/renderer-tier/__tests__/detectRendererTier.test.ts +180 -0
  542. package/src/renderer-tier/__tests__/selectBackend.test.ts +253 -0
  543. package/src/renderer-tier/detectRendererTier.ts +168 -0
  544. package/src/renderer-tier/index.ts +30 -0
  545. package/src/renderer-tier/selectBackend.ts +201 -0
  546. package/src/renderer-tier/types.ts +59 -0
  547. package/src/replay/__tests__/controller.test.ts +309 -0
  548. package/src/replay/__tests__/timeline.test.ts +99 -0
  549. package/src/replay/createReplayController.ts +302 -0
  550. package/src/replay/index.ts +15 -0
  551. package/src/replay/timeline.ts +106 -0
  552. package/src/replay/types.ts +107 -0
  553. package/src/scale/__tests__/anchoredZoom.test.ts +125 -0
  554. package/src/scale/__tests__/originShift.test.ts +97 -0
  555. package/src/scale/__tests__/priceScale.test.ts +219 -0
  556. package/src/scale/__tests__/timeScale.test.ts +119 -0
  557. package/src/scale/anchoredZoom.ts +104 -0
  558. package/src/scale/createPriceScale.ts +226 -0
  559. package/src/scale/createTimeScale.ts +150 -0
  560. package/src/scale/index.ts +9 -0
  561. package/src/scale/originShift.ts +111 -0
  562. package/src/scale/types.ts +100 -0
  563. package/src/scene/__tests__/layerRegistry.test.ts +207 -0
  564. package/src/scene/__tests__/scene.test.ts +411 -0
  565. package/src/scene/createScene.ts +117 -0
  566. package/src/scene/index.ts +29 -0
  567. package/src/scene/layerRegistry.ts +117 -0
  568. package/src/scene/types.ts +143 -0
  569. package/src/scheduler/__tests__/createFrameBudget.test.ts +315 -0
  570. package/src/scheduler/createFrameBudget.ts +316 -0
  571. package/src/scheduler/index.ts +7 -0
  572. package/src/tokens/themeToCssVars.ts +3 -1
  573. package/src/version.ts +1 -1
  574. package/dist/data-fetchers/gotdx/gotdx.d.ts +0 -7
  575. package/dist/data-fetchers/gotdx/gotdx.d.ts.map +0 -1
  576. package/dist/data-fetchers/gotdx/gotdx.js +0 -7
  577. package/dist/data-fetchers/gotdx/gotdx.js.map +0 -1
  578. package/src/data-fetchers/gotdx/gotdx.ts +0 -6
@@ -0,0 +1,108 @@
1
+ import { KLineChartError } from '../errors'
2
+ /**
3
+ * Stochastic RSI (Chande & Kroll, 1994).
4
+ *
5
+ * Two-step composition:
6
+ * 1. RSI(period) over close-only.
7
+ * 2. Stochastic over the RSI series:
8
+ * k[i] = 100 * (RSI[i] - min(RSI, stochPeriod))
9
+ * / (max(RSI, stochPeriod) - min(RSI, stochPeriod))
10
+ * 3. Smooth k by SMA(smoothK) → %K; smooth %K by SMA(smoothD) → %D.
11
+ *
12
+ * Output: parallel `Float64Array` pair { k, d }, both length === input.
13
+ * NaN leading. Returns 0..100.
14
+ */
15
+
16
+ export interface StochRsiOptions {
17
+ rsiPeriod: number
18
+ stochPeriod: number
19
+ smoothK?: number
20
+ smoothD?: number
21
+ }
22
+
23
+ export function computeStochRSI(
24
+ prices: ReadonlyArray<number>,
25
+ opts: StochRsiOptions,
26
+ ): { k: Float64Array; d: Float64Array } {
27
+ const { rsiPeriod, stochPeriod } = opts
28
+ const smoothK = opts.smoothK ?? 3
29
+ const smoothD = opts.smoothD ?? 3
30
+ if (rsiPeriod < 2 || stochPeriod < 2 || smoothK < 1 || smoothD < 1) {
31
+ throw new KLineChartError('INDICATOR_INVALID_PARAM', 'computeStochRSI: invalid period args')
32
+ }
33
+
34
+ const n = prices.length
35
+ const rsi = computeRsiSeries(prices, rsiPeriod)
36
+
37
+ const rawK = new Float64Array(n)
38
+ rawK.fill(Number.NaN)
39
+ for (let i = rsiPeriod + stochPeriod - 1; i < n; i++) {
40
+ let lo = Infinity
41
+ let hi = -Infinity
42
+ for (let j = i - stochPeriod + 1; j <= i; j++) {
43
+ const v = rsi[j] as number
44
+ if (Number.isNaN(v)) continue
45
+ if (v < lo) lo = v
46
+ if (v > hi) hi = v
47
+ }
48
+ const denom = hi - lo
49
+ rawK[i] = denom === 0 ? 50 : (100 * ((rsi[i] as number) - lo)) / denom
50
+ }
51
+
52
+ const k = smaSeries(rawK, smoothK)
53
+ const d = smaSeries(k, smoothD)
54
+ return { k, d }
55
+ }
56
+
57
+ function computeRsiSeries(prices: ReadonlyArray<number>, period: number): Float64Array {
58
+ const n = prices.length
59
+ const out = new Float64Array(n)
60
+ out.fill(Number.NaN)
61
+ if (n < period + 1) return out
62
+
63
+ let gainSum = 0
64
+ let lossSum = 0
65
+ for (let i = 1; i <= period; i++) {
66
+ const diff = (prices[i] as number) - (prices[i - 1] as number)
67
+ if (diff > 0) gainSum += diff
68
+ else lossSum += -diff
69
+ }
70
+ let avgGain = gainSum / period
71
+ let avgLoss = lossSum / period
72
+ out[period] = avgLoss === 0 ? 100 : 100 - 100 / (1 + avgGain / avgLoss)
73
+
74
+ for (let i = period + 1; i < n; i++) {
75
+ const diff = (prices[i] as number) - (prices[i - 1] as number)
76
+ const g = diff > 0 ? diff : 0
77
+ const l = diff < 0 ? -diff : 0
78
+ avgGain = (avgGain * (period - 1) + g) / period
79
+ avgLoss = (avgLoss * (period - 1) + l) / period
80
+ out[i] = avgLoss === 0 ? 100 : 100 - 100 / (1 + avgGain / avgLoss)
81
+ }
82
+ return out
83
+ }
84
+
85
+ function smaSeries(input: Float64Array, period: number): Float64Array {
86
+ const n = input.length
87
+ const out = new Float64Array(n)
88
+ out.fill(Number.NaN)
89
+ let acc = 0
90
+ let count = 0
91
+ let start = 0
92
+ for (let i = 0; i < n; i++) {
93
+ const v = input[i] as number
94
+ if (!Number.isNaN(v)) {
95
+ acc += v
96
+ count++
97
+ }
98
+ if (count >= period) {
99
+ out[i] = acc / period
100
+ // Slide window: subtract the value leaving the window (period back).
101
+ const left = input[start + count - period] as number
102
+ if (!Number.isNaN(left)) acc -= left
103
+ else count-- // adjust if a NaN was at the left edge
104
+ start = i - period + 2
105
+ }
106
+ }
107
+ return out
108
+ }
@@ -0,0 +1,96 @@
1
+ import { KLineChartError } from '../errors'
2
+ /**
3
+ * T3 — Tim Tillson's smoothed-EMA cascade (1998).
4
+ *
5
+ * Public reference: T. Tillson, "Better Moving Averages",
6
+ * Technical Analysis of Stocks & Commodities, January 1998.
7
+ *
8
+ * Algorithm:
9
+ * 1. EMA1 = EMA(price, period)
10
+ * 2. EMA2 = EMA(EMA1, period)
11
+ * 3. EMA3 = EMA(EMA2, period)
12
+ * 4. EMA4 = EMA(EMA3, period)
13
+ * 5. EMA5 = EMA(EMA4, period)
14
+ * 6. EMA6 = EMA(EMA5, period)
15
+ * T3 = c1*EMA6 + c2*EMA5 + c3*EMA4 + c4*EMA3
16
+ * where
17
+ * a = volume factor in [0, 1], default 0.7
18
+ * c1 = -a^3
19
+ * c2 = 3*a^2 + 3*a^3
20
+ * c3 = -6*a^2 - 3*a - 3*a^3
21
+ * c4 = 1 + 3*a + a^3 + 3*a^2
22
+ *
23
+ * Output length === input length. The first non-NaN value emerges once the
24
+ * EMA cascade has primed (we seed each EMA on its first input).
25
+ */
26
+
27
+ export interface T3Options {
28
+ period: number
29
+ /** Volume factor in [0, 1]. Default 0.7. Lower = smoother. */
30
+ volumeFactor?: number
31
+ }
32
+
33
+ function emaSeries(input: Float64Array, period: number): Float64Array {
34
+ const out = new Float64Array(input.length)
35
+ const k = 2 / (period + 1)
36
+ let prev = Number.NaN
37
+ for (let i = 0; i < input.length; i++) {
38
+ const v = input[i] as number
39
+ if (Number.isNaN(v)) {
40
+ out[i] = Number.NaN
41
+ continue
42
+ }
43
+ if (Number.isNaN(prev)) {
44
+ prev = v
45
+ } else {
46
+ prev = k * v + (1 - k) * prev
47
+ }
48
+ out[i] = prev
49
+ }
50
+ return out
51
+ }
52
+
53
+ export function computeT3(prices: ReadonlyArray<number>, opts: T3Options): Float64Array {
54
+ const { period } = opts
55
+ const a = opts.volumeFactor ?? 0.7
56
+ if (period < 2 || !Number.isFinite(period)) throw new KLineChartError('INDICATOR_INVALID_PARAM', 'computeT3: period must be >= 2')
57
+ if (a < 0 || a > 1 || !Number.isFinite(a)) {
58
+ throw new KLineChartError('INDICATOR_INVALID_PARAM', 'computeT3: volumeFactor must be in [0, 1]')
59
+ }
60
+
61
+ const src = new Float64Array(prices.length)
62
+ for (let i = 0; i < prices.length; i++) src[i] = prices[i] as number
63
+
64
+ const e1 = emaSeries(src, period)
65
+ const e2 = emaSeries(e1, period)
66
+ const e3 = emaSeries(e2, period)
67
+ const e4 = emaSeries(e3, period)
68
+ const e5 = emaSeries(e4, period)
69
+ const e6 = emaSeries(e5, period)
70
+
71
+ const a2 = a * a
72
+ const a3 = a2 * a
73
+ const c1 = -a3
74
+ const c2 = 3 * a2 + 3 * a3
75
+ const c3 = -6 * a2 - 3 * a - 3 * a3
76
+ const c4 = 1 + 3 * a + a3 + 3 * a2
77
+
78
+ const out = new Float64Array(prices.length)
79
+ for (let i = 0; i < prices.length; i++) {
80
+ const v6 = e6[i] as number
81
+ const v5 = e5[i] as number
82
+ const v4 = e4[i] as number
83
+ const v3 = e3[i] as number
84
+ if (
85
+ Number.isNaN(v6) ||
86
+ Number.isNaN(v5) ||
87
+ Number.isNaN(v4) ||
88
+ Number.isNaN(v3)
89
+ ) {
90
+ out[i] = Number.NaN
91
+ } else {
92
+ out[i] = c1 * v6 + c2 * v5 + c3 * v4 + c4 * v3
93
+ }
94
+ }
95
+ return out
96
+ }
@@ -0,0 +1,83 @@
1
+ import { KLineChartError } from '../errors'
2
+ /**
3
+ * Ultimate Oscillator — Larry Williams (1976).
4
+ *
5
+ * Weighted multi-period buying-pressure / true-range oscillator.
6
+ *
7
+ * prevClose[i] = close[i-1]
8
+ * BP[i] = close[i] - min(low[i], prevClose[i])
9
+ * TR[i] = max(high[i], prevClose[i]) - min(low[i], prevClose[i])
10
+ * avg(N) = sum(BP, N) / sum(TR, N)
11
+ * UO[i] = 100 * (4*avg(p1) + 2*avg(p2) + avg(p3)) / 7
12
+ *
13
+ * Defaults: p1=7, p2=14, p3=28.
14
+ *
15
+ * Output: `Float64Array` length === input. NaN until index >= max(p1,p2,p3).
16
+ */
17
+
18
+ export interface UltimateOscillatorOptions {
19
+ p1?: number
20
+ p2?: number
21
+ p3?: number
22
+ }
23
+
24
+ export function computeUltimateOscillator(
25
+ bars: ReadonlyArray<{ high: number; low: number; close: number }>,
26
+ opts: UltimateOscillatorOptions = {},
27
+ ): Float64Array {
28
+ const p1 = opts.p1 ?? 7
29
+ const p2 = opts.p2 ?? 14
30
+ const p3 = opts.p3 ?? 28
31
+ if (p1 < 1 || p2 < 1 || p3 < 1) {
32
+ throw new KLineChartError('INDICATOR_INVALID_PARAM', 'computeUltimateOscillator: all periods must be >= 1')
33
+ }
34
+ const n = bars.length
35
+ const bp = new Float64Array(n)
36
+ const tr = new Float64Array(n)
37
+ for (let i = 0; i < n; i++) {
38
+ const b = bars[i] as { high: number; low: number; close: number }
39
+ if (i === 0) {
40
+ bp[i] = 0
41
+ tr[i] = b.high - b.low
42
+ continue
43
+ }
44
+ const pc = (bars[i - 1] as { close: number }).close
45
+ const minLow = Math.min(b.low, pc)
46
+ bp[i] = b.close - minLow
47
+ tr[i] = Math.max(b.high, pc) - minLow
48
+ }
49
+ const r1 = rollingRatio(bp, tr, p1)
50
+ const r2 = rollingRatio(bp, tr, p2)
51
+ const r3 = rollingRatio(bp, tr, p3)
52
+ const out = new Float64Array(n)
53
+ const maxP = Math.max(p1, p2, p3)
54
+ for (let i = 0; i < n; i++) {
55
+ if (i < maxP) {
56
+ out[i] = Number.NaN
57
+ continue
58
+ }
59
+ out[i] = (100 * (4 * (r1[i] as number) + 2 * (r2[i] as number) + (r3[i] as number))) / 7
60
+ }
61
+ return out
62
+ }
63
+
64
+ function rollingRatio(num: Float64Array, den: Float64Array, period: number): Float64Array {
65
+ const n = num.length
66
+ const out = new Float64Array(n)
67
+ let sNum = 0
68
+ let sDen = 0
69
+ for (let i = 0; i < n; i++) {
70
+ sNum += num[i] as number
71
+ sDen += den[i] as number
72
+ if (i >= period) {
73
+ sNum -= num[i - period] as number
74
+ sDen -= den[i - period] as number
75
+ }
76
+ if (i < period - 1 || sDen === 0) {
77
+ out[i] = Number.NaN
78
+ } else {
79
+ out[i] = sNum / sDen
80
+ }
81
+ }
82
+ return out
83
+ }
@@ -0,0 +1,80 @@
1
+ import { KLineChartError } from '../errors'
2
+ /**
3
+ * VIDYA — Variable Index Dynamic Average (Tushar Chande).
4
+ *
5
+ * CMO-adapted EMA: the smoothing constant is scaled by the absolute value
6
+ * of the Chande Momentum Oscillator, so VIDYA accelerates in trending
7
+ * markets and slows in chop.
8
+ *
9
+ * gain[i] = max(price[i] - price[i-1], 0)
10
+ * loss[i] = max(price[i-1] - price[i], 0)
11
+ * CMO(t) = 100 * (sum(gain, t-cmoPeriod+1..t) - sum(loss, ...))
12
+ * / (sum(gain) + sum(loss)) (NaN-guarded)
13
+ * alpha = (2 / (period + 1)) * |CMO(t) / 100|
14
+ * VIDYA[i] = alpha * price[i] + (1 - alpha) * VIDYA[i-1]
15
+ *
16
+ * Output length === input length. Indices < cmoPeriod are NaN. VIDYA seeds
17
+ * on the first valid CMO sample.
18
+ */
19
+
20
+ export interface VidyaOptions {
21
+ period: number
22
+ /** Window for the CMO numerator/denominator. Default 9. */
23
+ cmoPeriod?: number
24
+ }
25
+
26
+ export function computeVIDYA(prices: ReadonlyArray<number>, opts: VidyaOptions): Float64Array {
27
+ const { period } = opts
28
+ const cmoPeriod = opts.cmoPeriod ?? 9
29
+ if (period < 2 || !Number.isFinite(period)) throw new KLineChartError('INDICATOR_INVALID_PARAM', 'computeVIDYA: period must be >= 2')
30
+ if (cmoPeriod < 1 || !Number.isFinite(cmoPeriod)) {
31
+ throw new KLineChartError('INDICATOR_INVALID_PARAM', 'computeVIDYA: cmoPeriod must be >= 1')
32
+ }
33
+
34
+ const n = prices.length
35
+ const out = new Float64Array(n)
36
+ const baseAlpha = 2 / (period + 1)
37
+
38
+ // Rolling sums of gain / loss across the cmoPeriod window of diffs.
39
+ let gainSum = 0
40
+ let lossSum = 0
41
+ let prev = Number.NaN
42
+
43
+ for (let i = 0; i < n; i++) {
44
+ if (i === 0) {
45
+ out[i] = Number.NaN
46
+ continue
47
+ }
48
+ const cur = prices[i] as number
49
+ const previous = prices[i - 1] as number
50
+ const diff = cur - previous
51
+ const gain = diff > 0 ? diff : 0
52
+ const loss = diff < 0 ? -diff : 0
53
+ gainSum += gain
54
+ lossSum += loss
55
+
56
+ // Drop the diff that just slid out of the window.
57
+ if (i > cmoPeriod) {
58
+ const drop = (prices[i - cmoPeriod] as number) - (prices[i - cmoPeriod - 1] as number)
59
+ if (drop > 0) gainSum -= drop
60
+ else if (drop < 0) lossSum += drop // (-drop is the abs)
61
+ }
62
+
63
+ if (i < cmoPeriod) {
64
+ out[i] = Number.NaN
65
+ continue
66
+ }
67
+
68
+ const denom = gainSum + lossSum
69
+ const cmoAbs = denom === 0 ? 0 : Math.abs((gainSum - lossSum) / denom)
70
+ const alpha = baseAlpha * cmoAbs
71
+
72
+ if (Number.isNaN(prev)) {
73
+ prev = cur
74
+ } else {
75
+ prev = alpha * cur + (1 - alpha) * prev
76
+ }
77
+ out[i] = prev
78
+ }
79
+ return out
80
+ }
@@ -0,0 +1,41 @@
1
+ import { KLineChartError } from '../errors'
2
+ /**
3
+ * ZLEMA — Zero-Lag Exponential Moving Average (Ehlers).
4
+ *
5
+ * Removes EMA lag by feeding the EMA a "momentum-adjusted" series:
6
+ * lag = floor((period - 1) / 2)
7
+ * adj[i] = price[i] + (price[i] - price[i - lag])
8
+ * zlema = EMA(adj, period)
9
+ *
10
+ * Output length === input length. Indices < lag are NaN (no adjustment
11
+ * available); the EMA seeds on the first valid sample.
12
+ */
13
+
14
+ export interface ZlemaOptions {
15
+ period: number
16
+ }
17
+
18
+ export function computeZLEMA(prices: ReadonlyArray<number>, opts: ZlemaOptions): Float64Array {
19
+ const { period } = opts
20
+ if (period < 2 || !Number.isFinite(period)) throw new KLineChartError('INDICATOR_INVALID_PARAM', 'computeZLEMA: period must be >= 2')
21
+
22
+ const out = new Float64Array(prices.length)
23
+ const lag = Math.floor((period - 1) / 2)
24
+ const k = 2 / (period + 1)
25
+
26
+ let ema = Number.NaN
27
+ for (let i = 0; i < prices.length; i++) {
28
+ if (i < lag) {
29
+ out[i] = Number.NaN
30
+ continue
31
+ }
32
+ const adj = 2 * (prices[i] as number) - (prices[i - lag] as number)
33
+ if (Number.isNaN(ema)) {
34
+ ema = adj
35
+ } else {
36
+ ema = k * adj + (1 - k) * ema
37
+ }
38
+ out[i] = ema
39
+ }
40
+ return out
41
+ }
@@ -0,0 +1,271 @@
1
+ /**
2
+ * Tests for `createGestureRecognizer`.
3
+ *
4
+ * Coverage:
5
+ * 1. State machine — idle / tracking / pan / pinch transitions.
6
+ * 2. Tap — single pointer down/up within deadzone.
7
+ * 3. Pan — primary pointer escapes deadzone, emits panStart + pan + panEnd.
8
+ * 4. Swipe — pan with fast release crosses velocity threshold → swipe.
9
+ * 5. Pinch — two pointers down, scale computed against initial distance.
10
+ * 6. Pinch → tracking demotion when one of the two pointers releases.
11
+ * 7. cancel() resets without emit.
12
+ * 8. Config validation — negative deadzone / velocity rejected.
13
+ * 9. dispose() makes everything a no-op.
14
+ */
15
+
16
+ import { describe, it, expect } from 'vitest'
17
+
18
+ import { createGestureRecognizer, type PointerEventLike, type GestureEvent } from '..'
19
+ import { isKLineChartError } from '../../errors'
20
+
21
+ function pt(id: number, x: number, y: number, ts: number): PointerEventLike {
22
+ return { pointerId: id, x, y, timestamp: ts }
23
+ }
24
+
25
+ /**
26
+ * Drive the recognizer and collect every emitted event in order.
27
+ */
28
+ function drive(
29
+ g: ReturnType<typeof createGestureRecognizer>,
30
+ steps: Array<['down' | 'move' | 'up', PointerEventLike]>,
31
+ ): GestureEvent[] {
32
+ const out: GestureEvent[] = []
33
+ g.events.subscribe(() => {
34
+ const e = g.events.peek()
35
+ if (e !== null) out.push(e)
36
+ })
37
+ for (const [op, e] of steps) {
38
+ if (op === 'down') g.onPointerDown(e)
39
+ else if (op === 'move') g.onPointerMove(e)
40
+ else g.onPointerUp(e)
41
+ }
42
+ return out
43
+ }
44
+
45
+ // ---------------------------------------------------------------------------
46
+ // Tap
47
+ // ---------------------------------------------------------------------------
48
+
49
+ describe('tap', () => {
50
+ it('down + up within deadzone emits a tap', () => {
51
+ const g = createGestureRecognizer({ panDeadzone: 6 })
52
+ const events = drive(g, [
53
+ ['down', pt(1, 100, 100, 0)],
54
+ ['up', pt(1, 102, 101, 50)],
55
+ ])
56
+ expect(events.map((e) => e.type)).toEqual(['tap'])
57
+ expect(g.state.peek()).toBe('idle')
58
+ })
59
+
60
+ it('down + up at exact same point emits a tap (no movement at all)', () => {
61
+ const g = createGestureRecognizer()
62
+ const events = drive(g, [
63
+ ['down', pt(1, 50, 50, 0)],
64
+ ['up', pt(1, 50, 50, 100)],
65
+ ])
66
+ expect(events.map((e) => e.type)).toEqual(['tap'])
67
+ })
68
+ })
69
+
70
+ // ---------------------------------------------------------------------------
71
+ // Pan
72
+ // ---------------------------------------------------------------------------
73
+
74
+ describe('pan', () => {
75
+ it('promotes to pan when movement escapes deadzone', () => {
76
+ const g = createGestureRecognizer({ panDeadzone: 6, swipeMinVelocity: 999 })
77
+ const events = drive(g, [
78
+ ['down', pt(1, 100, 100, 0)],
79
+ ['move', pt(1, 102, 102, 10)],
80
+ ['move', pt(1, 120, 100, 20)], // 20px from start → past deadzone
81
+ ['move', pt(1, 140, 100, 30)],
82
+ ['up', pt(1, 140, 100, 1000)], // slow release → panEnd, not swipe
83
+ ])
84
+ const types = events.map((e) => e.type)
85
+ expect(types).toContain('panStart')
86
+ expect(types.filter((t) => t === 'pan').length).toBeGreaterThanOrEqual(1)
87
+ expect(types[types.length - 1]).toBe('panEnd')
88
+ })
89
+
90
+ it('panStart fires exactly once per gesture', () => {
91
+ const g = createGestureRecognizer({ panDeadzone: 6, swipeMinVelocity: 999 })
92
+ const events = drive(g, [
93
+ ['down', pt(1, 0, 0, 0)],
94
+ ['move', pt(1, 20, 0, 10)],
95
+ ['move', pt(1, 40, 0, 20)],
96
+ ['move', pt(1, 60, 0, 30)],
97
+ ['up', pt(1, 60, 0, 1000)],
98
+ ])
99
+ expect(events.filter((e) => e.type === 'panStart').length).toBe(1)
100
+ })
101
+
102
+ it('pan events carry running dx/dy', () => {
103
+ const g = createGestureRecognizer({ panDeadzone: 0, swipeMinVelocity: 999 })
104
+ const events = drive(g, [
105
+ ['down', pt(1, 0, 0, 0)],
106
+ ['move', pt(1, 10, 5, 10)],
107
+ ['move', pt(1, 30, 12, 20)],
108
+ ['up', pt(1, 30, 12, 1000)],
109
+ ])
110
+ const pans = events.filter((e): e is Extract<GestureEvent, { type: 'pan' }> => e.type === 'pan')
111
+ // First pan: dx = 10 - 0 = 10, dy = 5 - 0 = 5
112
+ expect(pans[0]?.dx).toBe(10)
113
+ expect(pans[0]?.dy).toBe(5)
114
+ // Second pan: dx = 30 - 10 = 20, dy = 12 - 5 = 7
115
+ expect(pans[1]?.dx).toBe(20)
116
+ expect(pans[1]?.dy).toBe(7)
117
+ })
118
+ })
119
+
120
+ // ---------------------------------------------------------------------------
121
+ // Swipe
122
+ // ---------------------------------------------------------------------------
123
+
124
+ describe('swipe', () => {
125
+ it('fast release after pan emits swipe instead of panEnd', () => {
126
+ const g = createGestureRecognizer({
127
+ panDeadzone: 6,
128
+ swipeMinVelocity: 0.5,
129
+ swipeVelocityWindowMs: 100,
130
+ })
131
+ // 100px in 50ms → 2 px/ms, comfortably above 0.5
132
+ const events = drive(g, [
133
+ ['down', pt(1, 0, 0, 0)],
134
+ ['move', pt(1, 20, 0, 10)],
135
+ ['move', pt(1, 60, 0, 30)],
136
+ ['move', pt(1, 100, 0, 50)],
137
+ ['up', pt(1, 100, 0, 50)],
138
+ ])
139
+ const last = events[events.length - 1]
140
+ expect(last?.type).toBe('swipe')
141
+ const swipe = last as Extract<GestureEvent, { type: 'swipe' }>
142
+ expect(swipe.vx).toBeGreaterThan(0.5)
143
+ })
144
+
145
+ it('slow release after pan emits panEnd, not swipe', () => {
146
+ const g = createGestureRecognizer({
147
+ panDeadzone: 6,
148
+ swipeMinVelocity: 0.5,
149
+ swipeVelocityWindowMs: 100,
150
+ })
151
+ // 20px in 200ms → 0.1 px/ms, below threshold
152
+ const events = drive(g, [
153
+ ['down', pt(1, 0, 0, 0)],
154
+ ['move', pt(1, 10, 0, 100)],
155
+ ['move', pt(1, 20, 0, 200)],
156
+ ['up', pt(1, 20, 0, 200)],
157
+ ])
158
+ expect(events[events.length - 1]?.type).toBe('panEnd')
159
+ })
160
+ })
161
+
162
+ // ---------------------------------------------------------------------------
163
+ // Pinch
164
+ // ---------------------------------------------------------------------------
165
+
166
+ describe('pinch', () => {
167
+ it('second pointer down → pinchStart', () => {
168
+ const g = createGestureRecognizer()
169
+ const events = drive(g, [
170
+ ['down', pt(1, 0, 0, 0)],
171
+ ['down', pt(2, 100, 0, 10)],
172
+ ])
173
+ const start = events.find((e) => e.type === 'pinchStart') as
174
+ | Extract<GestureEvent, { type: 'pinchStart' }>
175
+ | undefined
176
+ expect(start).toBeDefined()
177
+ expect(start?.cx).toBe(50)
178
+ expect(start?.distance).toBe(100)
179
+ expect(g.state.peek()).toBe('pinch')
180
+ })
181
+
182
+ it('scale doubles when distance doubles', () => {
183
+ const g = createGestureRecognizer()
184
+ const events = drive(g, [
185
+ ['down', pt(1, 0, 0, 0)],
186
+ ['down', pt(2, 100, 0, 10)],
187
+ ['move', pt(2, 200, 0, 20)], // distance 200, started at 100 → scale 2
188
+ ])
189
+ const pinches = events.filter(
190
+ (e): e is Extract<GestureEvent, { type: 'pinch' }> => e.type === 'pinch',
191
+ )
192
+ expect(pinches[pinches.length - 1]?.scale).toBeCloseTo(2, 10)
193
+ })
194
+
195
+ it('lifting one finger emits pinchEnd and demotes to tracking', () => {
196
+ const g = createGestureRecognizer()
197
+ const events = drive(g, [
198
+ ['down', pt(1, 0, 0, 0)],
199
+ ['down', pt(2, 100, 0, 10)],
200
+ ['up', pt(2, 100, 0, 20)],
201
+ ])
202
+ expect(events.find((e) => e.type === 'pinchEnd')).toBeDefined()
203
+ expect(g.state.peek()).toBe('tracking')
204
+ })
205
+ })
206
+
207
+ // ---------------------------------------------------------------------------
208
+ // Cancel
209
+ // ---------------------------------------------------------------------------
210
+
211
+ describe('cancel', () => {
212
+ it('resets to idle without emitting', () => {
213
+ const g = createGestureRecognizer()
214
+ const seen: GestureEvent[] = []
215
+ g.events.subscribe(() => {
216
+ const e = g.events.peek()
217
+ if (e !== null) seen.push(e)
218
+ })
219
+ g.onPointerDown(pt(1, 0, 0, 0))
220
+ g.onPointerMove(pt(1, 100, 0, 10))
221
+ const before = seen.length
222
+ g.cancel()
223
+ expect(g.state.peek()).toBe('idle')
224
+ expect(seen.length).toBe(before) // no emit on cancel
225
+ })
226
+ })
227
+
228
+ // ---------------------------------------------------------------------------
229
+ // Config validation
230
+ // ---------------------------------------------------------------------------
231
+
232
+ describe('options validation', () => {
233
+ it('rejects negative panDeadzone', () => {
234
+ try {
235
+ createGestureRecognizer({ panDeadzone: -1 })
236
+ expect.fail('expected throw')
237
+ } catch (e) {
238
+ expect(isKLineChartError(e, 'INVALID_PARAM')).toBe(true)
239
+ }
240
+ })
241
+
242
+ it('rejects negative swipeMinVelocity', () => {
243
+ try {
244
+ createGestureRecognizer({ swipeMinVelocity: -0.1 })
245
+ expect.fail('expected throw')
246
+ } catch (e) {
247
+ expect(isKLineChartError(e, 'INVALID_PARAM')).toBe(true)
248
+ }
249
+ })
250
+ })
251
+
252
+ // ---------------------------------------------------------------------------
253
+ // Dispose
254
+ // ---------------------------------------------------------------------------
255
+
256
+ describe('dispose', () => {
257
+ it('makes pointer handlers and cancel into no-ops', () => {
258
+ const g = createGestureRecognizer()
259
+ g.dispose()
260
+ const seen: GestureEvent[] = []
261
+ g.events.subscribe(() => {
262
+ const e = g.events.peek()
263
+ if (e !== null) seen.push(e)
264
+ })
265
+ g.onPointerDown(pt(1, 0, 0, 0))
266
+ g.onPointerMove(pt(1, 100, 0, 10))
267
+ g.onPointerUp(pt(1, 100, 0, 20))
268
+ expect(seen).toEqual([])
269
+ expect(g.state.peek()).toBe('idle')
270
+ })
271
+ })