@363045841yyt/klinechart-core 0.7.12-alpha.1 → 0.7.13

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 (277) hide show
  1. package/dist/controllers/createIndicatorSelectorController.d.ts.map +1 -1
  2. package/dist/controllers/createIndicatorSelectorController.js +4 -6
  3. package/dist/controllers/createIndicatorSelectorController.js.map +1 -1
  4. package/dist/controllers/index.d.ts +0 -1
  5. package/dist/controllers/index.d.ts.map +1 -1
  6. package/dist/controllers/index.js +0 -1
  7. package/dist/controllers/index.js.map +1 -1
  8. package/dist/engine/chart.d.ts +6 -2
  9. package/dist/engine/chart.d.ts.map +1 -1
  10. package/dist/engine/chart.js +26 -23
  11. package/dist/engine/chart.js.map +1 -1
  12. package/dist/engine/indicators/indicator.worker.js +32 -4
  13. package/dist/engine/indicators/indicator.worker.js.map +1 -1
  14. package/dist/engine/indicators/indicatorDefinitionRegistry.d.ts +5 -3
  15. package/dist/engine/indicators/indicatorDefinitionRegistry.d.ts.map +1 -1
  16. package/dist/engine/indicators/indicatorDefinitionRegistry.js +26 -1
  17. package/dist/engine/indicators/indicatorDefinitionRegistry.js.map +1 -1
  18. package/dist/engine/indicators/indicatorMetadata.d.ts +54 -1
  19. package/dist/engine/indicators/indicatorMetadata.d.ts.map +1 -1
  20. package/dist/engine/indicators/indicatorMetadata.js.map +1 -1
  21. package/dist/engine/indicators/indicatorRuntime.d.ts +12 -117
  22. package/dist/engine/indicators/indicatorRuntime.d.ts.map +1 -1
  23. package/dist/engine/indicators/indicatorRuntime.js +124 -1308
  24. package/dist/engine/indicators/indicatorRuntime.js.map +1 -1
  25. package/dist/engine/indicators/scheduler.d.ts +19 -143
  26. package/dist/engine/indicators/scheduler.d.ts.map +1 -1
  27. package/dist/engine/indicators/scheduler.js +81 -434
  28. package/dist/engine/indicators/scheduler.js.map +1 -1
  29. package/dist/engine/indicators/stateComposer.d.ts.map +1 -1
  30. package/dist/engine/indicators/stateComposer.js +15 -47
  31. package/dist/engine/indicators/stateComposer.js.map +1 -1
  32. package/dist/engine/indicators/workerProtocol.d.ts +12 -36
  33. package/dist/engine/indicators/workerProtocol.d.ts.map +1 -1
  34. package/dist/engine/indicators/workerProtocol.js.map +1 -1
  35. package/dist/engine/renderers/Indicator/atr.d.ts +2 -1
  36. package/dist/engine/renderers/Indicator/atr.d.ts.map +1 -1
  37. package/dist/engine/renderers/Indicator/atr.js +11 -9
  38. package/dist/engine/renderers/Indicator/atr.js.map +1 -1
  39. package/dist/engine/renderers/Indicator/boll.d.ts +4 -1
  40. package/dist/engine/renderers/Indicator/boll.d.ts.map +1 -1
  41. package/dist/engine/renderers/Indicator/boll.js +24 -10
  42. package/dist/engine/renderers/Indicator/boll.js.map +1 -1
  43. package/dist/engine/renderers/Indicator/cci.d.ts +2 -1
  44. package/dist/engine/renderers/Indicator/cci.d.ts.map +1 -1
  45. package/dist/engine/renderers/Indicator/cci.js +12 -10
  46. package/dist/engine/renderers/Indicator/cci.js.map +1 -1
  47. package/dist/engine/renderers/Indicator/chaikinVol.d.ts +4 -1
  48. package/dist/engine/renderers/Indicator/chaikinVol.d.ts.map +1 -1
  49. package/dist/engine/renderers/Indicator/chaikinVol.js +21 -7
  50. package/dist/engine/renderers/Indicator/chaikinVol.js.map +1 -1
  51. package/dist/engine/renderers/Indicator/cmf.d.ts +4 -1
  52. package/dist/engine/renderers/Indicator/cmf.d.ts.map +1 -1
  53. package/dist/engine/renderers/Indicator/cmf.js +20 -7
  54. package/dist/engine/renderers/Indicator/cmf.js.map +1 -1
  55. package/dist/engine/renderers/Indicator/dema.d.ts +2 -0
  56. package/dist/engine/renderers/Indicator/dema.d.ts.map +1 -1
  57. package/dist/engine/renderers/Indicator/dema.js +19 -8
  58. package/dist/engine/renderers/Indicator/dema.js.map +1 -1
  59. package/dist/engine/renderers/Indicator/donchian.d.ts +4 -1
  60. package/dist/engine/renderers/Indicator/donchian.d.ts.map +1 -1
  61. package/dist/engine/renderers/Indicator/donchian.js +20 -8
  62. package/dist/engine/renderers/Indicator/donchian.js.map +1 -1
  63. package/dist/engine/renderers/Indicator/ene.d.ts +12 -1
  64. package/dist/engine/renderers/Indicator/ene.d.ts.map +1 -1
  65. package/dist/engine/renderers/Indicator/ene.js +25 -11
  66. package/dist/engine/renderers/Indicator/ene.js.map +1 -1
  67. package/dist/engine/renderers/Indicator/expma.d.ts +4 -1
  68. package/dist/engine/renderers/Indicator/expma.d.ts.map +1 -1
  69. package/dist/engine/renderers/Indicator/expma.js +22 -9
  70. package/dist/engine/renderers/Indicator/expma.js.map +1 -1
  71. package/dist/engine/renderers/Indicator/fastk.d.ts +2 -1
  72. package/dist/engine/renderers/Indicator/fastk.d.ts.map +1 -1
  73. package/dist/engine/renderers/Indicator/fastk.js +12 -10
  74. package/dist/engine/renderers/Indicator/fastk.js.map +1 -1
  75. package/dist/engine/renderers/Indicator/fib.d.ts +2 -0
  76. package/dist/engine/renderers/Indicator/fib.d.ts.map +1 -1
  77. package/dist/engine/renderers/Indicator/fib.js +26 -8
  78. package/dist/engine/renderers/Indicator/fib.js.map +1 -1
  79. package/dist/engine/renderers/Indicator/hma.d.ts +2 -0
  80. package/dist/engine/renderers/Indicator/hma.d.ts.map +1 -1
  81. package/dist/engine/renderers/Indicator/hma.js +19 -8
  82. package/dist/engine/renderers/Indicator/hma.js.map +1 -1
  83. package/dist/engine/renderers/Indicator/hv.d.ts +4 -1
  84. package/dist/engine/renderers/Indicator/hv.d.ts.map +1 -1
  85. package/dist/engine/renderers/Indicator/hv.js +18 -8
  86. package/dist/engine/renderers/Indicator/hv.js.map +1 -1
  87. package/dist/engine/renderers/Indicator/ichimoku.d.ts +4 -1
  88. package/dist/engine/renderers/Indicator/ichimoku.d.ts.map +1 -1
  89. package/dist/engine/renderers/Indicator/ichimoku.js +27 -8
  90. package/dist/engine/renderers/Indicator/ichimoku.js.map +1 -1
  91. package/dist/engine/renderers/Indicator/index.d.ts +27 -28
  92. package/dist/engine/renderers/Indicator/index.d.ts.map +1 -1
  93. package/dist/engine/renderers/Indicator/index.js +27 -28
  94. package/dist/engine/renderers/Indicator/index.js.map +1 -1
  95. package/dist/engine/renderers/Indicator/kama.d.ts +2 -0
  96. package/dist/engine/renderers/Indicator/kama.d.ts.map +1 -1
  97. package/dist/engine/renderers/Indicator/kama.js +19 -8
  98. package/dist/engine/renderers/Indicator/kama.js.map +1 -1
  99. package/dist/engine/renderers/Indicator/keltner.d.ts +4 -1
  100. package/dist/engine/renderers/Indicator/keltner.d.ts.map +1 -1
  101. package/dist/engine/renderers/Indicator/keltner.js +20 -8
  102. package/dist/engine/renderers/Indicator/keltner.js.map +1 -1
  103. package/dist/engine/renderers/Indicator/kst.d.ts +2 -1
  104. package/dist/engine/renderers/Indicator/kst.d.ts.map +1 -1
  105. package/dist/engine/renderers/Indicator/kst.js +13 -11
  106. package/dist/engine/renderers/Indicator/kst.js.map +1 -1
  107. package/dist/engine/renderers/Indicator/ma.d.ts +4 -1
  108. package/dist/engine/renderers/Indicator/ma.d.ts.map +1 -1
  109. package/dist/engine/renderers/Indicator/ma.js +36 -8
  110. package/dist/engine/renderers/Indicator/ma.js.map +1 -1
  111. package/dist/engine/renderers/Indicator/macd.d.ts +1 -1
  112. package/dist/engine/renderers/Indicator/macd.d.ts.map +1 -1
  113. package/dist/engine/renderers/Indicator/macd.js +9 -10
  114. package/dist/engine/renderers/Indicator/macd.js.map +1 -1
  115. package/dist/engine/renderers/Indicator/mainIndicatorLegend.d.ts.map +1 -1
  116. package/dist/engine/renderers/Indicator/mainIndicatorLegend.js +38 -136
  117. package/dist/engine/renderers/Indicator/mainIndicatorLegend.js.map +1 -1
  118. package/dist/engine/renderers/Indicator/mfi.d.ts +4 -1
  119. package/dist/engine/renderers/Indicator/mfi.d.ts.map +1 -1
  120. package/dist/engine/renderers/Indicator/mfi.js +20 -7
  121. package/dist/engine/renderers/Indicator/mfi.js.map +1 -1
  122. package/dist/engine/renderers/Indicator/mom.d.ts +2 -1
  123. package/dist/engine/renderers/Indicator/mom.d.ts.map +1 -1
  124. package/dist/engine/renderers/Indicator/mom.js +12 -10
  125. package/dist/engine/renderers/Indicator/mom.js.map +1 -1
  126. package/dist/engine/renderers/Indicator/obv.d.ts +4 -1
  127. package/dist/engine/renderers/Indicator/obv.d.ts.map +1 -1
  128. package/dist/engine/renderers/Indicator/obv.js +19 -7
  129. package/dist/engine/renderers/Indicator/obv.js.map +1 -1
  130. package/dist/engine/renderers/Indicator/parkinson.d.ts +4 -1
  131. package/dist/engine/renderers/Indicator/parkinson.d.ts.map +1 -1
  132. package/dist/engine/renderers/Indicator/parkinson.js +18 -8
  133. package/dist/engine/renderers/Indicator/parkinson.js.map +1 -1
  134. package/dist/engine/renderers/Indicator/pivot.d.ts +2 -0
  135. package/dist/engine/renderers/Indicator/pivot.d.ts.map +1 -1
  136. package/dist/engine/renderers/Indicator/pivot.js +43 -8
  137. package/dist/engine/renderers/Indicator/pivot.js.map +1 -1
  138. package/dist/engine/renderers/Indicator/pvt.d.ts +4 -1
  139. package/dist/engine/renderers/Indicator/pvt.d.ts.map +1 -1
  140. package/dist/engine/renderers/Indicator/pvt.js +19 -7
  141. package/dist/engine/renderers/Indicator/pvt.js.map +1 -1
  142. package/dist/engine/renderers/Indicator/roc.d.ts +4 -1
  143. package/dist/engine/renderers/Indicator/roc.d.ts.map +1 -1
  144. package/dist/engine/renderers/Indicator/roc.js +20 -7
  145. package/dist/engine/renderers/Indicator/roc.js.map +1 -1
  146. package/dist/engine/renderers/Indicator/rsi.d.ts +2 -1
  147. package/dist/engine/renderers/Indicator/rsi.d.ts.map +1 -1
  148. package/dist/engine/renderers/Indicator/rsi.js +14 -11
  149. package/dist/engine/renderers/Indicator/rsi.js.map +1 -1
  150. package/dist/engine/renderers/Indicator/sar.d.ts +4 -1
  151. package/dist/engine/renderers/Indicator/sar.d.ts.map +1 -1
  152. package/dist/engine/renderers/Indicator/sar.js +18 -8
  153. package/dist/engine/renderers/Indicator/sar.js.map +1 -1
  154. package/dist/engine/renderers/Indicator/stoch.d.ts +2 -1
  155. package/dist/engine/renderers/Indicator/stoch.d.ts.map +1 -1
  156. package/dist/engine/renderers/Indicator/stoch.js +10 -11
  157. package/dist/engine/renderers/Indicator/stoch.js.map +1 -1
  158. package/dist/engine/renderers/Indicator/structure.d.ts +4 -1
  159. package/dist/engine/renderers/Indicator/structure.d.ts.map +1 -1
  160. package/dist/engine/renderers/Indicator/structure.js +21 -8
  161. package/dist/engine/renderers/Indicator/structure.js.map +1 -1
  162. package/dist/engine/renderers/Indicator/supertrend.d.ts +4 -1
  163. package/dist/engine/renderers/Indicator/supertrend.d.ts.map +1 -1
  164. package/dist/engine/renderers/Indicator/supertrend.js +18 -8
  165. package/dist/engine/renderers/Indicator/supertrend.js.map +1 -1
  166. package/dist/engine/renderers/Indicator/tema.d.ts +2 -0
  167. package/dist/engine/renderers/Indicator/tema.d.ts.map +1 -1
  168. package/dist/engine/renderers/Indicator/tema.js +19 -8
  169. package/dist/engine/renderers/Indicator/tema.js.map +1 -1
  170. package/dist/engine/renderers/Indicator/trix.d.ts +4 -1
  171. package/dist/engine/renderers/Indicator/trix.d.ts.map +1 -1
  172. package/dist/engine/renderers/Indicator/trix.js +30 -8
  173. package/dist/engine/renderers/Indicator/trix.js.map +1 -1
  174. package/dist/engine/renderers/Indicator/vma.d.ts +4 -1
  175. package/dist/engine/renderers/Indicator/vma.d.ts.map +1 -1
  176. package/dist/engine/renderers/Indicator/vma.js +20 -7
  177. package/dist/engine/renderers/Indicator/vma.js.map +1 -1
  178. package/dist/engine/renderers/Indicator/volumeProfile.d.ts +4 -1
  179. package/dist/engine/renderers/Indicator/volumeProfile.d.ts.map +1 -1
  180. package/dist/engine/renderers/Indicator/volumeProfile.js +28 -8
  181. package/dist/engine/renderers/Indicator/volumeProfile.js.map +1 -1
  182. package/dist/engine/renderers/Indicator/vwap.d.ts +4 -1
  183. package/dist/engine/renderers/Indicator/vwap.d.ts.map +1 -1
  184. package/dist/engine/renderers/Indicator/vwap.js +19 -7
  185. package/dist/engine/renderers/Indicator/vwap.js.map +1 -1
  186. package/dist/engine/renderers/Indicator/wma.d.ts +2 -0
  187. package/dist/engine/renderers/Indicator/wma.d.ts.map +1 -1
  188. package/dist/engine/renderers/Indicator/wma.js +19 -8
  189. package/dist/engine/renderers/Indicator/wma.js.map +1 -1
  190. package/dist/engine/renderers/Indicator/wmsr.d.ts +2 -1
  191. package/dist/engine/renderers/Indicator/wmsr.d.ts.map +1 -1
  192. package/dist/engine/renderers/Indicator/wmsr.js +12 -10
  193. package/dist/engine/renderers/Indicator/wmsr.js.map +1 -1
  194. package/dist/engine/renderers/Indicator/zones.d.ts +2 -0
  195. package/dist/engine/renderers/Indicator/zones.d.ts.map +1 -1
  196. package/dist/engine/renderers/Indicator/zones.js +24 -8
  197. package/dist/engine/renderers/Indicator/zones.js.map +1 -1
  198. package/dist/engine/renderers/paneTitle.d.ts +4 -10
  199. package/dist/engine/renderers/paneTitle.d.ts.map +1 -1
  200. package/dist/engine/renderers/paneTitle.js +28 -6
  201. package/dist/engine/renderers/paneTitle.js.map +1 -1
  202. package/dist/engine/renderers/subVolume.js +0 -3
  203. package/dist/engine/renderers/subVolume.js.map +1 -1
  204. package/dist/version.d.ts +1 -1
  205. package/dist/version.d.ts.map +1 -1
  206. package/dist/version.js +1 -1
  207. package/dist/version.js.map +1 -1
  208. package/package.json +4 -4
  209. package/src/controllers/__tests__/indicatorSelector.test.ts +4 -3
  210. package/src/controllers/createIndicatorSelectorController.ts +4 -6
  211. package/src/controllers/index.ts +0 -4
  212. package/src/engine/chart.ts +30 -22
  213. package/src/engine/indicators/__tests__/registerBuiltins.test.ts +14 -23
  214. package/src/engine/indicators/__tests__/scheduler.test.ts +14 -14
  215. package/src/engine/indicators/__tests__/stateComposer.test.ts +7 -4
  216. package/src/engine/indicators/indicator.worker.ts +36 -4
  217. package/src/engine/indicators/indicatorDefinitionRegistry.ts +38 -3
  218. package/src/engine/indicators/indicatorMetadata.ts +66 -1
  219. package/src/engine/indicators/indicatorRuntime.ts +121 -1447
  220. package/src/engine/indicators/scheduler.ts +85 -489
  221. package/src/engine/indicators/stateComposer.ts +16 -60
  222. package/src/engine/indicators/workerProtocol.ts +14 -36
  223. package/src/engine/renderers/Indicator/atr.ts +14 -11
  224. package/src/engine/renderers/Indicator/boll.ts +33 -10
  225. package/src/engine/renderers/Indicator/cci.ts +15 -14
  226. package/src/engine/renderers/Indicator/chaikinVol.ts +29 -7
  227. package/src/engine/renderers/Indicator/cmf.ts +28 -7
  228. package/src/engine/renderers/Indicator/dema.ts +28 -9
  229. package/src/engine/renderers/Indicator/donchian.ts +28 -9
  230. package/src/engine/renderers/Indicator/ene.ts +34 -11
  231. package/src/engine/renderers/Indicator/expma.ts +31 -9
  232. package/src/engine/renderers/Indicator/fastk.ts +15 -14
  233. package/src/engine/renderers/Indicator/fib.ts +29 -9
  234. package/src/engine/renderers/Indicator/hma.ts +28 -9
  235. package/src/engine/renderers/Indicator/hv.ts +27 -8
  236. package/src/engine/renderers/Indicator/ichimoku.ts +31 -9
  237. package/src/engine/renderers/Indicator/index.ts +27 -28
  238. package/src/engine/renderers/Indicator/kama.ts +28 -9
  239. package/src/engine/renderers/Indicator/keltner.ts +28 -9
  240. package/src/engine/renderers/Indicator/kst.ts +16 -19
  241. package/src/engine/renderers/Indicator/ma.ts +44 -9
  242. package/src/engine/renderers/Indicator/macd.ts +31 -36
  243. package/src/engine/renderers/Indicator/mainIndicatorLegend.ts +43 -162
  244. package/src/engine/renderers/Indicator/mfi.ts +28 -7
  245. package/src/engine/renderers/Indicator/mom.ts +15 -14
  246. package/src/engine/renderers/Indicator/obv.ts +27 -7
  247. package/src/engine/renderers/Indicator/parkinson.ts +27 -8
  248. package/src/engine/renderers/Indicator/pivot.ts +47 -9
  249. package/src/engine/renderers/Indicator/pvt.ts +27 -7
  250. package/src/engine/renderers/Indicator/roc.ts +29 -7
  251. package/src/engine/renderers/Indicator/rsi.ts +14 -17
  252. package/src/engine/renderers/Indicator/sar.ts +26 -9
  253. package/src/engine/renderers/Indicator/stoch.ts +13 -16
  254. package/src/engine/renderers/Indicator/structure.ts +31 -8
  255. package/src/engine/renderers/Indicator/supertrend.ts +26 -9
  256. package/src/engine/renderers/Indicator/tema.ts +28 -9
  257. package/src/engine/renderers/Indicator/trix.ts +39 -8
  258. package/src/engine/renderers/Indicator/vma.ts +28 -7
  259. package/src/engine/renderers/Indicator/volumeProfile.ts +40 -8
  260. package/src/engine/renderers/Indicator/vwap.ts +27 -7
  261. package/src/engine/renderers/Indicator/wma.ts +28 -9
  262. package/src/engine/renderers/Indicator/wmsr.ts +15 -14
  263. package/src/engine/renderers/Indicator/zones.ts +29 -9
  264. package/src/engine/renderers/__tests__/mainIndicatorLegend.renderer.test.ts +142 -79
  265. package/src/engine/renderers/paneTitle.ts +43 -18
  266. package/src/engine/renderers/subVolume.ts +0 -2
  267. package/src/version.ts +1 -1
  268. package/dist/engine/renderers/Indicator/macdLegend.d.ts +0 -13
  269. package/dist/engine/renderers/Indicator/macdLegend.d.ts.map +0 -1
  270. package/dist/engine/renderers/Indicator/macdLegend.js +0 -116
  271. package/dist/engine/renderers/Indicator/macdLegend.js.map +0 -1
  272. package/dist/engine/renderers/Indicator/subPaneConfig.d.ts +0 -16
  273. package/dist/engine/renderers/Indicator/subPaneConfig.d.ts.map +0 -1
  274. package/dist/engine/renderers/Indicator/subPaneConfig.js +0 -194
  275. package/dist/engine/renderers/Indicator/subPaneConfig.js.map +0 -1
  276. package/src/engine/renderers/Indicator/macdLegend.ts +0 -141
  277. package/src/engine/renderers/Indicator/subPaneConfig.ts +0 -265
@@ -10,6 +10,8 @@ import { Indicator } from '../../indicators/indicatorDefinitionRegistry'
10
10
  import { resolveStateKey } from '../../indicators/indicatorMetadata'
11
11
  import type { IndicatorScheduler, MOMSchedulerConfig } from '../../indicators/scheduler'
12
12
  import { createMomScaleRendererPlugin } from './scale/mom_scale'
13
+ import { calcMOMData } from '../../indicators/calculators'
14
+ import type { KLineData } from '../../../types/price'
13
15
 
14
16
  type LinePoint = { x: number; y: number }
15
17
 
@@ -239,7 +241,7 @@ const { ctx, pane, range, scrollLeft, dpr, kLineCenters, lineWebGLSurface } = co
239
241
  },
240
242
 
241
243
  setConfig() {
242
- // no-op: 配置通过 scheduler.updateMOMConfig() 更新
244
+ // no-op: 配置通过 scheduler.updateIndicatorConfig() 更新
243
245
  },
244
246
  }
245
247
  }
@@ -276,14 +278,15 @@ function drawMOMLineWithCanvas2D(
276
278
  * 获取 MOM 标题信息(供 paneTitle 使用)
277
279
  */
278
280
  export function getMOMTitleInfo(
279
- index: number,
280
- period: number,
281
+ _data: KLineData[],
282
+ index: number | null,
283
+ params: Record<string, number | boolean | string>,
281
284
  pluginHost: PluginHost,
282
- paneId: string = 'sub_MOM',
283
- theme: 'light' | 'dark' = 'light',
284
- isAsiaMarket?: boolean
285
+ paneId: string,
285
286
  ): { name: string; params: number[]; values: Array<{ label: string; value: number; color: string }> } | null {
286
- const colors = resolveThemeColors(theme, isAsiaMarket)
287
+ if (index === null) return null
288
+ const period = (params.period as number) ?? 10
289
+ const colors = resolveThemeColors('light')
287
290
  const state = pluginHost.getSharedState<MOMRenderState>(createMOMStateKey(paneId))
288
291
  if (!state) return null
289
292
 
@@ -303,16 +306,14 @@ export function getMOMTitleInfo(
303
306
  name: 'mom',
304
307
  displayName: 'MOM',
305
308
  category: 'oscillator',
306
- stateKey: createMOMStateKey,
307
309
  defaultPaneId: 'sub_MOM',
308
- paneIdField: 'momPaneId',
309
310
  scaleRendererFactory: createMomScaleRendererPlugin,
310
- updateConfig: (scheduler, params, paneId) => {
311
- (scheduler as IndicatorScheduler).updateMOMConfig(params as Partial<MOMSchedulerConfig>, paneId)
312
- },
313
311
  visibleState: { compose: createPaddedSparseVisibleStateComposer('mom', EMPTY_MOM_STATE) },
314
- applyResult: (host, state, paneId) => {
315
- host.setSharedState(createMOMStateKey(paneId), state as any, 'indicator_scheduler')
312
+ getTitleInfo: getMOMTitleInfo,
313
+ runtime: {
314
+ defaultConfig: { period: 10, showMOM: true },
315
+ computeKey: 'calcMOMData',
316
+ compute: (data, c) => calcMOMData(data, c.period),
316
317
  },
317
318
  })
318
319
  class MOMIndicatorDefinition {
@@ -6,6 +6,9 @@ import { Indicator } from '../../indicators/indicatorDefinitionRegistry'
6
6
  import { resolveStateKey } from '../../indicators/indicatorMetadata'
7
7
  import { createSparseVisibleStateComposer } from '../../indicators/visibleStateComposers'
8
8
  import type { IndicatorScheduler, OBVSchedulerConfig } from '../../indicators/scheduler'
9
+ import { calcOBVData } from '../../indicators/calculators'
10
+ import type { TitleInfo } from '../../indicators/indicatorMetadata'
11
+ import type { KLineData } from '../../../types/price'
9
12
 
10
13
  const OBV_COLOR = '#16a34a'
11
14
 
@@ -108,20 +111,37 @@ export function createOBVRendererPlugin(options: { paneId?: string } = {}): Rend
108
111
  }
109
112
  }
110
113
 
114
+ export function getOBVTitleInfo(
115
+ _data: KLineData[],
116
+ index: number | null,
117
+ _params: Record<string, number | boolean | string>,
118
+ host: PluginHost,
119
+ paneId: string,
120
+ ): TitleInfo | null {
121
+ if (index === null) return null
122
+ const state = host.getSharedState<OBVRenderState>(createOBVStateKey(paneId))
123
+ const value = state?.series[index]
124
+ if (value === undefined) return null
125
+
126
+ return {
127
+ name: 'OBV',
128
+ params: [],
129
+ values: [{ label: 'OBV', value, color: OBV_COLOR }],
130
+ }
131
+ }
132
+
111
133
  @Indicator({
112
134
  name: 'obv',
113
135
  displayName: 'OBV',
114
136
  category: 'volume',
115
- stateKey: createOBVStateKey,
116
137
  defaultPaneId: 'sub_OBV',
117
- paneIdField: 'obvPaneId',
118
138
  visibleState: { compose: createSparseVisibleStateComposer('obv', EMPTY_OBV_STATE) },
119
139
  scale: { indicatorKey: 'obv', label: 'OBV', decimals: 0 },
120
- updateConfig: (scheduler, params, paneId) => {
121
- (scheduler as IndicatorScheduler).updateOBVConfig(params as Partial<OBVSchedulerConfig>, paneId)
122
- },
123
- applyResult: (host, state, paneId) => {
124
- host.setSharedState(createOBVStateKey(paneId), state as any, 'indicator_scheduler')
140
+ getTitleInfo: getOBVTitleInfo,
141
+ runtime: {
142
+ defaultConfig: { showOBV: true },
143
+ computeKey: 'calcOBVData',
144
+ compute: (data, c) => calcOBVData(data),
125
145
  },
126
146
  })
127
147
  class OBVIndicatorDefinition {
@@ -1,5 +1,6 @@
1
1
  import type { RendererPluginWithHost, RenderContext, PluginHost } from '../../../plugin'
2
2
  import { RENDERER_PRIORITY } from '../../../plugin'
3
+ import { resolveThemeColors } from '../../../tokens'
3
4
  import type { ParkinsonRenderState } from '../../indicators/parkinsonState'
4
5
  import { createParkinsonStateKey } from '../../indicators/parkinsonState'
5
6
  import { EMPTY_PARKINSON_STATE } from '../../indicators/parkinsonState'
@@ -7,6 +8,9 @@ import { createNonNegativeSparseVisibleStateComposer } from '../../indicators/vi
7
8
  import { Indicator } from '../../indicators/indicatorDefinitionRegistry'
8
9
  import { resolveStateKey } from '../../indicators/indicatorMetadata'
9
10
  import type { IndicatorScheduler, ParkinsonSchedulerConfig } from '../../indicators/scheduler'
11
+ import { calcParkinsonData } from '../../indicators/calculators'
12
+ import type { TitleInfo } from '../../indicators/indicatorMetadata'
13
+ import type { KLineData } from '../../../types/price'
10
14
 
11
15
  const PARKINSON_COLOR = '#0891b2'
12
16
 
@@ -110,21 +114,36 @@ export function createParkinsonRendererPlugin(options: { paneId?: string } = {})
110
114
  }
111
115
  }
112
116
 
117
+ export function getParkinsonTitleInfo(
118
+ _data: KLineData[],
119
+ index: number | null,
120
+ params: Record<string, number | boolean | string>,
121
+ host: PluginHost,
122
+ paneId: string,
123
+ ): TitleInfo | null {
124
+ if (index === null) return null
125
+ const period = (params.period as number) ?? 20
126
+ const annualizationFactor = (params.annualizationFactor as number) ?? 252
127
+ const state = host.getSharedState<ParkinsonRenderState>(createParkinsonStateKey(paneId))
128
+ const value = state?.series[index]
129
+ if (value === undefined) return null
130
+
131
+ return {
132
+ name: 'Parkinson',
133
+ params: [period, annualizationFactor],
134
+ values: [{ label: 'Parkinson', value, color: PARKINSON_COLOR }],
135
+ }
136
+ }
137
+
113
138
  @Indicator({
114
139
  name: 'parkinson',
115
140
  displayName: 'Parkinson',
116
141
  category: 'oscillator',
117
- stateKey: createParkinsonStateKey,
118
142
  defaultPaneId: 'sub_Parkinson',
119
- paneIdField: 'parkinsonPaneId',
120
143
  scale: { indicatorKey: 'parkinson', label: 'Parkinson', decimals: 2 },
121
- updateConfig: (scheduler, params, paneId) => {
122
- (scheduler as IndicatorScheduler).updateParkinsonConfig(params as Partial<ParkinsonSchedulerConfig>, paneId)
123
- },
144
+ getTitleInfo: getParkinsonTitleInfo,
124
145
  visibleState: { compose: createNonNegativeSparseVisibleStateComposer('parkinson', EMPTY_PARKINSON_STATE) },
125
- applyResult: (host, state, paneId) => {
126
- host.setSharedState(createParkinsonStateKey(paneId), state as any, 'indicator_scheduler')
127
- },
146
+ runtime: { defaultConfig:{period:20,annualizationFactor:252,showParkinson:true}, computeKey:'calcParkinsonData', compute:(data,c)=>calcParkinsonData(data,c.period,c.annualizationFactor) },
128
147
  })
129
148
  class ParkinsonIndicatorDefinition {
130
149
  static rendererFactory = createParkinsonRendererPlugin
@@ -3,9 +3,10 @@ import { RENDERER_PRIORITY } from '../../../plugin'
3
3
  import type { PivotRenderState } from '../../indicators/pivotState'
4
4
  import { createPivotStateKey, EMPTY_PIVOT_STATE } from '../../indicators/pivotState'
5
5
  import { Indicator } from '../../indicators/indicatorDefinitionRegistry'
6
- import { resolveStateKey } from '../../indicators/indicatorMetadata'
6
+ import { resolveStateKey, type TitleInfo, type TitleValueItem, type GetTitleInfoFn } from '../../indicators/indicatorMetadata'
7
7
  import type { IndicatorScheduler, PivotSchedulerConfig } from '../../indicators/scheduler'
8
8
  import { createExactRangePointVisibleStateComposer } from '../../indicators/visibleStateComposers'
9
+ import { calcPivotData } from '../../indicators/calculators'
9
10
 
10
11
  const PP_COLOR = '#94a3b8'
11
12
  const R_COLOR = '#dc2626'
@@ -115,23 +116,60 @@ function drawStep(ctx: CanvasRenderingContext2D, pts: Point[], color: string): v
115
116
  ctx.stroke()
116
117
  }
117
118
 
119
+ export const getPivotTitleInfo: GetTitleInfoFn = (_data, index, _params, host, paneId) => {
120
+ if (index === null || index < 0) return null
121
+
122
+ const stateKey = createPivotStateKey(paneId)
123
+ const state = host?.getSharedState<PivotRenderState>(stateKey)
124
+ if (!state) return null
125
+
126
+ const p = state.series[index]
127
+ if (!p) return null
128
+
129
+ const values: TitleValueItem[] = []
130
+
131
+ if (state.params.showPP) {
132
+ values.push({ label: 'PP', value: p.pp, color: PP_COLOR })
133
+ }
134
+ if (state.params.showR1) {
135
+ values.push({ label: 'R1', value: p.r1, color: R_COLOR })
136
+ }
137
+ if (state.params.showR2) {
138
+ values.push({ label: 'R2', value: p.r2, color: R_COLOR })
139
+ }
140
+ if (state.params.showR3) {
141
+ values.push({ label: 'R3', value: p.r3, color: R_COLOR })
142
+ }
143
+ if (state.params.showS1) {
144
+ values.push({ label: 'S1', value: p.s1, color: S_COLOR })
145
+ }
146
+ if (state.params.showS2) {
147
+ values.push({ label: 'S2', value: p.s2, color: S_COLOR })
148
+ }
149
+ if (state.params.showS3) {
150
+ values.push({ label: 'S3', value: p.s3, color: S_COLOR })
151
+ }
152
+
153
+ if (values.length === 0) return null
154
+
155
+ return {
156
+ name: 'Pivot',
157
+ params: [],
158
+ values,
159
+ }
160
+ }
161
+
118
162
  @Indicator({
119
163
  name: 'pivot',
120
164
  displayName: 'Pivot',
165
+ getTitleInfo: getPivotTitleInfo,
121
166
  category: 'main',
122
- stateKey: createPivotStateKey,
123
167
  defaultPaneId: 'main',
124
- paneIdField: 'pivotPaneId',
125
168
  allowMainPane: true,
126
169
  mainPane: { rendererName: 'pivot_main', toActiveConfig: (params, active) => ({ ...params, showPP: active, showR1: active, showR2: active, showR3: active, showS1: active, showS2: active, showS3: active }) },
127
170
  scale: { indicatorKey: 'pivot', label: 'Pivot', decimals: 2 },
128
171
  visibleState: { compose: createExactRangePointVisibleStateComposer('pivot', EMPTY_PIVOT_STATE, ['pp', 'r1', 'r2', 'r3', 's1', 's2', 's3']) },
129
- updateConfig: (scheduler, params, paneId) => {
130
- (scheduler as IndicatorScheduler).updatePivotConfig(params as Partial<PivotSchedulerConfig>, paneId)
131
- },
132
- applyResult: (host, state, paneId) => {
133
- host.setSharedState(createPivotStateKey(paneId), state as any, 'indicator_scheduler')
134
- },
172
+ runtime: { defaultConfig:{showPP:true,showR1:true,showR2:true,showR3:true,showS1:true,showS2:true,showS3:true}, computeKey:'calcPivotData', compute:(data,c)=>calcPivotData(data) },
135
173
  })
136
174
  class PivotDefinition {
137
175
  static rendererFactory = createPivotRendererPlugin
@@ -6,6 +6,9 @@ import { Indicator } from '../../indicators/indicatorDefinitionRegistry'
6
6
  import { resolveStateKey } from '../../indicators/indicatorMetadata'
7
7
  import { createSparseVisibleStateComposer } from '../../indicators/visibleStateComposers'
8
8
  import type { IndicatorScheduler, PVTSchedulerConfig } from '../../indicators/scheduler'
9
+ import { calcPVTData } from '../../indicators/calculators'
10
+ import type { TitleInfo } from '../../indicators/indicatorMetadata'
11
+ import type { KLineData } from '../../../types/price'
9
12
 
10
13
  const PVT_COLOR = '#a855f7'
11
14
 
@@ -108,20 +111,37 @@ export function createPVTRendererPlugin(options: { paneId?: string } = {}): Rend
108
111
  }
109
112
  }
110
113
 
114
+ export function getPVTTitleInfo(
115
+ _data: KLineData[],
116
+ index: number | null,
117
+ _params: Record<string, number | boolean | string>,
118
+ host: PluginHost,
119
+ paneId: string,
120
+ ): TitleInfo | null {
121
+ if (index === null) return null
122
+ const state = host.getSharedState<PVTRenderState>(createPVTStateKey(paneId))
123
+ const value = state?.series[index]
124
+ if (value === undefined) return null
125
+
126
+ return {
127
+ name: 'PVT',
128
+ params: [],
129
+ values: [{ label: 'PVT', value, color: PVT_COLOR }],
130
+ }
131
+ }
132
+
111
133
  @Indicator({
112
134
  name: 'pvt',
113
135
  displayName: 'PVT',
114
136
  category: 'volume',
115
- stateKey: createPVTStateKey,
116
137
  defaultPaneId: 'sub_PVT',
117
- paneIdField: 'pvtPaneId',
118
138
  visibleState: { compose: createSparseVisibleStateComposer('pvt', EMPTY_PVT_STATE) },
119
139
  scale: { indicatorKey: 'pvt', label: 'PVT', decimals: 0 },
120
- updateConfig: (scheduler, params, paneId) => {
121
- (scheduler as IndicatorScheduler).updatePVTConfig(params as Partial<PVTSchedulerConfig>, paneId)
122
- },
123
- applyResult: (host, state, paneId) => {
124
- host.setSharedState(createPVTStateKey(paneId), state as any, 'indicator_scheduler')
140
+ getTitleInfo: getPVTTitleInfo,
141
+ runtime: {
142
+ defaultConfig: { showPVT: true },
143
+ computeKey: 'calcPVTData',
144
+ compute: (data, c) => calcPVTData(data),
125
145
  },
126
146
  })
127
147
  class PVTIndicatorDefinition {
@@ -1,11 +1,15 @@
1
1
  import type { RendererPluginWithHost, RenderContext, PluginHost } from '../../../plugin'
2
2
  import { RENDERER_PRIORITY } from '../../../plugin'
3
+ import { resolveThemeColors } from '../../../tokens'
3
4
  import type { ROCRenderState } from '../../indicators/rocState'
4
5
  import { createROCStateKey, EMPTY_ROC_STATE } from '../../indicators/rocState'
5
6
  import { Indicator } from '../../indicators/indicatorDefinitionRegistry'
6
7
  import { resolveStateKey } from '../../indicators/indicatorMetadata'
7
8
  import { createSparseVisibleStateComposer } from '../../indicators/visibleStateComposers'
8
9
  import type { IndicatorScheduler, ROCSchedulerConfig } from '../../indicators/scheduler'
10
+ import { calcROCData } from '../../indicators/calculators'
11
+ import type { KLineData } from '../../../types/price'
12
+ import type { TitleInfo } from '../../indicators/indicatorMetadata'
9
13
 
10
14
  const ROC_COLOR = '#0ea5e9'
11
15
 
@@ -128,20 +132,38 @@ export function createROCRendererPlugin(options: ROCRendererOptions = {}): Rende
128
132
  }
129
133
  }
130
134
 
135
+ export function getROCTitleInfo(
136
+ _data: KLineData[],
137
+ index: number | null,
138
+ params: Record<string, number | boolean | string>,
139
+ pluginHost: PluginHost,
140
+ paneId: string,
141
+ ): TitleInfo | null {
142
+ if (index === null) return null
143
+ const period = (params.period as number) ?? 12
144
+ const state = pluginHost.getSharedState<ROCRenderState>(createROCStateKey(paneId))
145
+ const value = state?.series[index]
146
+ if (value === undefined) return null
147
+
148
+ return {
149
+ name: 'ROC',
150
+ params: [period],
151
+ values: [{ label: 'ROC', value, color: ROC_COLOR }],
152
+ }
153
+ }
154
+
131
155
  @Indicator({
132
156
  name: 'roc',
133
157
  displayName: 'ROC',
134
158
  category: 'oscillator',
135
- stateKey: createROCStateKey,
136
159
  defaultPaneId: 'sub_ROC',
137
- paneIdField: 'rocPaneId',
138
160
  visibleState: { compose: createSparseVisibleStateComposer('roc', EMPTY_ROC_STATE) },
139
161
  scale: { indicatorKey: 'roc', label: 'ROC', decimals: 2 },
140
- updateConfig: (scheduler, params, paneId) => {
141
- (scheduler as IndicatorScheduler).updateROCConfig(params as Partial<ROCSchedulerConfig>, paneId)
142
- },
143
- applyResult: (host, state, paneId) => {
144
- host.setSharedState(createROCStateKey(paneId), state as any, 'indicator_scheduler')
162
+ getTitleInfo: getROCTitleInfo,
163
+ runtime: {
164
+ defaultConfig: { period: 12, showROC: true },
165
+ computeKey: 'calcROCData',
166
+ compute: (data, c) => calcROCData(data, c.period),
145
167
  },
146
168
  })
147
169
  class ROCIndicatorDefinition {
@@ -9,6 +9,8 @@ import { createFixedRangeRecordVisibleStateComposer } from '../../indicators/vis
9
9
  import { resolveStateKey } from '../../indicators/indicatorMetadata'
10
10
  import type { IndicatorScheduler, RSISchedulerConfig } from '../../indicators/scheduler'
11
11
  import { createRsiScaleRendererPlugin } from './scale/rsi_scale'
12
+ import { calcRSIData } from '../../indicators/calculators'
13
+ import type { KLineData } from '../../../types/price'
12
14
 
13
15
  type LinePoint = { x: number; y: number }
14
16
 
@@ -287,7 +289,7 @@ const { ctx, pane, range, scrollLeft, dpr, kLineCenters, lineWebGLSurface } = co
287
289
  },
288
290
 
289
291
  setConfig(_newConfig: Record<string, unknown>) {
290
- // 无状态渲染器:配置变更请使用 chart.getIndicatorScheduler().updateRSIConfig()
292
+ // 无状态渲染器:配置变更请使用 chart.getIndicatorScheduler().updateIndicatorConfig()
291
293
  },
292
294
  }
293
295
  }
@@ -350,16 +352,17 @@ export function drawRSILinesWithCanvas2D(
350
352
  }
351
353
 
352
354
  export function getRSITitleInfo(
353
- index: number,
354
- period1: number,
355
- period2: number,
356
- period3: number,
355
+ _data: KLineData[],
356
+ index: number | null,
357
+ params: Record<string, number | boolean | string>,
357
358
  pluginHost: PluginHost,
358
- paneId: string = 'sub_RSI',
359
- theme: 'light' | 'dark' = 'light',
360
- isAsiaMarket?: boolean
359
+ paneId: string,
361
360
  ): { name: string; params: number[]; values: Array<{ label: string; value: number; color: string }> } | null {
362
- const colors = resolveThemeColors(theme, isAsiaMarket)
361
+ if (index === null) return null
362
+ const period1 = (params.period1 as number) ?? 6
363
+ const period2 = (params.period2 as number) ?? 12
364
+ const period3 = (params.period3 as number) ?? 24
365
+ const colors = resolveThemeColors('light')
363
366
  const stateKey = createRSIStateKey(paneId)
364
367
  const state = pluginHost.getSharedState<RSIRenderState>(stateKey)
365
368
 
@@ -387,17 +390,11 @@ export function getRSITitleInfo(
387
390
  name: 'rsi',
388
391
  displayName: 'RSI',
389
392
  category: 'oscillator',
390
- stateKey: createRSIStateKey,
391
393
  defaultPaneId: 'sub_RSI',
392
- paneIdField: 'rsiPaneId',
393
394
  visibleState: { compose: createFixedRangeRecordVisibleStateComposer('rsi', EMPTY_RSI_STATE) },
394
395
  scaleRendererFactory: createRsiScaleRendererPlugin,
395
- updateConfig: (scheduler, params, paneId) => {
396
- (scheduler as IndicatorScheduler).updateRSIConfig(params as Partial<RSISchedulerConfig>, paneId)
397
- },
398
- applyResult: (host, state, paneId) => {
399
- host.setSharedState(createRSIStateKey(paneId), state as any, 'indicator_scheduler')
400
- },
396
+ getTitleInfo: getRSITitleInfo,
397
+ runtime: { defaultConfig:{period1:6,period2:12,period3:24,showRSI1:true,showRSI2:true,showRSI3:true}, computeKey:'calcRSIData', compute:(data,c)=>{const p=[c.period1,c.period2,c.period3];const s=[c.showRSI1,c.showRSI2,c.showRSI3];const r:Record<number,(number|undefined)[]>={};for(let i=0;i<3;i++){if(s[i])r[p[i]]=calcRSIData(data,p[i])}return r} },
401
398
  })
402
399
  class RSIIndicatorDefinition {
403
400
  static rendererFactory = createRSIRendererPlugin
@@ -1,10 +1,12 @@
1
1
  import type { RendererPluginWithHost, RenderContext, PluginHost } from '../../../plugin'
2
2
  import { RENDERER_PRIORITY } from '../../../plugin'
3
+ import type { KLineData } from '../../../types/price'
3
4
  import type { SARRenderState } from '../../indicators/sarState'
4
5
  import { createSARStateKey, EMPTY_SAR_STATE } from '../../indicators/sarState'
5
6
  import { Indicator } from '../../indicators/indicatorDefinitionRegistry'
6
- import { resolveStateKey } from '../../indicators/indicatorMetadata'
7
+ import { resolveStateKey, type TitleInfo, type GetTitleInfoFn } from '../../indicators/indicatorMetadata'
7
8
  import type { IndicatorScheduler, SARSchedulerConfig } from '../../indicators/scheduler'
9
+ import { calcSARData } from '../../indicators/calculators'
8
10
  import { createValuePointVisibleStateComposer } from '../../indicators/visibleStateComposers'
9
11
 
10
12
  const SAR_UP_COLOR = '#22c55e'
@@ -97,23 +99,38 @@ export function createSARRendererPlugin(options: SARRendererOptions = {}): Rende
97
99
  }
98
100
  }
99
101
 
102
+ export function getSARTitleInfo(
103
+ _data: KLineData[],
104
+ index: number | null,
105
+ params: Record<string, number | boolean | string>,
106
+ host: PluginHost,
107
+ paneId: string,
108
+ ): TitleInfo | null {
109
+ if (index === null) return null
110
+ const state = host.getSharedState<SARRenderState>(createSARStateKey(paneId))
111
+ const p = state?.series[index]
112
+ if (!p) return null
113
+
114
+ return {
115
+ name: 'SAR',
116
+ params: [(params.step as number) ?? 0.02, (params.maxStep as number) ?? 0.2],
117
+ values: [
118
+ { label: 'SAR', value: p.value, color: p.trend === 'up' ? '#22c55e' : '#ef4444' },
119
+ ],
120
+ }
121
+ }
122
+
100
123
  @Indicator({
101
124
  name: 'sar',
102
125
  displayName: 'SAR',
126
+ getTitleInfo: getSARTitleInfo,
103
127
  category: 'main',
104
- stateKey: createSARStateKey,
105
128
  defaultPaneId: 'main',
106
- paneIdField: 'sarPaneId',
107
129
  allowMainPane: true,
108
130
  mainPane: { rendererName: 'sar_main', toActiveConfig: (params, active) => ({ ...params, showSAR: active }) },
109
131
  scale: { indicatorKey: 'sar', label: 'SAR', decimals: 4 },
110
132
  visibleState: { compose: createValuePointVisibleStateComposer('sar', EMPTY_SAR_STATE, ['value']) },
111
- updateConfig: (scheduler, params, paneId) => {
112
- (scheduler as IndicatorScheduler).updateSARConfig(params as Partial<SARSchedulerConfig>, paneId)
113
- },
114
- applyResult: (host, state, paneId) => {
115
- host.setSharedState(createSARStateKey(paneId), state as any, 'indicator_scheduler')
116
- },
133
+ runtime: { defaultConfig:{step:0.02,maxStep:0.2,showSAR:true}, computeKey:'calcSARData', compute:(data,c)=>calcSARData(data,c.step,c.maxStep) },
117
134
  })
118
135
  class SARDefinition {
119
136
  static rendererFactory = createSARRendererPlugin
@@ -9,6 +9,8 @@ import { createFixedRangePointVisibleStateComposer } from '../../indicators/visi
9
9
  import { resolveStateKey } from '../../indicators/indicatorMetadata'
10
10
  import type { IndicatorScheduler, STOCHSchedulerConfig } from '../../indicators/scheduler'
11
11
  import { createStochScaleRendererPlugin } from './scale/stoch_scale'
12
+ import { calcSTOCHData } from '../../indicators/calculators'
13
+ import type { KLineData } from '../../../types/price'
12
14
 
13
15
  type LinePoint = { x: number; y: number }
14
16
 
@@ -267,7 +269,7 @@ const { ctx, pane, range, scrollLeft, dpr, kLineCenters, lineWebGLSurface } = co
267
269
  },
268
270
 
269
271
  setConfig() {
270
- // no-op: 配置通过 scheduler.updateSTOCHConfig() 更新
272
+ // no-op: 配置通过 scheduler.updateIndicatorConfig() 更新
271
273
  },
272
274
  }
273
275
  }
@@ -318,15 +320,16 @@ function drawSTOCHLinesWithCanvas2D(
318
320
  * 获取 STOCH 标题信息(供 paneTitle 使用)
319
321
  */
320
322
  export function getSTOCHTitleInfo(
321
- index: number,
322
- n: number,
323
- m: number,
323
+ _data: KLineData[],
324
+ index: number | null,
325
+ params: Record<string, number | boolean | string>,
324
326
  pluginHost: PluginHost,
325
- paneId: string = 'sub_STOCH',
326
- theme: 'light' | 'dark' = 'light',
327
- isAsiaMarket?: boolean
327
+ paneId: string,
328
328
  ): { name: string; params: number[]; values: Array<{ label: string; value: number; color: string }> } | null {
329
- const colors = resolveThemeColors(theme, isAsiaMarket)
329
+ if (index === null) return null
330
+ const n = (params.n as number) ?? 9
331
+ const m = (params.m as number) ?? 3
332
+ const colors = resolveThemeColors('light')
330
333
  const state = pluginHost.getSharedState<STOCHRenderState>(createSTOCHStateKey(paneId))
331
334
  if (!state) return null
332
335
 
@@ -350,17 +353,11 @@ export function getSTOCHTitleInfo(
350
353
  name: 'stoch',
351
354
  displayName: 'STOCH',
352
355
  category: 'oscillator',
353
- stateKey: createSTOCHStateKey,
354
356
  defaultPaneId: 'sub_STOCH',
355
- paneIdField: 'stochPaneId',
356
357
  visibleState: { compose: createFixedRangePointVisibleStateComposer('stoch', EMPTY_STOCH_STATE, ['k', 'd'] as const) },
357
358
  scaleRendererFactory: createStochScaleRendererPlugin,
358
- updateConfig: (scheduler, params, paneId) => {
359
- (scheduler as IndicatorScheduler).updateSTOCHConfig(params as Partial<STOCHSchedulerConfig>, paneId)
360
- },
361
- applyResult: (host, state, paneId) => {
362
- host.setSharedState(createSTOCHStateKey(paneId), state as any, 'indicator_scheduler')
363
- },
359
+ getTitleInfo: getSTOCHTitleInfo,
360
+ runtime: { defaultConfig:{n:9,m:3,showK:true,showD:true}, computeKey:'calcSTOCHData', compute:(data,c)=>calcSTOCHData(data,c.n,c.m) },
364
361
  })
365
362
  class STOCHIndicatorDefinition {
366
363
  static rendererFactory = createSTOCHRendererPlugin
@@ -7,6 +7,9 @@ import { Indicator } from '../../indicators/indicatorDefinitionRegistry'
7
7
  import { createFixedUnitVisibleStateComposer } from '../../indicators/visibleStateComposers'
8
8
  import { resolveStateKey } from '../../indicators/indicatorMetadata'
9
9
  import type { IndicatorScheduler, StructureSchedulerConfig } from '../../indicators/scheduler'
10
+ import { calcStructureData } from '../../indicators/calculators'
11
+ import type { TitleInfo } from '../../indicators/indicatorMetadata'
12
+ import type { KLineData } from '../../../types/price'
10
13
 
11
14
  const LABEL_FONT = '11px sans-serif'
12
15
 
@@ -110,23 +113,43 @@ export function createStructureRendererPlugin(options: { paneId?: string } = {})
110
113
  }
111
114
  }
112
115
 
116
+ export function getStructureTitleInfo(
117
+ _data: KLineData[],
118
+ index: number | null,
119
+ params: Record<string, number | boolean | string>,
120
+ host: PluginHost,
121
+ paneId: string,
122
+ ): TitleInfo | null {
123
+ if (index === null) return null
124
+ const leftWindow = (params.leftWindow as number) ?? 5
125
+ const rightWindow = (params.rightWindow as number) ?? 2
126
+ const colors = resolveThemeColors('light')
127
+ const state = host.getSharedState<StructureRenderState>(createStructureStateKey(paneId))
128
+
129
+ const values: Array<{ label: string; value: number; color: string }> = []
130
+ if (state && state.series.swings.length > 0) {
131
+ values.push({ label: 'Swings', value: state.series.swings.length, color: colors.structure.hh })
132
+ values.push({ label: 'Events', value: state.series.events.length, color: colors.structure.choch })
133
+ }
134
+
135
+ return {
136
+ name: 'Structure',
137
+ params: [leftWindow, rightWindow],
138
+ values,
139
+ }
140
+ }
141
+
113
142
  @Indicator({
114
143
  name: 'structure',
115
144
  displayName: 'Structure',
116
145
  category: 'sub',
117
- stateKey: createStructureStateKey,
118
146
  defaultPaneId: 'sub_Structure',
119
- paneIdField: 'structurePaneId',
120
147
  allowMainPane: true,
121
148
  mainPane: { rendererName: 'structure_main', toActiveConfig: (params, active) => ({ ...params, showSwingLabels: active, showBOS: active, showCHOCH: active }) },
122
149
  scale: { indicatorKey: 'structure', label: 'Structure', decimals: 2 },
150
+ getTitleInfo: getStructureTitleInfo,
123
151
  visibleState: { compose: createFixedUnitVisibleStateComposer('structure', EMPTY_STRUCTURE_STATE) },
124
- updateConfig: (scheduler, params, paneId) => {
125
- (scheduler as IndicatorScheduler).updateStructureConfig(params as Partial<StructureSchedulerConfig>, paneId)
126
- },
127
- applyResult: (host, state, paneId) => {
128
- host.setSharedState(createStructureStateKey(paneId), state as any, 'indicator_scheduler')
129
- },
152
+ runtime: { defaultConfig:{leftWindow:5,rightWindow:2,breakoutSource:'close',showSwingLabels:true,showBOS:true,showCHOCH:true,showProvisional:true}, computeKey:'calcStructureData', compute:(data,c)=>calcStructureData(data,c.leftWindow,c.rightWindow,c.breakoutSource) },
130
153
  })
131
154
  class StructureIndicatorDefinition {
132
155
  static rendererFactory = createStructureRendererPlugin