@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
@@ -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 { SuperTrendRenderState } from '../../indicators/supertrendState'
4
5
  import { createSuperTrendStateKey, EMPTY_SUPERTREND_STATE } from '../../indicators/supertrendState'
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, SuperTrendSchedulerConfig } from '../../indicators/scheduler'
9
+ import { calcSuperTrendData } from '../../indicators/calculators'
8
10
  import { createValuePointVisibleStateComposer } from '../../indicators/visibleStateComposers'
9
11
 
10
12
  const ST_UP_COLOR = '#22c55e'
@@ -99,23 +101,38 @@ export function createSuperTrendRendererPlugin(options: SuperTrendRendererOption
99
101
  }
100
102
  }
101
103
 
104
+ export function getSuperTrendTitleInfo(
105
+ _data: KLineData[],
106
+ index: number | null,
107
+ params: Record<string, number | boolean | string>,
108
+ host: PluginHost,
109
+ paneId: string,
110
+ ): TitleInfo | null {
111
+ if (index === null) return null
112
+ const state = host.getSharedState<SuperTrendRenderState>(createSuperTrendStateKey(paneId))
113
+ const p = state?.series[index]
114
+ if (!p) return null
115
+
116
+ return {
117
+ name: 'SuperTrend',
118
+ params: [(params.atrPeriod as number) ?? 10, (params.multiplier as number) ?? 3],
119
+ values: [
120
+ { label: p.trend === 'up' ? 'Up' : 'Down', value: p.value, color: p.trend === 'up' ? '#22c55e' : '#ef4444' },
121
+ ],
122
+ }
123
+ }
124
+
102
125
  @Indicator({
103
126
  name: 'supertrend',
104
127
  displayName: 'SuperTrend',
128
+ getTitleInfo: getSuperTrendTitleInfo,
105
129
  category: 'oscillator',
106
- stateKey: createSuperTrendStateKey,
107
130
  defaultPaneId: 'sub_SuperTrend',
108
- paneIdField: 'supertrendPaneId',
109
131
  allowMainPane: true,
110
132
  mainPane: { rendererName: 'supertrend_main', toActiveConfig: (params, active) => ({ ...params, showSuperTrend: active }) },
111
133
  scale: { indicatorKey: 'supertrend', label: 'SuperTrend', decimals: 2 },
112
134
  visibleState: { compose: createValuePointVisibleStateComposer('supertrend', EMPTY_SUPERTREND_STATE, ['value']) },
113
- updateConfig: (scheduler, params, paneId) => {
114
- (scheduler as IndicatorScheduler).updateSuperTrendConfig(params as Partial<SuperTrendSchedulerConfig>, paneId)
115
- },
116
- applyResult: (host, state, paneId) => {
117
- host.setSharedState(createSuperTrendStateKey(paneId), state as any, 'indicator_scheduler')
118
- },
135
+ runtime: { defaultConfig:{atrPeriod:10,multiplier:3,showSuperTrend:true}, computeKey:'calcSuperTrendData', compute:(data,c)=>calcSuperTrendData(data,c.atrPeriod,c.multiplier) },
119
136
  })
120
137
  class SuperTrendIndicatorDefinition {
121
138
  static rendererFactory = createSuperTrendRendererPlugin
@@ -1,11 +1,13 @@
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 { TEMARenderState } from '../../indicators/temaState'
4
5
  import { createTEMAStateKey, EMPTY_TEMA_STATE } from '../../indicators/temaState'
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, TEMASchedulerConfig } from '../../indicators/scheduler'
10
+ import { calcTEMAData } from '../../indicators/calculators'
9
11
 
10
12
  const TEMA_COLOR = '#d946ef'
11
13
 
@@ -120,23 +122,40 @@ export function createTEMARendererPlugin(options: TEMARendererOptions = {}): Ren
120
122
  }
121
123
  }
122
124
 
125
+ export const getTEMATitleInfo: 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 = createTEMAStateKey(paneId)
135
+ const state = pluginHost?.getSharedState<TEMARenderState>(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: 'TEMA',
143
+ params: [state.params.period],
144
+ values: [{ label: 'TEMA', value, color: '#d946ef' }],
145
+ }
146
+ }
147
+
123
148
  @Indicator({
124
149
  name: 'tema',
125
150
  displayName: 'TEMA',
151
+ getTitleInfo: getTEMATitleInfo,
126
152
  category: 'main',
127
- stateKey: createTEMAStateKey,
128
153
  defaultPaneId: 'main',
129
- paneIdField: 'temaPaneId',
130
154
  allowMainPane: true,
131
155
  mainPane: { rendererName: 'tema_main', toActiveConfig: (params, active) => ({ ...params, showTEMA: active }) },
132
156
  visibleState: { compose: createSparseVisibleStateComposer('tema', EMPTY_TEMA_STATE) },
133
157
  scale: { indicatorKey: 'tema', label: 'TEMA', decimals: 2 },
134
- updateConfig: (scheduler, params, paneId) => {
135
- (scheduler as IndicatorScheduler).updateTEMAConfig(params as Partial<TEMASchedulerConfig>, paneId)
136
- },
137
- applyResult: (host, state, paneId) => {
138
- host.setSharedState(createTEMAStateKey(paneId), state as any, 'indicator_scheduler')
139
- },
158
+ runtime: { defaultConfig:{period:14,showTEMA:true}, computeKey:'calcTEMAData', compute:(data,c)=>calcTEMAData(data,c.period) },
140
159
  })
141
160
  class TEMADefinition {
142
161
  static rendererFactory = createTEMARendererPlugin
@@ -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 { TRIXRenderState } from '../../indicators/trixState'
4
5
  import { createTRIXStateKey } from '../../indicators/trixState'
5
6
  import { EMPTY_TRIX_STATE } from '../../indicators/trixState'
@@ -7,6 +8,9 @@ import { createDualSparseVisibleStateComposer } from '../../indicators/visibleSt
7
8
  import { Indicator } from '../../indicators/indicatorDefinitionRegistry'
8
9
  import { resolveStateKey } from '../../indicators/indicatorMetadata'
9
10
  import type { IndicatorScheduler, TRIXSchedulerConfig } from '../../indicators/scheduler'
11
+ import { calcTRIXData } from '../../indicators/calculators'
12
+ import type { KLineData } from '../../../types/price'
13
+ import type { TitleInfo } from '../../indicators/indicatorMetadata'
10
14
 
11
15
  const TRIX_COLOR = '#e11d48'
12
16
  const SIGNAL_COLOR = '#f59e0b'
@@ -144,21 +148,48 @@ function drawLine(ctx: CanvasRenderingContext2D, pts: Point[], color: string): v
144
148
  ctx.stroke()
145
149
  }
146
150
 
151
+ export function getTRIXTitleInfo(
152
+ _data: KLineData[],
153
+ index: number | null,
154
+ params: Record<string, number | boolean | string>,
155
+ pluginHost: PluginHost,
156
+ paneId: string,
157
+ ): TitleInfo | null {
158
+ if (index === null) return null
159
+ const period = (params.period as number) ?? 15
160
+ const signalPeriod = (params.signalPeriod as number) ?? 9
161
+ const state = pluginHost.getSharedState<TRIXRenderState>(createTRIXStateKey(paneId))
162
+ if (!state) return null
163
+
164
+ const values: Array<{ label: string; value: number; color: string }> = []
165
+
166
+ if (state.params.showTRIX) {
167
+ const v = state.series[index]
168
+ if (v !== undefined) values.push({ label: 'TRIX', value: v, color: TRIX_COLOR })
169
+ }
170
+ if (state.params.showSignal) {
171
+ const v = state.signalSeries[index]
172
+ if (v !== undefined) values.push({ label: 'Signal', value: v, color: SIGNAL_COLOR })
173
+ }
174
+
175
+ if (values.length === 0) return null
176
+
177
+ return {
178
+ name: 'TRIX',
179
+ params: [period, signalPeriod],
180
+ values,
181
+ }
182
+ }
183
+
147
184
  @Indicator({
148
185
  name: 'trix',
149
186
  displayName: 'TRIX',
150
187
  category: 'oscillator',
151
- stateKey: createTRIXStateKey,
152
188
  defaultPaneId: 'sub_TRIX',
153
- paneIdField: 'trixPaneId',
154
189
  scale: { indicatorKey: 'trix', label: 'TRIX', decimals: 6 },
155
- updateConfig: (scheduler, params, paneId) => {
156
- (scheduler as IndicatorScheduler).updateTRIXConfig(params as Partial<TRIXSchedulerConfig>, paneId)
157
- },
158
190
  visibleState: { compose: createDualSparseVisibleStateComposer('trix', EMPTY_TRIX_STATE) },
159
- applyResult: (host, state, paneId) => {
160
- host.setSharedState(createTRIXStateKey(paneId), state as any, 'indicator_scheduler')
161
- },
191
+ getTitleInfo: getTRIXTitleInfo,
192
+ runtime: { defaultConfig:{period:15,signalPeriod:9,showTRIX:true,showSignal:true}, computeKey:'calcTRIXData', compute:(data,c)=>calcTRIXData(data,c.period,c.signalPeriod) },
162
193
  })
163
194
  class TRIXIndicatorDefinition {
164
195
  static rendererFactory = createTRIXRendererPlugin
@@ -3,10 +3,13 @@ import { RENDERER_PRIORITY } from '../../../plugin'
3
3
  import type { VMARenderState } from '../../indicators/vmaState'
4
4
  import { createVMAStateKey } from '../../indicators/vmaState'
5
5
  import { EMPTY_VMA_STATE } from '../../indicators/vmaState'
6
+ import type { TitleInfo } from '../../indicators/indicatorMetadata'
7
+ import type { KLineData } from '../../../types/price'
6
8
  import { createNonNegativeSparseVisibleStateComposer } from '../../indicators/visibleStateComposers'
7
9
  import { Indicator } from '../../indicators/indicatorDefinitionRegistry'
8
10
  import { resolveStateKey } from '../../indicators/indicatorMetadata'
9
11
  import type { IndicatorScheduler, VMASchedulerConfig } from '../../indicators/scheduler'
12
+ import { calcVMAData } from '../../indicators/calculators'
10
13
 
11
14
  const VMA_COLOR = '#0ea5e9'
12
15
 
@@ -110,20 +113,38 @@ export function createVMARendererPlugin(options: { paneId?: string } = {}): Rend
110
113
  }
111
114
  }
112
115
 
116
+ export function getVMATitleInfo(
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 period = (params.period as number) ?? 5
125
+ const state = host.getSharedState<VMARenderState>(createVMAStateKey(paneId))
126
+ const value = state?.series[index]
127
+ if (value === undefined) return null
128
+
129
+ return {
130
+ name: 'VMA',
131
+ params: [period],
132
+ values: [{ label: 'VMA', value, color: VMA_COLOR }],
133
+ }
134
+ }
135
+
113
136
  @Indicator({
114
137
  name: 'vma',
115
138
  displayName: 'VMA',
116
139
  category: 'volume',
117
- stateKey: createVMAStateKey,
118
140
  defaultPaneId: 'sub_VMA',
119
- paneIdField: 'vmaPaneId',
120
141
  scale: { indicatorKey: 'vma', label: 'VMA', decimals: 0 },
121
- updateConfig: (scheduler, params, paneId) => {
122
- (scheduler as IndicatorScheduler).updateVMAConfig(params as Partial<VMASchedulerConfig>, paneId)
123
- },
142
+ getTitleInfo: getVMATitleInfo,
124
143
  visibleState: { compose: createNonNegativeSparseVisibleStateComposer('vma', EMPTY_VMA_STATE) },
125
- applyResult: (host, state, paneId) => {
126
- host.setSharedState(createVMAStateKey(paneId), state as any, 'indicator_scheduler')
144
+ runtime: {
145
+ defaultConfig: { period: 5, showVMA: true },
146
+ computeKey: 'calcVMAData',
147
+ compute: (data, c) => calcVMAData(data, c.period),
127
148
  },
128
149
  })
129
150
  class VMAIndicatorDefinition {
@@ -6,6 +6,10 @@ import { Indicator } from '../../indicators/indicatorDefinitionRegistry'
6
6
  import { createVolumeProfileVisibleStateComposer } from '../../indicators/visibleStateComposers'
7
7
  import { resolveStateKey } from '../../indicators/indicatorMetadata'
8
8
  import type { IndicatorScheduler, VolumeProfileSchedulerConfig } from '../../indicators/scheduler'
9
+ import { calcVolumeProfileData } from '../../indicators/calculators'
10
+ import type { TitleInfo } from '../../indicators/indicatorMetadata'
11
+ import type { KLineData } from '../../../types/price'
12
+ import { resolveThemeColors } from '../../../tokens'
9
13
 
10
14
  const BAR_FILL = 'rgba(99, 102, 241, 0.35)'
11
15
  const POC_COLOR = '#f59e0b'
@@ -110,21 +114,49 @@ export function createVolumeProfileRendererPlugin(options: { paneId?: string } =
110
114
  }
111
115
  }
112
116
 
117
+ const VP_POC_COLOR = '#8b5cf6'
118
+ const VP_VAH_COLOR = '#6366f1'
119
+ const VP_VAL_COLOR = '#818cf8'
120
+
121
+ export function getVolumeProfileTitleInfo(
122
+ _data: KLineData[],
123
+ index: number | null,
124
+ params: Record<string, number | boolean | string>,
125
+ host: PluginHost,
126
+ paneId: string,
127
+ ): TitleInfo | null {
128
+ if (index === null) return null
129
+ const bins = (params.bins as number) ?? 24
130
+ const state = host.getSharedState<VolumeProfileRenderState>(createVolumeProfileStateKey(paneId))
131
+ const vp = state?.series
132
+
133
+ const values: Array<{ label: string; value: number; color: string }> = []
134
+ if (vp && vp.bins.length > 0) {
135
+ if (state.params.showPOC) {
136
+ values.push({ label: 'POC', value: vp.poc, color: VP_POC_COLOR })
137
+ }
138
+ if (state.params.showValueArea) {
139
+ values.push({ label: 'VAH', value: vp.vah, color: VP_VAH_COLOR })
140
+ values.push({ label: 'VAL', value: vp.val, color: VP_VAL_COLOR })
141
+ }
142
+ }
143
+
144
+ return {
145
+ name: 'VP',
146
+ params: [bins],
147
+ values,
148
+ }
149
+ }
150
+
113
151
  @Indicator({
114
152
  name: 'volumeProfile',
115
153
  displayName: 'VP',
116
154
  category: 'volume',
117
- stateKey: createVolumeProfileStateKey,
118
155
  defaultPaneId: 'sub_VolumeProfile',
119
- paneIdField: 'volumeProfilePaneId',
120
156
  scale: { indicatorKey: 'volumeProfile', label: 'VP', decimals: 0 },
157
+ getTitleInfo: getVolumeProfileTitleInfo,
121
158
  visibleState: { compose: createVolumeProfileVisibleStateComposer('volumeProfile', EMPTY_VOLUME_PROFILE_STATE) },
122
- updateConfig: (scheduler, params, paneId) => {
123
- (scheduler as IndicatorScheduler).updateVolumeProfileConfig(params as Partial<VolumeProfileSchedulerConfig>, paneId)
124
- },
125
- applyResult: (host, state, paneId) => {
126
- host.setSharedState(createVolumeProfileStateKey(paneId), state as any, 'indicator_scheduler')
127
- },
159
+ runtime: { defaultConfig:{bins:24,lookback:100,valueAreaPercent:70,showPOC:true,showValueArea:true}, computeKey:'calcVolumeProfileData', compute:(data,c)=>calcVolumeProfileData(data,c.bins,c.lookback,c.valueAreaPercent) },
128
160
  })
129
161
  class VolumeProfileIndicatorDefinition {
130
162
  static rendererFactory = createVolumeProfileRendererPlugin
@@ -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, VWAPSchedulerConfig } from '../../indicators/scheduler'
9
+ import { calcVWAPData } from '../../indicators/calculators'
10
+ import type { TitleInfo } from '../../indicators/indicatorMetadata'
11
+ import type { KLineData } from '../../../types/price'
9
12
 
10
13
  const VWAP_COLOR = '#ec4899'
11
14
 
@@ -108,20 +111,37 @@ export function createVWAPRendererPlugin(options: { paneId?: string } = {}): Ren
108
111
  }
109
112
  }
110
113
 
114
+ export function getVWAPTitleInfo(
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<VWAPRenderState>(createVWAPStateKey(paneId))
123
+ const value = state?.series[index]
124
+ if (value === undefined) return null
125
+
126
+ return {
127
+ name: 'VWAP',
128
+ params: [],
129
+ values: [{ label: 'VWAP', value, color: VWAP_COLOR }],
130
+ }
131
+ }
132
+
111
133
  @Indicator({
112
134
  name: 'vwap',
113
135
  displayName: 'VWAP',
114
136
  category: 'volume',
115
- stateKey: createVWAPStateKey,
116
137
  defaultPaneId: 'sub_VWAP',
117
- paneIdField: 'vwapPaneId',
118
138
  visibleState: { compose: createSparseVisibleStateComposer('vwap', EMPTY_VWAP_STATE) },
119
139
  scale: { indicatorKey: 'vwap', label: 'VWAP', decimals: 2 },
120
- updateConfig: (scheduler, params, paneId) => {
121
- (scheduler as IndicatorScheduler).updateVWAPConfig(params as Partial<VWAPSchedulerConfig>, paneId)
122
- },
123
- applyResult: (host, state, paneId) => {
124
- host.setSharedState(createVWAPStateKey(paneId), state as any, 'indicator_scheduler')
140
+ getTitleInfo: getVWAPTitleInfo,
141
+ runtime: {
142
+ defaultConfig: { sessionResetGapMs: 0, showVWAP: true },
143
+ computeKey: 'calcVWAPData',
144
+ compute: (data, c) => calcVWAPData(data, c.sessionResetGapMs),
125
145
  },
126
146
  })
127
147
  class VWAPIndicatorDefinition {
@@ -1,11 +1,13 @@
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 { WMARenderState } from '../../indicators/wmaState'
4
5
  import { createWMAStateKey, EMPTY_WMA_STATE } from '../../indicators/wmaState'
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, WMASchedulerConfig } from '../../indicators/scheduler'
10
+ import { calcWMAData } from '../../indicators/calculators'
9
11
 
10
12
  const WMA_COLOR = '#10b981'
11
13
 
@@ -120,23 +122,40 @@ export function createWMARendererPlugin(options: WMARendererOptions = {}): Rende
120
122
  }
121
123
  }
122
124
 
125
+ export const getWMATitleInfo: 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 = createWMAStateKey(paneId)
135
+ const state = pluginHost?.getSharedState<WMARenderState>(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: 'WMA',
143
+ params: [state.params.period],
144
+ values: [{ label: 'WMA', value, color: '#10b981' }],
145
+ }
146
+ }
147
+
123
148
  @Indicator({
124
149
  name: 'wma',
125
150
  displayName: 'WMA',
151
+ getTitleInfo: getWMATitleInfo,
126
152
  category: 'main',
127
- stateKey: createWMAStateKey,
128
153
  defaultPaneId: 'main',
129
- paneIdField: 'wmaPaneId',
130
154
  allowMainPane: true,
131
155
  mainPane: { rendererName: 'wma_main', toActiveConfig: (params, active) => ({ ...params, showWMA: active }) },
132
156
  visibleState: { compose: createSparseVisibleStateComposer('wma', EMPTY_WMA_STATE) },
133
157
  scale: { indicatorKey: 'wma', label: 'WMA', decimals: 2 },
134
- updateConfig: (scheduler, params, paneId) => {
135
- (scheduler as IndicatorScheduler).updateWMAConfig(params as Partial<WMASchedulerConfig>, paneId)
136
- },
137
- applyResult: (host, state, paneId) => {
138
- host.setSharedState(createWMAStateKey(paneId), state as any, 'indicator_scheduler')
139
- },
158
+ runtime: { defaultConfig:{period:10,showWMA:true}, computeKey:'calcWMAData', compute:(data,c)=>calcWMAData(data,c.period) },
140
159
  })
141
160
  class WMADefinition {
142
161
  static rendererFactory = createWMARendererPlugin
@@ -9,6 +9,8 @@ import { createFixedRangeSparseVisibleStateComposer } from '../../indicators/vis
9
9
  import { resolveStateKey } from '../../indicators/indicatorMetadata'
10
10
  import type { IndicatorScheduler, WMSRSchedulerConfig } from '../../indicators/scheduler'
11
11
  import { createWmsrScaleRendererPlugin } from './scale/wmsr_scale'
12
+ import { calcWMSRData } from '../../indicators/calculators'
13
+ import type { KLineData } from '../../../types/price'
12
14
 
13
15
  type LinePoint = { x: number; y: number }
14
16
 
@@ -255,7 +257,7 @@ const { ctx, pane, range, scrollLeft, dpr, kLineCenters, lineWebGLSurface } = co
255
257
  },
256
258
 
257
259
  setConfig() {
258
- // no-op: 配置通过 scheduler.updateWMSRConfig() 更新
260
+ // no-op: 配置通过 scheduler.updateIndicatorConfig() 更新
259
261
  },
260
262
  }
261
263
  }
@@ -292,14 +294,15 @@ function drawWMSRLineWithCanvas2D(
292
294
  * 获取 WMSR 标题信息(供 paneTitle 使用)
293
295
  */
294
296
  export function getWMSRTitleInfo(
295
- index: number,
296
- period: number,
297
+ _data: KLineData[],
298
+ index: number | null,
299
+ params: Record<string, number | boolean | string>,
297
300
  pluginHost: PluginHost,
298
- paneId: string = 'sub_WMSR',
299
- theme: 'light' | 'dark' = 'light',
300
- isAsiaMarket?: boolean
301
+ paneId: string,
301
302
  ): { name: string; params: number[]; values: Array<{ label: string; value: number; color: string }> } | null {
302
- const colors = resolveThemeColors(theme, isAsiaMarket)
303
+ if (index === null) return null
304
+ const period = (params.period as number) ?? 14
305
+ const colors = resolveThemeColors('light')
303
306
  const state = pluginHost.getSharedState<WMSRRenderState>(createWMSRStateKey(paneId))
304
307
  if (!state) return null
305
308
 
@@ -319,16 +322,14 @@ export function getWMSRTitleInfo(
319
322
  name: 'wmsr',
320
323
  displayName: 'WMSR',
321
324
  category: 'oscillator',
322
- stateKey: createWMSRStateKey,
323
325
  defaultPaneId: 'sub_WMSR',
324
- paneIdField: 'wmsrPaneId',
325
326
  visibleState: { compose: createFixedRangeSparseVisibleStateComposer('wmsr', EMPTY_WMSR_STATE) },
326
327
  scaleRendererFactory: createWmsrScaleRendererPlugin,
327
- updateConfig: (scheduler, params, paneId) => {
328
- (scheduler as IndicatorScheduler).updateWMSRConfig(params as Partial<WMSRSchedulerConfig>, paneId)
329
- },
330
- applyResult: (host, state, paneId) => {
331
- host.setSharedState(createWMSRStateKey(paneId), state as any, 'indicator_scheduler')
328
+ getTitleInfo: getWMSRTitleInfo,
329
+ runtime: {
330
+ defaultConfig: { period: 14, showWMSR: true },
331
+ computeKey: 'calcWMSRData',
332
+ compute: (data, c) => calcWMSRData(data, c.period),
332
333
  },
333
334
  })
334
335
  class WMSRIndicatorDefinition {
@@ -5,8 +5,9 @@ import type { ZonesRenderState } from '../../indicators/zonesState'
5
5
  import { createZonesStateKey, EMPTY_ZONES_STATE } from '../../indicators/zonesState'
6
6
  import { Indicator } from '../../indicators/indicatorDefinitionRegistry'
7
7
  import { createFixedUnitVisibleStateComposer } from '../../indicators/visibleStateComposers'
8
- import { resolveStateKey } from '../../indicators/indicatorMetadata'
8
+ import { resolveStateKey, type TitleInfo, type TitleValueItem, type GetTitleInfoFn } from '../../indicators/indicatorMetadata'
9
9
  import type { IndicatorScheduler, ZonesSchedulerConfig } from '../../indicators/scheduler'
10
+ import { calcZonesData } from '../../indicators/calculators'
10
11
 
11
12
  function getZonesStateKey(host: PluginHost | null, paneId: string): string | null {
12
13
  const scheduler = host?.getService<IndicatorScheduler>('indicatorScheduler')
@@ -89,23 +90,42 @@ export function createZonesRendererPlugin(options: { paneId?: string } = {}): Re
89
90
  }
90
91
  }
91
92
 
93
+ export const getZonesTitleInfo: GetTitleInfoFn = (_data, index, _params, host, paneId) => {
94
+ if (index === null) return null
95
+
96
+ const stateKey = createZonesStateKey(paneId)
97
+ const state = host?.getSharedState<ZonesRenderState>(stateKey)
98
+ if (!state) return null
99
+
100
+ const activeZones = state.series.filter(
101
+ z => z.startIndex <= index && (z.endIndex === undefined || z.endIndex >= index)
102
+ )
103
+ if (activeZones.length === 0) return null
104
+
105
+ const values: TitleValueItem[] = activeZones.slice(0, 5).map(z => ({
106
+ label: z.kind,
107
+ value: z.high,
108
+ color: z.kind.includes('Bull') ? '#22c55e' : '#ef4444',
109
+ }))
110
+
111
+ return {
112
+ name: 'Zones',
113
+ params: [activeZones.length],
114
+ values,
115
+ }
116
+ }
117
+
92
118
  @Indicator({
93
119
  name: 'zones',
94
120
  displayName: 'Zones',
121
+ getTitleInfo: getZonesTitleInfo,
95
122
  category: 'main',
96
- stateKey: createZonesStateKey,
97
123
  defaultPaneId: 'main',
98
- paneIdField: 'zonesPaneId',
99
124
  allowMainPane: true,
100
125
  mainPane: { rendererName: 'zones_main', toActiveConfig: (params, active) => ({ ...params, showFVG: active, showOB: active, showFilledZones: active }) },
101
126
  scale: { indicatorKey: 'zones', label: 'Zones', decimals: 2 },
102
127
  visibleState: { compose: createFixedUnitVisibleStateComposer('zones', EMPTY_ZONES_STATE) },
103
- updateConfig: (scheduler, params, paneId) => {
104
- (scheduler as IndicatorScheduler).updateZonesConfig(params as Partial<ZonesSchedulerConfig>, paneId)
105
- },
106
- applyResult: (host, state, paneId) => {
107
- host.setSharedState(createZonesStateKey(paneId), state as any, 'indicator_scheduler')
108
- },
128
+ runtime: { defaultConfig:{showFVG:true,showOB:true,showFilledZones:true,obLookback:20}, computeKey:'calcZonesData', compute:(data,c)=>calcZonesData(data,c.obLookback,5,2,'close') },
109
129
  })
110
130
  class ZonesDefinition {
111
131
  static rendererFactory = createZonesRendererPlugin