@363045841yyt/klinechart-core 0.7.12 → 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 (261) 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/indicatorDefinitionRegistry.d.ts +3 -2
  13. package/dist/engine/indicators/indicatorDefinitionRegistry.d.ts.map +1 -1
  14. package/dist/engine/indicators/indicatorDefinitionRegistry.js +26 -1
  15. package/dist/engine/indicators/indicatorDefinitionRegistry.js.map +1 -1
  16. package/dist/engine/indicators/indicatorMetadata.d.ts +29 -2
  17. package/dist/engine/indicators/indicatorMetadata.d.ts.map +1 -1
  18. package/dist/engine/indicators/indicatorMetadata.js.map +1 -1
  19. package/dist/engine/indicators/indicatorRuntime.d.ts.map +1 -1
  20. package/dist/engine/indicators/indicatorRuntime.js +5 -4
  21. package/dist/engine/indicators/indicatorRuntime.js.map +1 -1
  22. package/dist/engine/indicators/scheduler.d.ts +16 -1
  23. package/dist/engine/indicators/scheduler.d.ts.map +1 -1
  24. package/dist/engine/indicators/scheduler.js +26 -7
  25. package/dist/engine/indicators/scheduler.js.map +1 -1
  26. package/dist/engine/renderers/Indicator/atr.d.ts +2 -1
  27. package/dist/engine/renderers/Indicator/atr.d.ts.map +1 -1
  28. package/dist/engine/renderers/Indicator/atr.js +5 -9
  29. package/dist/engine/renderers/Indicator/atr.js.map +1 -1
  30. package/dist/engine/renderers/Indicator/boll.d.ts +4 -1
  31. package/dist/engine/renderers/Indicator/boll.d.ts.map +1 -1
  32. package/dist/engine/renderers/Indicator/boll.js +22 -10
  33. package/dist/engine/renderers/Indicator/boll.js.map +1 -1
  34. package/dist/engine/renderers/Indicator/cci.d.ts +2 -1
  35. package/dist/engine/renderers/Indicator/cci.d.ts.map +1 -1
  36. package/dist/engine/renderers/Indicator/cci.js +6 -10
  37. package/dist/engine/renderers/Indicator/cci.js.map +1 -1
  38. package/dist/engine/renderers/Indicator/chaikinVol.d.ts +4 -1
  39. package/dist/engine/renderers/Indicator/chaikinVol.d.ts.map +1 -1
  40. package/dist/engine/renderers/Indicator/chaikinVol.js +16 -8
  41. package/dist/engine/renderers/Indicator/chaikinVol.js.map +1 -1
  42. package/dist/engine/renderers/Indicator/cmf.d.ts +4 -1
  43. package/dist/engine/renderers/Indicator/cmf.d.ts.map +1 -1
  44. package/dist/engine/renderers/Indicator/cmf.js +15 -8
  45. package/dist/engine/renderers/Indicator/cmf.js.map +1 -1
  46. package/dist/engine/renderers/Indicator/dema.d.ts +2 -0
  47. package/dist/engine/renderers/Indicator/dema.d.ts.map +1 -1
  48. package/dist/engine/renderers/Indicator/dema.js +18 -8
  49. package/dist/engine/renderers/Indicator/dema.js.map +1 -1
  50. package/dist/engine/renderers/Indicator/donchian.d.ts +4 -1
  51. package/dist/engine/renderers/Indicator/donchian.d.ts.map +1 -1
  52. package/dist/engine/renderers/Indicator/donchian.js +19 -8
  53. package/dist/engine/renderers/Indicator/donchian.js.map +1 -1
  54. package/dist/engine/renderers/Indicator/ene.d.ts +12 -1
  55. package/dist/engine/renderers/Indicator/ene.d.ts.map +1 -1
  56. package/dist/engine/renderers/Indicator/ene.js +22 -10
  57. package/dist/engine/renderers/Indicator/ene.js.map +1 -1
  58. package/dist/engine/renderers/Indicator/expma.d.ts +4 -1
  59. package/dist/engine/renderers/Indicator/expma.d.ts.map +1 -1
  60. package/dist/engine/renderers/Indicator/expma.js +21 -10
  61. package/dist/engine/renderers/Indicator/expma.js.map +1 -1
  62. package/dist/engine/renderers/Indicator/fastk.d.ts +2 -1
  63. package/dist/engine/renderers/Indicator/fastk.d.ts.map +1 -1
  64. package/dist/engine/renderers/Indicator/fastk.js +6 -10
  65. package/dist/engine/renderers/Indicator/fastk.js.map +1 -1
  66. package/dist/engine/renderers/Indicator/fib.d.ts +2 -0
  67. package/dist/engine/renderers/Indicator/fib.d.ts.map +1 -1
  68. package/dist/engine/renderers/Indicator/fib.js +25 -8
  69. package/dist/engine/renderers/Indicator/fib.js.map +1 -1
  70. package/dist/engine/renderers/Indicator/hma.d.ts +2 -0
  71. package/dist/engine/renderers/Indicator/hma.d.ts.map +1 -1
  72. package/dist/engine/renderers/Indicator/hma.js +18 -8
  73. package/dist/engine/renderers/Indicator/hma.js.map +1 -1
  74. package/dist/engine/renderers/Indicator/hv.d.ts +4 -1
  75. package/dist/engine/renderers/Indicator/hv.d.ts.map +1 -1
  76. package/dist/engine/renderers/Indicator/hv.js +17 -8
  77. package/dist/engine/renderers/Indicator/hv.js.map +1 -1
  78. package/dist/engine/renderers/Indicator/ichimoku.d.ts +4 -1
  79. package/dist/engine/renderers/Indicator/ichimoku.d.ts.map +1 -1
  80. package/dist/engine/renderers/Indicator/ichimoku.js +26 -8
  81. package/dist/engine/renderers/Indicator/ichimoku.js.map +1 -1
  82. package/dist/engine/renderers/Indicator/index.d.ts +27 -28
  83. package/dist/engine/renderers/Indicator/index.d.ts.map +1 -1
  84. package/dist/engine/renderers/Indicator/index.js +27 -28
  85. package/dist/engine/renderers/Indicator/index.js.map +1 -1
  86. package/dist/engine/renderers/Indicator/kama.d.ts +2 -0
  87. package/dist/engine/renderers/Indicator/kama.d.ts.map +1 -1
  88. package/dist/engine/renderers/Indicator/kama.js +18 -8
  89. package/dist/engine/renderers/Indicator/kama.js.map +1 -1
  90. package/dist/engine/renderers/Indicator/keltner.d.ts +4 -1
  91. package/dist/engine/renderers/Indicator/keltner.d.ts.map +1 -1
  92. package/dist/engine/renderers/Indicator/keltner.js +19 -8
  93. package/dist/engine/renderers/Indicator/keltner.js.map +1 -1
  94. package/dist/engine/renderers/Indicator/kst.d.ts +2 -1
  95. package/dist/engine/renderers/Indicator/kst.d.ts.map +1 -1
  96. package/dist/engine/renderers/Indicator/kst.js +11 -10
  97. package/dist/engine/renderers/Indicator/kst.js.map +1 -1
  98. package/dist/engine/renderers/Indicator/ma.d.ts +4 -1
  99. package/dist/engine/renderers/Indicator/ma.d.ts.map +1 -1
  100. package/dist/engine/renderers/Indicator/ma.js +32 -9
  101. package/dist/engine/renderers/Indicator/ma.js.map +1 -1
  102. package/dist/engine/renderers/Indicator/macd.d.ts +1 -1
  103. package/dist/engine/renderers/Indicator/macd.d.ts.map +1 -1
  104. package/dist/engine/renderers/Indicator/macd.js +9 -10
  105. package/dist/engine/renderers/Indicator/macd.js.map +1 -1
  106. package/dist/engine/renderers/Indicator/mainIndicatorLegend.d.ts.map +1 -1
  107. package/dist/engine/renderers/Indicator/mainIndicatorLegend.js +38 -136
  108. package/dist/engine/renderers/Indicator/mainIndicatorLegend.js.map +1 -1
  109. package/dist/engine/renderers/Indicator/mfi.d.ts +4 -1
  110. package/dist/engine/renderers/Indicator/mfi.d.ts.map +1 -1
  111. package/dist/engine/renderers/Indicator/mfi.js +15 -8
  112. package/dist/engine/renderers/Indicator/mfi.js.map +1 -1
  113. package/dist/engine/renderers/Indicator/mom.d.ts +2 -1
  114. package/dist/engine/renderers/Indicator/mom.d.ts.map +1 -1
  115. package/dist/engine/renderers/Indicator/mom.js +6 -10
  116. package/dist/engine/renderers/Indicator/mom.js.map +1 -1
  117. package/dist/engine/renderers/Indicator/obv.d.ts +4 -1
  118. package/dist/engine/renderers/Indicator/obv.d.ts.map +1 -1
  119. package/dist/engine/renderers/Indicator/obv.js +14 -8
  120. package/dist/engine/renderers/Indicator/obv.js.map +1 -1
  121. package/dist/engine/renderers/Indicator/parkinson.d.ts +4 -1
  122. package/dist/engine/renderers/Indicator/parkinson.d.ts.map +1 -1
  123. package/dist/engine/renderers/Indicator/parkinson.js +17 -8
  124. package/dist/engine/renderers/Indicator/parkinson.js.map +1 -1
  125. package/dist/engine/renderers/Indicator/pivot.d.ts +2 -0
  126. package/dist/engine/renderers/Indicator/pivot.d.ts.map +1 -1
  127. package/dist/engine/renderers/Indicator/pivot.js +42 -8
  128. package/dist/engine/renderers/Indicator/pivot.js.map +1 -1
  129. package/dist/engine/renderers/Indicator/pvt.d.ts +4 -1
  130. package/dist/engine/renderers/Indicator/pvt.d.ts.map +1 -1
  131. package/dist/engine/renderers/Indicator/pvt.js +14 -8
  132. package/dist/engine/renderers/Indicator/pvt.js.map +1 -1
  133. package/dist/engine/renderers/Indicator/roc.d.ts +4 -1
  134. package/dist/engine/renderers/Indicator/roc.d.ts.map +1 -1
  135. package/dist/engine/renderers/Indicator/roc.js +15 -8
  136. package/dist/engine/renderers/Indicator/roc.js.map +1 -1
  137. package/dist/engine/renderers/Indicator/rsi.d.ts +2 -1
  138. package/dist/engine/renderers/Indicator/rsi.d.ts.map +1 -1
  139. package/dist/engine/renderers/Indicator/rsi.js +9 -10
  140. package/dist/engine/renderers/Indicator/rsi.js.map +1 -1
  141. package/dist/engine/renderers/Indicator/sar.d.ts +4 -1
  142. package/dist/engine/renderers/Indicator/sar.d.ts.map +1 -1
  143. package/dist/engine/renderers/Indicator/sar.js +17 -8
  144. package/dist/engine/renderers/Indicator/sar.js.map +1 -1
  145. package/dist/engine/renderers/Indicator/stoch.d.ts +2 -1
  146. package/dist/engine/renderers/Indicator/stoch.d.ts.map +1 -1
  147. package/dist/engine/renderers/Indicator/stoch.js +8 -10
  148. package/dist/engine/renderers/Indicator/stoch.js.map +1 -1
  149. package/dist/engine/renderers/Indicator/structure.d.ts +4 -1
  150. package/dist/engine/renderers/Indicator/structure.d.ts.map +1 -1
  151. package/dist/engine/renderers/Indicator/structure.js +20 -8
  152. package/dist/engine/renderers/Indicator/structure.js.map +1 -1
  153. package/dist/engine/renderers/Indicator/supertrend.d.ts +4 -1
  154. package/dist/engine/renderers/Indicator/supertrend.d.ts.map +1 -1
  155. package/dist/engine/renderers/Indicator/supertrend.js +17 -8
  156. package/dist/engine/renderers/Indicator/supertrend.js.map +1 -1
  157. package/dist/engine/renderers/Indicator/tema.d.ts +2 -0
  158. package/dist/engine/renderers/Indicator/tema.d.ts.map +1 -1
  159. package/dist/engine/renderers/Indicator/tema.js +18 -8
  160. package/dist/engine/renderers/Indicator/tema.js.map +1 -1
  161. package/dist/engine/renderers/Indicator/trix.d.ts +4 -1
  162. package/dist/engine/renderers/Indicator/trix.d.ts.map +1 -1
  163. package/dist/engine/renderers/Indicator/trix.js +29 -8
  164. package/dist/engine/renderers/Indicator/trix.js.map +1 -1
  165. package/dist/engine/renderers/Indicator/vma.d.ts +4 -1
  166. package/dist/engine/renderers/Indicator/vma.d.ts.map +1 -1
  167. package/dist/engine/renderers/Indicator/vma.js +15 -8
  168. package/dist/engine/renderers/Indicator/vma.js.map +1 -1
  169. package/dist/engine/renderers/Indicator/volumeProfile.d.ts +4 -1
  170. package/dist/engine/renderers/Indicator/volumeProfile.d.ts.map +1 -1
  171. package/dist/engine/renderers/Indicator/volumeProfile.js +27 -8
  172. package/dist/engine/renderers/Indicator/volumeProfile.js.map +1 -1
  173. package/dist/engine/renderers/Indicator/vwap.d.ts +4 -1
  174. package/dist/engine/renderers/Indicator/vwap.d.ts.map +1 -1
  175. package/dist/engine/renderers/Indicator/vwap.js +14 -8
  176. package/dist/engine/renderers/Indicator/vwap.js.map +1 -1
  177. package/dist/engine/renderers/Indicator/wma.d.ts +2 -0
  178. package/dist/engine/renderers/Indicator/wma.d.ts.map +1 -1
  179. package/dist/engine/renderers/Indicator/wma.js +18 -8
  180. package/dist/engine/renderers/Indicator/wma.js.map +1 -1
  181. package/dist/engine/renderers/Indicator/wmsr.d.ts +2 -1
  182. package/dist/engine/renderers/Indicator/wmsr.d.ts.map +1 -1
  183. package/dist/engine/renderers/Indicator/wmsr.js +6 -10
  184. package/dist/engine/renderers/Indicator/wmsr.js.map +1 -1
  185. package/dist/engine/renderers/Indicator/zones.d.ts +2 -0
  186. package/dist/engine/renderers/Indicator/zones.d.ts.map +1 -1
  187. package/dist/engine/renderers/Indicator/zones.js +23 -8
  188. package/dist/engine/renderers/Indicator/zones.js.map +1 -1
  189. package/dist/engine/renderers/paneTitle.d.ts +4 -10
  190. package/dist/engine/renderers/paneTitle.d.ts.map +1 -1
  191. package/dist/engine/renderers/paneTitle.js +28 -6
  192. package/dist/engine/renderers/paneTitle.js.map +1 -1
  193. package/dist/engine/renderers/subVolume.js +0 -3
  194. package/dist/engine/renderers/subVolume.js.map +1 -1
  195. package/dist/version.d.ts +1 -1
  196. package/dist/version.js +1 -1
  197. package/package.json +4 -4
  198. package/src/controllers/__tests__/indicatorSelector.test.ts +4 -3
  199. package/src/controllers/createIndicatorSelectorController.ts +4 -6
  200. package/src/controllers/index.ts +0 -4
  201. package/src/engine/chart.ts +30 -22
  202. package/src/engine/indicators/__tests__/registerBuiltins.test.ts +4 -5
  203. package/src/engine/indicators/indicatorDefinitionRegistry.ts +35 -2
  204. package/src/engine/indicators/indicatorMetadata.ts +39 -2
  205. package/src/engine/indicators/indicatorRuntime.ts +5 -4
  206. package/src/engine/indicators/scheduler.ts +32 -8
  207. package/src/engine/renderers/Indicator/atr.ts +8 -11
  208. package/src/engine/renderers/Indicator/boll.ts +31 -10
  209. package/src/engine/renderers/Indicator/cci.ts +9 -14
  210. package/src/engine/renderers/Indicator/chaikinVol.ts +24 -8
  211. package/src/engine/renderers/Indicator/cmf.ts +23 -8
  212. package/src/engine/renderers/Indicator/dema.ts +27 -9
  213. package/src/engine/renderers/Indicator/donchian.ts +27 -9
  214. package/src/engine/renderers/Indicator/ene.ts +31 -10
  215. package/src/engine/renderers/Indicator/expma.ts +30 -10
  216. package/src/engine/renderers/Indicator/fastk.ts +9 -14
  217. package/src/engine/renderers/Indicator/fib.ts +28 -9
  218. package/src/engine/renderers/Indicator/hma.ts +27 -9
  219. package/src/engine/renderers/Indicator/hv.ts +26 -8
  220. package/src/engine/renderers/Indicator/ichimoku.ts +30 -9
  221. package/src/engine/renderers/Indicator/index.ts +27 -28
  222. package/src/engine/renderers/Indicator/kama.ts +27 -9
  223. package/src/engine/renderers/Indicator/keltner.ts +27 -9
  224. package/src/engine/renderers/Indicator/kst.ts +14 -18
  225. package/src/engine/renderers/Indicator/ma.ts +43 -9
  226. package/src/engine/renderers/Indicator/macd.ts +27 -32
  227. package/src/engine/renderers/Indicator/mainIndicatorLegend.ts +43 -162
  228. package/src/engine/renderers/Indicator/mfi.ts +23 -8
  229. package/src/engine/renderers/Indicator/mom.ts +9 -14
  230. package/src/engine/renderers/Indicator/obv.ts +22 -8
  231. package/src/engine/renderers/Indicator/parkinson.ts +26 -8
  232. package/src/engine/renderers/Indicator/pivot.ts +46 -9
  233. package/src/engine/renderers/Indicator/pvt.ts +22 -8
  234. package/src/engine/renderers/Indicator/roc.ts +24 -8
  235. package/src/engine/renderers/Indicator/rsi.ts +12 -16
  236. package/src/engine/renderers/Indicator/sar.ts +25 -9
  237. package/src/engine/renderers/Indicator/stoch.ts +11 -15
  238. package/src/engine/renderers/Indicator/structure.ts +30 -8
  239. package/src/engine/renderers/Indicator/supertrend.ts +25 -9
  240. package/src/engine/renderers/Indicator/tema.ts +27 -9
  241. package/src/engine/renderers/Indicator/trix.ts +38 -8
  242. package/src/engine/renderers/Indicator/vma.ts +23 -8
  243. package/src/engine/renderers/Indicator/volumeProfile.ts +39 -8
  244. package/src/engine/renderers/Indicator/vwap.ts +22 -8
  245. package/src/engine/renderers/Indicator/wma.ts +27 -9
  246. package/src/engine/renderers/Indicator/wmsr.ts +9 -14
  247. package/src/engine/renderers/Indicator/zones.ts +28 -9
  248. package/src/engine/renderers/__tests__/mainIndicatorLegend.renderer.test.ts +142 -79
  249. package/src/engine/renderers/paneTitle.ts +43 -18
  250. package/src/engine/renderers/subVolume.ts +0 -2
  251. package/src/version.ts +1 -1
  252. package/dist/engine/renderers/Indicator/macdLegend.d.ts +0 -13
  253. package/dist/engine/renderers/Indicator/macdLegend.d.ts.map +0 -1
  254. package/dist/engine/renderers/Indicator/macdLegend.js +0 -116
  255. package/dist/engine/renderers/Indicator/macdLegend.js.map +0 -1
  256. package/dist/engine/renderers/Indicator/subPaneConfig.d.ts +0 -16
  257. package/dist/engine/renderers/Indicator/subPaneConfig.d.ts.map +0 -1
  258. package/dist/engine/renderers/Indicator/subPaneConfig.js +0 -194
  259. package/dist/engine/renderers/Indicator/subPaneConfig.js.map +0 -1
  260. package/src/engine/renderers/Indicator/macdLegend.ts +0 -141
  261. package/src/engine/renderers/Indicator/subPaneConfig.ts +0 -265
@@ -6,7 +6,7 @@ import { resolveThemeColors } from '../../../tokens'
6
6
  import { ENE_STATE_KEY, type ENERenderState } from '../../indicators/eneState'
7
7
  import { Indicator } from '../../indicators/indicatorDefinitionRegistry'
8
8
  import { resolveStateKey } from '../../indicators/indicatorMetadata'
9
- import type { IndicatorPriceRangeComputer, IndicatorRenderStateComposer } from '../../indicators/indicatorMetadata'
9
+ import type { IndicatorPriceRangeComputer, IndicatorRenderStateComposer, GetTitleInfoFn, TitleInfo, TitleValueItem } from '../../indicators/indicatorMetadata'
10
10
  import type { ENESchedulerConfig, IndicatorScheduler } from '../../indicators/scheduler'
11
11
  import { calcENEData } from '../../indicators/calculators'
12
12
 
@@ -94,7 +94,7 @@ function drawENEWithWebGL(
94
94
  * 3. 配置变更通过外部 IndicatorScheduler 处理
95
95
  * 4. 纯绘制函数,无副作用
96
96
  */
97
- function getENEStateKey(host: PluginHost | null): string | null {
97
+ export function getENEStateKey(host: PluginHost | null): string | null {
98
98
  const scheduler = host?.getService<IndicatorScheduler>('indicatorScheduler')
99
99
  if (!scheduler) {
100
100
  console.warn('[ENERenderer] Scheduler not available via service locator')
@@ -289,11 +289,37 @@ export function createENERendererPlugin(): RendererPluginWithHost {
289
289
  }
290
290
  }
291
291
 
292
+ export const getENETitleInfo: GetTitleInfoFn = (
293
+ _data: KLineData[],
294
+ index: number | null,
295
+ _params: Record<string, number | boolean | string>,
296
+ pluginHost: PluginHost,
297
+ _paneId: string,
298
+ ): TitleInfo | null => {
299
+ if (index === null) return null
300
+
301
+ const stateKey = getENEStateKey(pluginHost)
302
+ if (!stateKey) return null
303
+
304
+ const state = pluginHost?.getSharedState<ENERenderState>(stateKey)
305
+ if (!state || state.visibleMin > state.visibleMax) return null
306
+
307
+ const enePoint = state.series[index]
308
+ if (!enePoint) return null
309
+
310
+ const values: TitleValueItem[] = [
311
+ { label: 'UP', value: enePoint.upper, color: '#FF5064' },
312
+ { label: 'MID', value: enePoint.middle, color: '#5A8CFF' },
313
+ { label: 'DN', value: enePoint.lower, color: '#3CC8A0' },
314
+ ]
315
+
316
+ return { name: 'ENE', params: [state.params.period, state.params.deviation], values }
317
+ }
318
+
292
319
  @Indicator({
293
320
  name: 'ene',
294
321
  displayName: 'ENE',
295
322
  category: 'main',
296
- stateKey: ENE_STATE_KEY,
297
323
  defaultPaneId: 'main',
298
324
  mainPane: {
299
325
  rendererName: 'ene',
@@ -301,9 +327,6 @@ export function createENERendererPlugin(): RendererPluginWithHost {
301
327
  computePriceRange: computeENEPriceRange,
302
328
  composeRenderState: composeENERenderState,
303
329
  },
304
- updateConfig: (scheduler, params) => {
305
- (scheduler as IndicatorScheduler).updateIndicatorConfig('ene', params)
306
- },
307
330
  semantic: {
308
331
  apply: (chart, indicator) => {
309
332
  const params = (indicator as { params?: { period?: number; deviation?: number } }).params
@@ -313,10 +336,8 @@ export function createENERendererPlugin(): RendererPluginWithHost {
313
336
  })
314
337
  },
315
338
  },
316
- applyResult: (host, state, _paneId) => {
317
- host.setSharedState(ENE_STATE_KEY, state as any, 'indicator_scheduler')
318
- },
319
- runtime: { configKey:'ene', defaultConfig:{period:10,deviation:11}, computeKey:'calcENEData', compute:(data,c)=>calcENEData(data,c.period,c.deviation) },
339
+ runtime: { defaultConfig:{period:10,deviation:11}, computeKey:'calcENEData', compute:(data,c)=>calcENEData(data,c.period,c.deviation) },
340
+ getTitleInfo: getENETitleInfo,
320
341
  })
321
342
  class ENEDefinition {
322
343
  static rendererFactory = createENERendererPlugin
@@ -6,7 +6,7 @@ import { resolveThemeColors } from '../../../tokens'
6
6
  import { EXPMA_STATE_KEY, type EXPMARenderState } from '../../indicators/expmaState'
7
7
  import { Indicator } from '../../indicators/indicatorDefinitionRegistry'
8
8
  import { resolveStateKey } from '../../indicators/indicatorMetadata'
9
- import type { IndicatorPriceRangeComputer, IndicatorRenderStateComposer } from '../../indicators/indicatorMetadata'
9
+ import type { IndicatorPriceRangeComputer, IndicatorRenderStateComposer, GetTitleInfoFn, TitleInfo, TitleValueItem } from '../../indicators/indicatorMetadata'
10
10
  import type { EXPMASchedulerConfig, IndicatorScheduler } from '../../indicators/scheduler'
11
11
  import { calcEXPMAData } from '../../indicators/calculators'
12
12
 
@@ -34,7 +34,7 @@ function buildEXPMACacheKey(
34
34
  ].join('|')
35
35
  }
36
36
 
37
- function getEXPMAStateKey(host: PluginHost | null): string | null {
37
+ export function getEXPMAStateKey(host: PluginHost | null): string | null {
38
38
  const scheduler = host?.getService<IndicatorScheduler>('indicatorScheduler')
39
39
  if (!scheduler) {
40
40
  console.warn('[EXPMARenderer] Scheduler not available via service locator')
@@ -215,11 +215,36 @@ export function createEXPMARendererPlugin(): RendererPluginWithHost {
215
215
  }
216
216
  }
217
217
 
218
+ export const getEXPMATitleInfo: GetTitleInfoFn = (
219
+ _data: KLineData[],
220
+ index: number | null,
221
+ _params: Record<string, number | boolean | string>,
222
+ pluginHost: PluginHost,
223
+ _paneId: string,
224
+ ): TitleInfo | null => {
225
+ if (index === null) return null
226
+
227
+ const stateKey = getEXPMAStateKey(pluginHost)
228
+ if (!stateKey) return null
229
+
230
+ const state = pluginHost?.getSharedState<EXPMARenderState>(stateKey)
231
+ if (!state || state.visibleMin > state.visibleMax) return null
232
+
233
+ const expmaPoint = state.series[index]
234
+ if (!expmaPoint) return null
235
+
236
+ const values: TitleValueItem[] = [
237
+ { label: 'FAST', value: expmaPoint.fast, color: '#FFAA32' },
238
+ { label: 'SLOW', value: expmaPoint.slow, color: '#5A8CFF' },
239
+ ]
240
+
241
+ return { name: 'EXPMA', params: [state.params.fastPeriod, state.params.slowPeriod], values }
242
+ }
243
+
218
244
  @Indicator({
219
245
  name: 'expma',
220
246
  displayName: 'EXPMA',
221
247
  category: 'main',
222
- stateKey: EXPMA_STATE_KEY,
223
248
  defaultPaneId: 'main',
224
249
  mainPane: {
225
250
  rendererName: 'expma',
@@ -227,9 +252,6 @@ export function createEXPMARendererPlugin(): RendererPluginWithHost {
227
252
  computePriceRange: computeEXPMAPriceRange,
228
253
  composeRenderState: composeEXPMARenderState,
229
254
  },
230
- updateConfig: (scheduler, params) => {
231
- (scheduler as IndicatorScheduler).updateIndicatorConfig('expma', params)
232
- },
233
255
  semantic: {
234
256
  apply: (chart, indicator) => {
235
257
  const params = (indicator as { params?: { fastPeriod?: number; slowPeriod?: number } }).params
@@ -239,10 +261,8 @@ export function createEXPMARendererPlugin(): RendererPluginWithHost {
239
261
  })
240
262
  },
241
263
  },
242
- applyResult: (host, state, _paneId) => {
243
- host.setSharedState(EXPMA_STATE_KEY, state as any, 'indicator_scheduler')
244
- },
245
- runtime: { configKey:'expma', defaultConfig:{fastPeriod:12,slowPeriod:50}, computeKey:'calcEXPMAData', compute:(data,c)=>calcEXPMAData(data,c.fastPeriod,c.slowPeriod) },
264
+ runtime: { defaultConfig:{fastPeriod:12,slowPeriod:50}, computeKey:'calcEXPMAData', compute:(data,c)=>calcEXPMAData(data,c.fastPeriod,c.slowPeriod) },
265
+ getTitleInfo: getEXPMATitleInfo,
246
266
  })
247
267
  class EXPMADefinition {
248
268
  static rendererFactory = createEXPMARendererPlugin
@@ -10,6 +10,7 @@ import { resolveStateKey } from '../../indicators/indicatorMetadata'
10
10
  import type { IndicatorScheduler, FASTKSchedulerConfig } from '../../indicators/scheduler'
11
11
  import { createFastkScaleRendererPlugin } from './scale/fastk_scale'
12
12
  import { calcFASTKData } from '../../indicators/calculators'
13
+ import type { KLineData } from '../../../types/price'
13
14
 
14
15
  type LinePoint = { x: number; y: number }
15
16
 
@@ -281,14 +282,15 @@ function drawFASTKLineWithCanvas2D(
281
282
  * 获取 FASTK 标题信息(供 paneTitle 使用)
282
283
  */
283
284
  export function getFASTKTitleInfo(
284
- index: number,
285
- period: number,
285
+ _data: KLineData[],
286
+ index: number | null,
287
+ params: Record<string, number | boolean | string>,
286
288
  pluginHost: PluginHost,
287
- paneId: string = 'sub_FASTK',
288
- theme: 'light' | 'dark' = 'light',
289
- isAsiaMarket?: boolean
289
+ paneId: string,
290
290
  ): { name: string; params: number[]; values: Array<{ label: string; value: number; color: string }> } | null {
291
- const colors = resolveThemeColors(theme, isAsiaMarket)
291
+ if (index === null) return null
292
+ const period = (params.period as number) ?? 9
293
+ const colors = resolveThemeColors('light')
292
294
  const state = pluginHost.getSharedState<FASTKRenderState>(createFASTKStateKey(paneId))
293
295
  if (!state) return null
294
296
 
@@ -308,18 +310,11 @@ export function getFASTKTitleInfo(
308
310
  name: 'fastk',
309
311
  displayName: 'FASTK',
310
312
  category: 'oscillator',
311
- stateKey: createFASTKStateKey,
312
313
  defaultPaneId: 'sub_FASTK',
313
314
  visibleState: { compose: createFixedRangeSparseVisibleStateComposer('fastk', EMPTY_FASTK_STATE) },
314
315
  scaleRendererFactory: createFastkScaleRendererPlugin,
315
- updateConfig: (scheduler, params, paneId) => {
316
- (scheduler as IndicatorScheduler).updateIndicatorConfig('fastk', params, paneId)
317
- },
318
- applyResult: (host, state, paneId) => {
319
- host.setSharedState(createFASTKStateKey(paneId), state as any, 'indicator_scheduler')
320
- },
316
+ getTitleInfo: getFASTKTitleInfo,
321
317
  runtime: {
322
- configKey: 'fastk',
323
318
  defaultConfig: { period: 9, showFASTK: true },
324
319
  computeKey: 'calcFASTKData',
325
320
  compute: (data, c) => calcFASTKData(data, c.period),
@@ -3,7 +3,7 @@ import { RENDERER_PRIORITY } from '../../../plugin'
3
3
  import type { FibRenderState } from '../../indicators/fibState'
4
4
  import { createFibStateKey, EMPTY_FIB_STATE } from '../../indicators/fibState'
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, FibSchedulerConfig } from '../../indicators/scheduler'
8
8
  import { createExactRangePointVisibleStateComposer } from '../../indicators/visibleStateComposers'
9
9
  import { calcFibData } from '../../indicators/calculators'
@@ -126,23 +126,42 @@ function drawLine(ctx: CanvasRenderingContext2D, pts: Point[], color: string): v
126
126
  ctx.stroke()
127
127
  }
128
128
 
129
+ export const getFibTitleInfo: GetTitleInfoFn = (_data, index, _params, host, paneId) => {
130
+ if (index === null || index < 0) return null
131
+
132
+ const stateKey = createFibStateKey(paneId)
133
+ const state = host?.getSharedState<FibRenderState>(stateKey)
134
+ if (!state) return null
135
+
136
+ const p = state.series[index]
137
+ if (!p) return null
138
+
139
+ const values: TitleValueItem[] = [
140
+ { label: '236', value: p.level236, color: FIB_COLORS.l236 },
141
+ { label: '382', value: p.level382, color: FIB_COLORS.l382 },
142
+ { label: '500', value: p.level500, color: FIB_COLORS.l500 },
143
+ { label: '618', value: p.level618, color: FIB_COLORS.l618 },
144
+ { label: '786', value: p.level786, color: FIB_COLORS.l786 },
145
+ ]
146
+
147
+ return {
148
+ name: 'Fib',
149
+ params: [state.params.period],
150
+ values,
151
+ }
152
+ }
153
+
129
154
  @Indicator({
130
155
  name: 'fib',
131
156
  displayName: 'Fib',
157
+ getTitleInfo: getFibTitleInfo,
132
158
  category: 'main',
133
- stateKey: createFibStateKey,
134
159
  defaultPaneId: 'main',
135
160
  allowMainPane: true,
136
161
  mainPane: { rendererName: 'fib_main', toActiveConfig: (params, active) => ({ ...params, showLevels: active }) },
137
162
  scale: { indicatorKey: 'fib', label: 'Fib', decimals: 4 },
138
163
  visibleState: { compose: createExactRangePointVisibleStateComposer('fib', EMPTY_FIB_STATE, ['low', 'high']) },
139
- updateConfig: (scheduler, params, paneId) => {
140
- (scheduler as IndicatorScheduler).updateIndicatorConfig('fib', params, paneId)
141
- },
142
- applyResult: (host, state, paneId) => {
143
- host.setSharedState(createFibStateKey(paneId), state as any, 'indicator_scheduler')
144
- },
145
- runtime: { configKey:'fib', defaultConfig:{period:50,showLevels:true}, computeKey:'calcFibData', compute:(data,c)=>calcFibData(data,c.period) },
164
+ runtime: { defaultConfig:{period:50,showLevels:true}, computeKey:'calcFibData', compute:(data,c)=>calcFibData(data,c.period) },
146
165
  })
147
166
  class FibDefinition {
148
167
  static rendererFactory = createFibRendererPlugin
@@ -1,9 +1,10 @@
1
1
  import type { RendererPluginWithHost, RenderContext, PluginHost } from '../../../plugin'
2
+ import type { KLineData } from '../../../types/price'
2
3
  import { RENDERER_PRIORITY } from '../../../plugin'
3
4
  import type { HMARenderState } from '../../indicators/hmaState'
4
5
  import { createHMAStateKey, EMPTY_HMA_STATE } from '../../indicators/hmaState'
5
6
  import { Indicator } from '../../indicators/indicatorDefinitionRegistry'
6
- import { resolveStateKey } from '../../indicators/indicatorMetadata'
7
+ import { resolveStateKey, type TitleInfo, type TitleValueItem, type GetTitleInfoFn } from '../../indicators/indicatorMetadata'
7
8
  import { createSparseVisibleStateComposer } from '../../indicators/visibleStateComposers'
8
9
  import type { IndicatorScheduler, HMASchedulerConfig } from '../../indicators/scheduler'
9
10
  import { calcHMAData } from '../../indicators/calculators'
@@ -121,23 +122,40 @@ export function createHMARendererPlugin(options: HMARendererOptions = {}): Rende
121
122
  }
122
123
  }
123
124
 
125
+ export const getHMATitleInfo: GetTitleInfoFn = (
126
+ _data: KLineData[],
127
+ index: number | null,
128
+ _params: Record<string, number | boolean | string>,
129
+ pluginHost: PluginHost,
130
+ paneId: string,
131
+ ): TitleInfo | null => {
132
+ if (index === null) return null
133
+
134
+ const stateKey = createHMAStateKey(paneId)
135
+ const state = pluginHost?.getSharedState<HMARenderState>(stateKey)
136
+ if (!state || state.visibleMin > state.visibleMax) return null
137
+
138
+ const value = state.series[index]
139
+ if (value === undefined) return null
140
+
141
+ return {
142
+ name: 'HMA',
143
+ params: [state.params.period],
144
+ values: [{ label: 'HMA', value, color: '#f43f5e' }],
145
+ }
146
+ }
147
+
124
148
  @Indicator({
125
149
  name: 'hma',
126
150
  displayName: 'HMA',
151
+ getTitleInfo: getHMATitleInfo,
127
152
  category: 'main',
128
- stateKey: createHMAStateKey,
129
153
  defaultPaneId: 'main',
130
154
  allowMainPane: true,
131
155
  mainPane: { rendererName: 'hma_main', toActiveConfig: (params, active) => ({ ...params, showHMA: active }) },
132
156
  visibleState: { compose: createSparseVisibleStateComposer('hma', EMPTY_HMA_STATE) },
133
157
  scale: { indicatorKey: 'hma', label: 'HMA', decimals: 2 },
134
- updateConfig: (scheduler, params, paneId) => {
135
- (scheduler as IndicatorScheduler).updateIndicatorConfig('hma', params, paneId)
136
- },
137
- applyResult: (host, state, paneId) => {
138
- host.setSharedState(createHMAStateKey(paneId), state as any, 'indicator_scheduler')
139
- },
140
- runtime: { configKey:'hma', defaultConfig:{period:14,showHMA:true}, computeKey:'calcHMAData', compute:(data,c)=>calcHMAData(data,c.period) },
158
+ runtime: { defaultConfig:{period:14,showHMA:true}, computeKey:'calcHMAData', compute:(data,c)=>calcHMAData(data,c.period) },
141
159
  })
142
160
  class HMADefinition {
143
161
  static rendererFactory = createHMARendererPlugin
@@ -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 { HVRenderState } from '../../indicators/hvState'
4
5
  import { createHVStateKey } from '../../indicators/hvState'
5
6
  import { EMPTY_HV_STATE } from '../../indicators/hvState'
@@ -8,6 +9,8 @@ import { Indicator } from '../../indicators/indicatorDefinitionRegistry'
8
9
  import { resolveStateKey } from '../../indicators/indicatorMetadata'
9
10
  import type { IndicatorScheduler, HVSchedulerConfig } from '../../indicators/scheduler'
10
11
  import { calcHVData } from '../../indicators/calculators'
12
+ import type { TitleInfo } from '../../indicators/indicatorMetadata'
13
+ import type { KLineData } from '../../../types/price'
11
14
 
12
15
  const HV_COLOR = '#7c3aed'
13
16
 
@@ -111,21 +114,36 @@ export function createHVRendererPlugin(options: { paneId?: string } = {}): Rende
111
114
  }
112
115
  }
113
116
 
117
+ export function getHVTitleInfo(
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<HVRenderState>(createHVStateKey(paneId))
128
+ const value = state?.series[index]
129
+ if (value === undefined) return null
130
+
131
+ return {
132
+ name: 'HV',
133
+ params: [period, annualizationFactor],
134
+ values: [{ label: 'HV', value, color: HV_COLOR }],
135
+ }
136
+ }
137
+
114
138
  @Indicator({
115
139
  name: 'hv',
116
140
  displayName: 'HV',
117
141
  category: 'oscillator',
118
- stateKey: createHVStateKey,
119
142
  defaultPaneId: 'sub_HV',
120
143
  scale: { indicatorKey: 'hv', label: 'HV', decimals: 2 },
121
- updateConfig: (scheduler, params, paneId) => {
122
- (scheduler as IndicatorScheduler).updateIndicatorConfig('hv', params, paneId)
123
- },
144
+ getTitleInfo: getHVTitleInfo,
124
145
  visibleState: { compose: createNonNegativeSparseVisibleStateComposer('hv', EMPTY_HV_STATE) },
125
- applyResult: (host, state, paneId) => {
126
- host.setSharedState(createHVStateKey(paneId), state as any, 'indicator_scheduler')
127
- },
128
- runtime: { configKey:'hv', defaultConfig:{period:20,annualizationFactor:252,showHV:true}, computeKey:'calcHVData', compute:(data,c)=>calcHVData(data,c.period,c.annualizationFactor) },
146
+ runtime: { defaultConfig:{period:20,annualizationFactor:252,showHV:true}, computeKey:'calcHVData', compute:(data,c)=>calcHVData(data,c.period,c.annualizationFactor) },
129
147
  })
130
148
  class HVIndicatorDefinition {
131
149
  static rendererFactory = createHVRendererPlugin
@@ -1,9 +1,10 @@
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 { IchimokuRenderState } from '../../indicators/ichimokuState'
4
5
  import { createIchimokuStateKey, EMPTY_ICHIMOKU_STATE } from '../../indicators/ichimokuState'
5
6
  import { Indicator } from '../../indicators/indicatorDefinitionRegistry'
6
- import { resolveStateKey } from '../../indicators/indicatorMetadata'
7
+ import { resolveStateKey, type TitleInfo, type TitleValueItem, type GetTitleInfoFn } from '../../indicators/indicatorMetadata'
7
8
  import type { IndicatorScheduler, IchimokuSchedulerConfig } from '../../indicators/scheduler'
8
9
  import { calcIchimokuData } from '../../indicators/calculators'
9
10
  import { createValuePointVisibleStateComposer } from '../../indicators/visibleStateComposers'
@@ -167,23 +168,43 @@ function fillCloud(
167
168
  }
168
169
  }
169
170
 
171
+ export function getIchimokuTitleInfo(
172
+ _data: KLineData[],
173
+ index: number | null,
174
+ params: Record<string, number | boolean | string>,
175
+ host: PluginHost,
176
+ paneId: string,
177
+ ): TitleInfo | null {
178
+ if (index === null) return null
179
+ const state = host.getSharedState<IchimokuRenderState>(createIchimokuStateKey(paneId))
180
+ const p = state?.series[index]
181
+ if (!p) return null
182
+
183
+ const values: TitleValueItem[] = []
184
+ if (p.tenkan !== undefined) values.push({ label: 'Tenkan', value: p.tenkan, color: '#dc2626' })
185
+ if (p.kijun !== undefined) values.push({ label: 'Kijun', value: p.kijun, color: '#2563eb' })
186
+ if (p.spanA !== undefined) values.push({ label: 'SpanA', value: p.spanA, color: '#16a34a' })
187
+ if (p.spanB !== undefined) values.push({ label: 'SpanB', value: p.spanB, color: '#dc2626' })
188
+ if (p.chikou !== undefined) values.push({ label: 'Chikou', value: p.chikou, color: '#7c3aed' })
189
+
190
+ return {
191
+ name: 'Ichimoku',
192
+ params: [(params.tenkanPeriod as number) ?? 9, (params.kijunPeriod as number) ?? 26, (params.spanBPeriod as number) ?? 52, (params.displacement as number) ?? 26],
193
+ values,
194
+ }
195
+ }
196
+
170
197
  @Indicator({
171
198
  name: 'ichimoku',
172
199
  displayName: 'Ichimoku',
200
+ getTitleInfo: getIchimokuTitleInfo,
173
201
  category: 'main',
174
- stateKey: createIchimokuStateKey,
175
202
  defaultPaneId: 'main',
176
203
  allowMainPane: true,
177
204
  mainPane: { rendererName: 'ichimoku_main', toActiveConfig: (params, active) => ({ ...params, showTenkan: active, showKijun: active, showSpanA: active, showSpanB: active, showChikou: active, showCloud: active }) },
178
205
  scale: { indicatorKey: 'ichimoku', label: 'Ichimoku', decimals: 2 },
179
206
  visibleState: { compose: createValuePointVisibleStateComposer('ichimoku', EMPTY_ICHIMOKU_STATE, ['tenkan', 'kijun', 'spanA', 'spanB', 'chikou']) },
180
- updateConfig: (scheduler, params, paneId) => {
181
- (scheduler as IndicatorScheduler).updateIndicatorConfig('ichimoku', params, paneId)
182
- },
183
- applyResult: (host, state, paneId) => {
184
- host.setSharedState(createIchimokuStateKey(paneId), state as any, 'indicator_scheduler')
185
- },
186
- runtime: { configKey:'ichimoku', defaultConfig:{tenkanPeriod:9,kijunPeriod:26,spanBPeriod:52,displacement:26,showTenkan:true,showKijun:true,showSpanA:true,showSpanB:true,showCloud:true,showChikou:true}, computeKey:'calcIchimokuData', compute:(data,c)=>calcIchimokuData(data,c.tenkanPeriod,c.kijunPeriod,c.spanBPeriod,c.displacement) },
207
+ runtime: { defaultConfig:{tenkanPeriod:9,kijunPeriod:26,spanBPeriod:52,displacement:26,showTenkan:true,showKijun:true,showSpanA:true,showSpanB:true,showCloud:true,showChikou:true}, computeKey:'calcIchimokuData', compute:(data,c)=>calcIchimokuData(data,c.tenkanPeriod,c.kijunPeriod,c.spanBPeriod,c.displacement) },
187
208
  })
188
209
  class IchimokuDefinition {
189
210
  static rendererFactory = createIchimokuRendererPlugin
@@ -6,7 +6,7 @@ import type { RendererPlugin } from '../../../plugin'
6
6
  import type { IndicatorMetadata } from '../../indicators/indicatorMetadata'
7
7
 
8
8
  // MA 均线
9
- export { createMARendererPlugin, type MAFlags } from './ma'
9
+ export { createMARendererPlugin, type MAFlags, getMATitleInfo } from './ma'
10
10
 
11
11
  // BOLL 布林带
12
12
  export { createBOLLRendererPlugin } from './boll'
@@ -22,7 +22,6 @@ export { createMainIndicatorLegendRendererPlugin } from './mainIndicatorLegend'
22
22
 
23
23
  // MACD
24
24
  export { createMACDRendererPlugin, calcMACDAtIndex, type MACDConfig, type MACDRendererOptions, getMACDTitleInfo } from './macd'
25
- export { createMACDLegendRendererPlugin, type MACDLegendOptions } from './macdLegend'
26
25
 
27
26
  // RSI 相对强弱指标
28
27
  export { createRSIRendererPlugin, type RSIRendererOptions, getRSITitleInfo } from './rsi'
@@ -49,57 +48,57 @@ export { createFASTKRendererPlugin, type FASTKRendererOptions, getFASTKTitleInfo
49
48
  export { createATRRendererPlugin, type ATRRendererOptions, getATRTitleInfo } from './atr'
50
49
 
51
50
  // WMA 加权移动平均
52
- export { createWMARendererPlugin } from './wma'
51
+ export { createWMARendererPlugin, getWMATitleInfo } from './wma'
53
52
  // DEMA 双指数移动平均
54
- export { createDEMARendererPlugin } from './dema'
53
+ export { createDEMARendererPlugin, getDEMATitleInfo } from './dema'
55
54
  // TEMA 三指数移动平均
56
- export { createTEMARendererPlugin } from './tema'
55
+ export { createTEMARendererPlugin, getTEMATitleInfo } from './tema'
57
56
  // HMA 赫尔移动平均
58
- export { createHMARendererPlugin } from './hma'
57
+ export { createHMARendererPlugin, getHMATitleInfo } from './hma'
59
58
  // KAMA 考夫曼自适应移动平均
60
- export { createKAMARendererPlugin } from './kama'
59
+ export { createKAMARendererPlugin, getKAMATitleInfo } from './kama'
61
60
  // SAR 抛物线转向
62
- export { createSARRendererPlugin } from './sar'
61
+ export { createSARRendererPlugin, getSARTitleInfo } from './sar'
63
62
  // SuperTrend 超级趋势
64
- export { createSuperTrendRendererPlugin } from './supertrend'
63
+ export { createSuperTrendRendererPlugin, getSuperTrendTitleInfo } from './supertrend'
65
64
  // Keltner 肯特纳通道
66
- export { createKeltnerRendererPlugin } from './keltner'
65
+ export { createKeltnerRendererPlugin, getKeltnerTitleInfo } from './keltner'
67
66
  // Donchian 唐奇安通道
68
- export { createDonchianRendererPlugin } from './donchian'
67
+ export { createDonchianRendererPlugin, getDonchianTitleInfo } from './donchian'
69
68
  // Ichimoku 一目均衡表
70
- export { createIchimokuRendererPlugin } from './ichimoku'
69
+ export { createIchimokuRendererPlugin, getIchimokuTitleInfo } from './ichimoku'
71
70
  // ROC 变化率
72
- export { createROCRendererPlugin } from './roc'
71
+ export { createROCRendererPlugin, getROCTitleInfo } from './roc'
73
72
  // TRIX 三重指数平滑平均
74
- export { createTRIXRendererPlugin } from './trix'
73
+ export { createTRIXRendererPlugin, getTRIXTitleInfo } from './trix'
75
74
  // HV 历史波动率
76
- export { createHVRendererPlugin } from './hv'
75
+ export { createHVRendererPlugin, getHVTitleInfo } from './hv'
77
76
  // Parkinson 帕金森波动率
78
- export { createParkinsonRendererPlugin } from './parkinson'
77
+ export { createParkinsonRendererPlugin, getParkinsonTitleInfo } from './parkinson'
79
78
  // Chaikin Vol 蔡金波动率
80
- export { createChaikinVolRendererPlugin } from './chaikinVol'
79
+ export { createChaikinVolRendererPlugin, getChaikinVolTitleInfo } from './chaikinVol'
81
80
  // VMA 成交量移动平均
82
- export { createVMARendererPlugin } from './vma'
81
+ export { createVMARendererPlugin, getVMATitleInfo } from './vma'
83
82
  // OBV 能量潮
84
- export { createOBVRendererPlugin } from './obv'
83
+ export { createOBVRendererPlugin, getOBVTitleInfo } from './obv'
85
84
  // PVT 价量趋势
86
- export { createPVTRendererPlugin } from './pvt'
85
+ export { createPVTRendererPlugin, getPVTTitleInfo } from './pvt'
87
86
  // VWAP 成交量加权均价
88
- export { createVWAPRendererPlugin } from './vwap'
87
+ export { createVWAPRendererPlugin, getVWAPTitleInfo } from './vwap'
89
88
  // CMF 蔡金资金流
90
- export { createCMFRendererPlugin } from './cmf'
89
+ export { createCMFRendererPlugin, getCMFTitleInfo } from './cmf'
91
90
  // MFI 资金流量指数
92
- export { createMFIRendererPlugin } from './mfi'
91
+ export { createMFIRendererPlugin, getMFITitleInfo } from './mfi'
93
92
  // Pivot Points 枢轴点
94
- export { createPivotRendererPlugin } from './pivot'
93
+ export { createPivotRendererPlugin, getPivotTitleInfo } from './pivot'
95
94
  // Fibonacci 斐波那契
96
- export { createFibRendererPlugin } from './fib'
95
+ export { createFibRendererPlugin, getFibTitleInfo } from './fib'
97
96
  // SMC Structure 结构
98
- export { createStructureRendererPlugin } from './structure'
97
+ export { createStructureRendererPlugin, getStructureTitleInfo } from './structure'
99
98
  // SMC Zones 区域
100
- export { createZonesRendererPlugin } from './zones'
99
+ export { createZonesRendererPlugin, getZonesTitleInfo } from './zones'
101
100
  // Volume Profile 成交量分布
102
- export { createVolumeProfileRendererPlugin } from './volumeProfile'
101
+ export { createVolumeProfileRendererPlugin, getVolumeProfileTitleInfo } from './volumeProfile'
103
102
 
104
103
  /**
105
104
  * 副图指标类型
@@ -1,9 +1,10 @@
1
1
  import type { RendererPluginWithHost, RenderContext, PluginHost } from '../../../plugin'
2
+ import type { KLineData } from '../../../types/price'
2
3
  import { RENDERER_PRIORITY } from '../../../plugin'
3
4
  import type { KAMARenderState } from '../../indicators/kamaState'
4
5
  import { createKAMAStateKey, EMPTY_KAMA_STATE } from '../../indicators/kamaState'
5
6
  import { Indicator } from '../../indicators/indicatorDefinitionRegistry'
6
- import { resolveStateKey } from '../../indicators/indicatorMetadata'
7
+ import { resolveStateKey, type TitleInfo, type TitleValueItem, type GetTitleInfoFn } from '../../indicators/indicatorMetadata'
7
8
  import { createSparseVisibleStateComposer } from '../../indicators/visibleStateComposers'
8
9
  import type { IndicatorScheduler, KAMASchedulerConfig } from '../../indicators/scheduler'
9
10
  import { calcKAMAData } from '../../indicators/calculators'
@@ -121,23 +122,40 @@ export function createKAMARendererPlugin(options: KAMARendererOptions = {}): Ren
121
122
  }
122
123
  }
123
124
 
125
+ export const getKAMATitleInfo: GetTitleInfoFn = (
126
+ _data: KLineData[],
127
+ index: number | null,
128
+ _params: Record<string, number | boolean | string>,
129
+ pluginHost: PluginHost,
130
+ paneId: string,
131
+ ): TitleInfo | null => {
132
+ if (index === null) return null
133
+
134
+ const stateKey = createKAMAStateKey(paneId)
135
+ const state = pluginHost?.getSharedState<KAMARenderState>(stateKey)
136
+ if (!state || state.visibleMin > state.visibleMax) return null
137
+
138
+ const value = state.series[index]
139
+ if (value === undefined) return null
140
+
141
+ return {
142
+ name: 'KAMA',
143
+ params: [state.params.period, state.params.fastPeriod, state.params.slowPeriod],
144
+ values: [{ label: 'KAMA', value, color: '#0ea5e9' }],
145
+ }
146
+ }
147
+
124
148
  @Indicator({
125
149
  name: 'kama',
126
150
  displayName: 'KAMA',
151
+ getTitleInfo: getKAMATitleInfo,
127
152
  category: 'main',
128
- stateKey: createKAMAStateKey,
129
153
  defaultPaneId: 'main',
130
154
  allowMainPane: true,
131
155
  mainPane: { rendererName: 'kama_main', toActiveConfig: (params, active) => ({ ...params, showKAMA: active }) },
132
156
  visibleState: { compose: createSparseVisibleStateComposer('kama', EMPTY_KAMA_STATE) },
133
157
  scale: { indicatorKey: 'kama', label: 'KAMA', decimals: 2 },
134
- updateConfig: (scheduler, params, paneId) => {
135
- (scheduler as IndicatorScheduler).updateIndicatorConfig('kama', params, paneId)
136
- },
137
- applyResult: (host, state, paneId) => {
138
- host.setSharedState(createKAMAStateKey(paneId), state as any, 'indicator_scheduler')
139
- },
140
- runtime: { configKey:'kama', defaultConfig:{period:10,fastPeriod:2,slowPeriod:30,showKAMA:true}, computeKey:'calcKAMAData', compute:(data,c)=>calcKAMAData(data,c.period,c.fastPeriod,c.slowPeriod) },
158
+ runtime: { defaultConfig:{period:10,fastPeriod:2,slowPeriod:30,showKAMA:true}, computeKey:'calcKAMAData', compute:(data,c)=>calcKAMAData(data,c.period,c.fastPeriod,c.slowPeriod) },
141
159
  })
142
160
  class KAMADefinition {
143
161
  static rendererFactory = createKAMARendererPlugin