@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
@@ -7,6 +7,8 @@ import { resolveStateKey } from '../../indicators/indicatorMetadata'
7
7
  import { createSparseVisibleStateComposer } from '../../indicators/visibleStateComposers'
8
8
  import type { IndicatorScheduler, OBVSchedulerConfig } from '../../indicators/scheduler'
9
9
  import { calcOBVData } from '../../indicators/calculators'
10
+ import type { TitleInfo } from '../../indicators/indicatorMetadata'
11
+ import type { KLineData } from '../../../types/price'
10
12
 
11
13
  const OBV_COLOR = '#16a34a'
12
14
 
@@ -109,22 +111,34 @@ export function createOBVRendererPlugin(options: { paneId?: string } = {}): Rend
109
111
  }
110
112
  }
111
113
 
114
+ export function getOBVTitleInfo(
115
+ _data: KLineData[],
116
+ index: number | null,
117
+ _params: Record<string, number | boolean | string>,
118
+ host: PluginHost,
119
+ paneId: string,
120
+ ): TitleInfo | null {
121
+ if (index === null) return null
122
+ const state = host.getSharedState<OBVRenderState>(createOBVStateKey(paneId))
123
+ const value = state?.series[index]
124
+ if (value === undefined) return null
125
+
126
+ return {
127
+ name: 'OBV',
128
+ params: [],
129
+ values: [{ label: 'OBV', value, color: OBV_COLOR }],
130
+ }
131
+ }
132
+
112
133
  @Indicator({
113
134
  name: 'obv',
114
135
  displayName: 'OBV',
115
136
  category: 'volume',
116
- stateKey: createOBVStateKey,
117
137
  defaultPaneId: 'sub_OBV',
118
138
  visibleState: { compose: createSparseVisibleStateComposer('obv', EMPTY_OBV_STATE) },
119
139
  scale: { indicatorKey: 'obv', label: 'OBV', decimals: 0 },
120
- updateConfig: (scheduler, params, paneId) => {
121
- (scheduler as IndicatorScheduler).updateIndicatorConfig('obv', params, paneId)
122
- },
123
- applyResult: (host, state, paneId) => {
124
- host.setSharedState(createOBVStateKey(paneId), state as any, 'indicator_scheduler')
125
- },
140
+ getTitleInfo: getOBVTitleInfo,
126
141
  runtime: {
127
- configKey: 'obv',
128
142
  defaultConfig: { showOBV: true },
129
143
  computeKey: 'calcOBVData',
130
144
  compute: (data, c) => calcOBVData(data),
@@ -1,5 +1,6 @@
1
1
  import type { RendererPluginWithHost, RenderContext, PluginHost } from '../../../plugin'
2
2
  import { RENDERER_PRIORITY } from '../../../plugin'
3
+ import { resolveThemeColors } from '../../../tokens'
3
4
  import type { ParkinsonRenderState } from '../../indicators/parkinsonState'
4
5
  import { createParkinsonStateKey } from '../../indicators/parkinsonState'
5
6
  import { EMPTY_PARKINSON_STATE } from '../../indicators/parkinsonState'
@@ -8,6 +9,8 @@ import { Indicator } from '../../indicators/indicatorDefinitionRegistry'
8
9
  import { resolveStateKey } from '../../indicators/indicatorMetadata'
9
10
  import type { IndicatorScheduler, ParkinsonSchedulerConfig } from '../../indicators/scheduler'
10
11
  import { calcParkinsonData } from '../../indicators/calculators'
12
+ import type { TitleInfo } from '../../indicators/indicatorMetadata'
13
+ import type { KLineData } from '../../../types/price'
11
14
 
12
15
  const PARKINSON_COLOR = '#0891b2'
13
16
 
@@ -111,21 +114,36 @@ export function createParkinsonRendererPlugin(options: { paneId?: string } = {})
111
114
  }
112
115
  }
113
116
 
117
+ export function getParkinsonTitleInfo(
118
+ _data: KLineData[],
119
+ index: number | null,
120
+ params: Record<string, number | boolean | string>,
121
+ host: PluginHost,
122
+ paneId: string,
123
+ ): TitleInfo | null {
124
+ if (index === null) return null
125
+ const period = (params.period as number) ?? 20
126
+ const annualizationFactor = (params.annualizationFactor as number) ?? 252
127
+ const state = host.getSharedState<ParkinsonRenderState>(createParkinsonStateKey(paneId))
128
+ const value = state?.series[index]
129
+ if (value === undefined) return null
130
+
131
+ return {
132
+ name: 'Parkinson',
133
+ params: [period, annualizationFactor],
134
+ values: [{ label: 'Parkinson', value, color: PARKINSON_COLOR }],
135
+ }
136
+ }
137
+
114
138
  @Indicator({
115
139
  name: 'parkinson',
116
140
  displayName: 'Parkinson',
117
141
  category: 'oscillator',
118
- stateKey: createParkinsonStateKey,
119
142
  defaultPaneId: 'sub_Parkinson',
120
143
  scale: { indicatorKey: 'parkinson', label: 'Parkinson', decimals: 2 },
121
- updateConfig: (scheduler, params, paneId) => {
122
- (scheduler as IndicatorScheduler).updateIndicatorConfig('parkinson', params, paneId)
123
- },
144
+ getTitleInfo: getParkinsonTitleInfo,
124
145
  visibleState: { compose: createNonNegativeSparseVisibleStateComposer('parkinson', EMPTY_PARKINSON_STATE) },
125
- applyResult: (host, state, paneId) => {
126
- host.setSharedState(createParkinsonStateKey(paneId), state as any, 'indicator_scheduler')
127
- },
128
- runtime: { configKey:'parkinson', defaultConfig:{period:20,annualizationFactor:252,showParkinson:true}, computeKey:'calcParkinsonData', compute:(data,c)=>calcParkinsonData(data,c.period,c.annualizationFactor) },
146
+ runtime: { defaultConfig:{period:20,annualizationFactor:252,showParkinson:true}, computeKey:'calcParkinsonData', compute:(data,c)=>calcParkinsonData(data,c.period,c.annualizationFactor) },
129
147
  })
130
148
  class ParkinsonIndicatorDefinition {
131
149
  static rendererFactory = createParkinsonRendererPlugin
@@ -3,7 +3,7 @@ import { RENDERER_PRIORITY } from '../../../plugin'
3
3
  import type { PivotRenderState } from '../../indicators/pivotState'
4
4
  import { createPivotStateKey, EMPTY_PIVOT_STATE } from '../../indicators/pivotState'
5
5
  import { Indicator } from '../../indicators/indicatorDefinitionRegistry'
6
- import { resolveStateKey } from '../../indicators/indicatorMetadata'
6
+ import { resolveStateKey, type TitleInfo, type TitleValueItem, type GetTitleInfoFn } from '../../indicators/indicatorMetadata'
7
7
  import type { IndicatorScheduler, PivotSchedulerConfig } from '../../indicators/scheduler'
8
8
  import { createExactRangePointVisibleStateComposer } from '../../indicators/visibleStateComposers'
9
9
  import { calcPivotData } from '../../indicators/calculators'
@@ -116,23 +116,60 @@ function drawStep(ctx: CanvasRenderingContext2D, pts: Point[], color: string): v
116
116
  ctx.stroke()
117
117
  }
118
118
 
119
+ export const getPivotTitleInfo: GetTitleInfoFn = (_data, index, _params, host, paneId) => {
120
+ if (index === null || index < 0) return null
121
+
122
+ const stateKey = createPivotStateKey(paneId)
123
+ const state = host?.getSharedState<PivotRenderState>(stateKey)
124
+ if (!state) return null
125
+
126
+ const p = state.series[index]
127
+ if (!p) return null
128
+
129
+ const values: TitleValueItem[] = []
130
+
131
+ if (state.params.showPP) {
132
+ values.push({ label: 'PP', value: p.pp, color: PP_COLOR })
133
+ }
134
+ if (state.params.showR1) {
135
+ values.push({ label: 'R1', value: p.r1, color: R_COLOR })
136
+ }
137
+ if (state.params.showR2) {
138
+ values.push({ label: 'R2', value: p.r2, color: R_COLOR })
139
+ }
140
+ if (state.params.showR3) {
141
+ values.push({ label: 'R3', value: p.r3, color: R_COLOR })
142
+ }
143
+ if (state.params.showS1) {
144
+ values.push({ label: 'S1', value: p.s1, color: S_COLOR })
145
+ }
146
+ if (state.params.showS2) {
147
+ values.push({ label: 'S2', value: p.s2, color: S_COLOR })
148
+ }
149
+ if (state.params.showS3) {
150
+ values.push({ label: 'S3', value: p.s3, color: S_COLOR })
151
+ }
152
+
153
+ if (values.length === 0) return null
154
+
155
+ return {
156
+ name: 'Pivot',
157
+ params: [],
158
+ values,
159
+ }
160
+ }
161
+
119
162
  @Indicator({
120
163
  name: 'pivot',
121
164
  displayName: 'Pivot',
165
+ getTitleInfo: getPivotTitleInfo,
122
166
  category: 'main',
123
- stateKey: createPivotStateKey,
124
167
  defaultPaneId: 'main',
125
168
  allowMainPane: true,
126
169
  mainPane: { rendererName: 'pivot_main', toActiveConfig: (params, active) => ({ ...params, showPP: active, showR1: active, showR2: active, showR3: active, showS1: active, showS2: active, showS3: active }) },
127
170
  scale: { indicatorKey: 'pivot', label: 'Pivot', decimals: 2 },
128
171
  visibleState: { compose: createExactRangePointVisibleStateComposer('pivot', EMPTY_PIVOT_STATE, ['pp', 'r1', 'r2', 'r3', 's1', 's2', 's3']) },
129
- updateConfig: (scheduler, params, paneId) => {
130
- (scheduler as IndicatorScheduler).updateIndicatorConfig('pivot', params, paneId)
131
- },
132
- applyResult: (host, state, paneId) => {
133
- host.setSharedState(createPivotStateKey(paneId), state as any, 'indicator_scheduler')
134
- },
135
- runtime: { configKey:'pivot', defaultConfig:{showPP:true,showR1:true,showR2:true,showR3:true,showS1:true,showS2:true,showS3:true}, computeKey:'calcPivotData', compute:(data,c)=>calcPivotData(data) },
172
+ runtime: { defaultConfig:{showPP:true,showR1:true,showR2:true,showR3:true,showS1:true,showS2:true,showS3:true}, computeKey:'calcPivotData', compute:(data,c)=>calcPivotData(data) },
136
173
  })
137
174
  class PivotDefinition {
138
175
  static rendererFactory = createPivotRendererPlugin
@@ -7,6 +7,8 @@ import { resolveStateKey } from '../../indicators/indicatorMetadata'
7
7
  import { createSparseVisibleStateComposer } from '../../indicators/visibleStateComposers'
8
8
  import type { IndicatorScheduler, PVTSchedulerConfig } from '../../indicators/scheduler'
9
9
  import { calcPVTData } from '../../indicators/calculators'
10
+ import type { TitleInfo } from '../../indicators/indicatorMetadata'
11
+ import type { KLineData } from '../../../types/price'
10
12
 
11
13
  const PVT_COLOR = '#a855f7'
12
14
 
@@ -109,22 +111,34 @@ export function createPVTRendererPlugin(options: { paneId?: string } = {}): Rend
109
111
  }
110
112
  }
111
113
 
114
+ export function getPVTTitleInfo(
115
+ _data: KLineData[],
116
+ index: number | null,
117
+ _params: Record<string, number | boolean | string>,
118
+ host: PluginHost,
119
+ paneId: string,
120
+ ): TitleInfo | null {
121
+ if (index === null) return null
122
+ const state = host.getSharedState<PVTRenderState>(createPVTStateKey(paneId))
123
+ const value = state?.series[index]
124
+ if (value === undefined) return null
125
+
126
+ return {
127
+ name: 'PVT',
128
+ params: [],
129
+ values: [{ label: 'PVT', value, color: PVT_COLOR }],
130
+ }
131
+ }
132
+
112
133
  @Indicator({
113
134
  name: 'pvt',
114
135
  displayName: 'PVT',
115
136
  category: 'volume',
116
- stateKey: createPVTStateKey,
117
137
  defaultPaneId: 'sub_PVT',
118
138
  visibleState: { compose: createSparseVisibleStateComposer('pvt', EMPTY_PVT_STATE) },
119
139
  scale: { indicatorKey: 'pvt', label: 'PVT', decimals: 0 },
120
- updateConfig: (scheduler, params, paneId) => {
121
- (scheduler as IndicatorScheduler).updateIndicatorConfig('pvt', params, paneId)
122
- },
123
- applyResult: (host, state, paneId) => {
124
- host.setSharedState(createPVTStateKey(paneId), state as any, 'indicator_scheduler')
125
- },
140
+ getTitleInfo: getPVTTitleInfo,
126
141
  runtime: {
127
- configKey: 'pvt',
128
142
  defaultConfig: { showPVT: true },
129
143
  computeKey: 'calcPVTData',
130
144
  compute: (data, c) => calcPVTData(data),
@@ -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 { ROCRenderState } from '../../indicators/rocState'
4
5
  import { createROCStateKey, EMPTY_ROC_STATE } from '../../indicators/rocState'
5
6
  import { Indicator } from '../../indicators/indicatorDefinitionRegistry'
@@ -7,6 +8,8 @@ import { resolveStateKey } from '../../indicators/indicatorMetadata'
7
8
  import { createSparseVisibleStateComposer } from '../../indicators/visibleStateComposers'
8
9
  import type { IndicatorScheduler, ROCSchedulerConfig } from '../../indicators/scheduler'
9
10
  import { calcROCData } from '../../indicators/calculators'
11
+ import type { KLineData } from '../../../types/price'
12
+ import type { TitleInfo } from '../../indicators/indicatorMetadata'
10
13
 
11
14
  const ROC_COLOR = '#0ea5e9'
12
15
 
@@ -129,22 +132,35 @@ export function createROCRendererPlugin(options: ROCRendererOptions = {}): Rende
129
132
  }
130
133
  }
131
134
 
135
+ export function getROCTitleInfo(
136
+ _data: KLineData[],
137
+ index: number | null,
138
+ params: Record<string, number | boolean | string>,
139
+ pluginHost: PluginHost,
140
+ paneId: string,
141
+ ): TitleInfo | null {
142
+ if (index === null) return null
143
+ const period = (params.period as number) ?? 12
144
+ const state = pluginHost.getSharedState<ROCRenderState>(createROCStateKey(paneId))
145
+ const value = state?.series[index]
146
+ if (value === undefined) return null
147
+
148
+ return {
149
+ name: 'ROC',
150
+ params: [period],
151
+ values: [{ label: 'ROC', value, color: ROC_COLOR }],
152
+ }
153
+ }
154
+
132
155
  @Indicator({
133
156
  name: 'roc',
134
157
  displayName: 'ROC',
135
158
  category: 'oscillator',
136
- stateKey: createROCStateKey,
137
159
  defaultPaneId: 'sub_ROC',
138
160
  visibleState: { compose: createSparseVisibleStateComposer('roc', EMPTY_ROC_STATE) },
139
161
  scale: { indicatorKey: 'roc', label: 'ROC', decimals: 2 },
140
- updateConfig: (scheduler, params, paneId) => {
141
- (scheduler as IndicatorScheduler).updateIndicatorConfig('roc', params, paneId)
142
- },
143
- applyResult: (host, state, paneId) => {
144
- host.setSharedState(createROCStateKey(paneId), state as any, 'indicator_scheduler')
145
- },
162
+ getTitleInfo: getROCTitleInfo,
146
163
  runtime: {
147
- configKey: 'roc',
148
164
  defaultConfig: { period: 12, showROC: true },
149
165
  computeKey: 'calcROCData',
150
166
  compute: (data, c) => calcROCData(data, c.period),
@@ -10,6 +10,7 @@ import { resolveStateKey } from '../../indicators/indicatorMetadata'
10
10
  import type { IndicatorScheduler, RSISchedulerConfig } from '../../indicators/scheduler'
11
11
  import { createRsiScaleRendererPlugin } from './scale/rsi_scale'
12
12
  import { calcRSIData } from '../../indicators/calculators'
13
+ import type { KLineData } from '../../../types/price'
13
14
 
14
15
  type LinePoint = { x: number; y: number }
15
16
 
@@ -351,16 +352,17 @@ export function drawRSILinesWithCanvas2D(
351
352
  }
352
353
 
353
354
  export function getRSITitleInfo(
354
- index: number,
355
- period1: number,
356
- period2: number,
357
- period3: number,
355
+ _data: KLineData[],
356
+ index: number | null,
357
+ params: Record<string, number | boolean | string>,
358
358
  pluginHost: PluginHost,
359
- paneId: string = 'sub_RSI',
360
- theme: 'light' | 'dark' = 'light',
361
- isAsiaMarket?: boolean
359
+ paneId: string,
362
360
  ): { name: string; params: number[]; values: Array<{ label: string; value: number; color: string }> } | null {
363
- const colors = resolveThemeColors(theme, isAsiaMarket)
361
+ if (index === null) return null
362
+ const period1 = (params.period1 as number) ?? 6
363
+ const period2 = (params.period2 as number) ?? 12
364
+ const period3 = (params.period3 as number) ?? 24
365
+ const colors = resolveThemeColors('light')
364
366
  const stateKey = createRSIStateKey(paneId)
365
367
  const state = pluginHost.getSharedState<RSIRenderState>(stateKey)
366
368
 
@@ -388,17 +390,11 @@ export function getRSITitleInfo(
388
390
  name: 'rsi',
389
391
  displayName: 'RSI',
390
392
  category: 'oscillator',
391
- stateKey: createRSIStateKey,
392
393
  defaultPaneId: 'sub_RSI',
393
394
  visibleState: { compose: createFixedRangeRecordVisibleStateComposer('rsi', EMPTY_RSI_STATE) },
394
395
  scaleRendererFactory: createRsiScaleRendererPlugin,
395
- updateConfig: (scheduler, params, paneId) => {
396
- (scheduler as IndicatorScheduler).updateIndicatorConfig('rsi', params, paneId)
397
- },
398
- applyResult: (host, state, paneId) => {
399
- host.setSharedState(createRSIStateKey(paneId), state as any, 'indicator_scheduler')
400
- },
401
- runtime: { configKey:'rsi', defaultConfig:{period1:6,period2:12,period3:24,showRSI1:true,showRSI2:true,showRSI3:true}, computeKey:'calcRSIData', compute:(data,c)=>{const p=[c.period1,c.period2,c.period3];const s=[c.showRSI1,c.showRSI2,c.showRSI3];const r:Record<number,(number|undefined)[]>={};for(let i=0;i<3;i++){if(s[i])r[p[i]]=calcRSIData(data,p[i])}return r} },
396
+ getTitleInfo: getRSITitleInfo,
397
+ runtime: { defaultConfig:{period1:6,period2:12,period3:24,showRSI1:true,showRSI2:true,showRSI3:true}, computeKey:'calcRSIData', compute:(data,c)=>{const p=[c.period1,c.period2,c.period3];const s=[c.showRSI1,c.showRSI2,c.showRSI3];const r:Record<number,(number|undefined)[]>={};for(let i=0;i<3;i++){if(s[i])r[p[i]]=calcRSIData(data,p[i])}return r} },
402
398
  })
403
399
  class RSIIndicatorDefinition {
404
400
  static rendererFactory = createRSIRendererPlugin
@@ -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 { SARRenderState } from '../../indicators/sarState'
4
5
  import { createSARStateKey, EMPTY_SAR_STATE } from '../../indicators/sarState'
5
6
  import { Indicator } from '../../indicators/indicatorDefinitionRegistry'
6
- import { resolveStateKey } from '../../indicators/indicatorMetadata'
7
+ import { resolveStateKey, type TitleInfo, type GetTitleInfoFn } from '../../indicators/indicatorMetadata'
7
8
  import type { IndicatorScheduler, SARSchedulerConfig } from '../../indicators/scheduler'
8
9
  import { calcSARData } from '../../indicators/calculators'
9
10
  import { createValuePointVisibleStateComposer } from '../../indicators/visibleStateComposers'
@@ -98,23 +99,38 @@ export function createSARRendererPlugin(options: SARRendererOptions = {}): Rende
98
99
  }
99
100
  }
100
101
 
102
+ export function getSARTitleInfo(
103
+ _data: KLineData[],
104
+ index: number | null,
105
+ params: Record<string, number | boolean | string>,
106
+ host: PluginHost,
107
+ paneId: string,
108
+ ): TitleInfo | null {
109
+ if (index === null) return null
110
+ const state = host.getSharedState<SARRenderState>(createSARStateKey(paneId))
111
+ const p = state?.series[index]
112
+ if (!p) return null
113
+
114
+ return {
115
+ name: 'SAR',
116
+ params: [(params.step as number) ?? 0.02, (params.maxStep as number) ?? 0.2],
117
+ values: [
118
+ { label: 'SAR', value: p.value, color: p.trend === 'up' ? '#22c55e' : '#ef4444' },
119
+ ],
120
+ }
121
+ }
122
+
101
123
  @Indicator({
102
124
  name: 'sar',
103
125
  displayName: 'SAR',
126
+ getTitleInfo: getSARTitleInfo,
104
127
  category: 'main',
105
- stateKey: createSARStateKey,
106
128
  defaultPaneId: 'main',
107
129
  allowMainPane: true,
108
130
  mainPane: { rendererName: 'sar_main', toActiveConfig: (params, active) => ({ ...params, showSAR: active }) },
109
131
  scale: { indicatorKey: 'sar', label: 'SAR', decimals: 4 },
110
132
  visibleState: { compose: createValuePointVisibleStateComposer('sar', EMPTY_SAR_STATE, ['value']) },
111
- updateConfig: (scheduler, params, paneId) => {
112
- (scheduler as IndicatorScheduler).updateIndicatorConfig('sar', params, paneId)
113
- },
114
- applyResult: (host, state, paneId) => {
115
- host.setSharedState(createSARStateKey(paneId), state as any, 'indicator_scheduler')
116
- },
117
- runtime: { configKey:'sar', defaultConfig:{step:0.02,maxStep:0.2,showSAR:true}, computeKey:'calcSARData', compute:(data,c)=>calcSARData(data,c.step,c.maxStep) },
133
+ runtime: { defaultConfig:{step:0.02,maxStep:0.2,showSAR:true}, computeKey:'calcSARData', compute:(data,c)=>calcSARData(data,c.step,c.maxStep) },
118
134
  })
119
135
  class SARDefinition {
120
136
  static rendererFactory = createSARRendererPlugin
@@ -10,6 +10,7 @@ import { resolveStateKey } from '../../indicators/indicatorMetadata'
10
10
  import type { IndicatorScheduler, STOCHSchedulerConfig } from '../../indicators/scheduler'
11
11
  import { createStochScaleRendererPlugin } from './scale/stoch_scale'
12
12
  import { calcSTOCHData } from '../../indicators/calculators'
13
+ import type { KLineData } from '../../../types/price'
13
14
 
14
15
  type LinePoint = { x: number; y: number }
15
16
 
@@ -319,15 +320,16 @@ function drawSTOCHLinesWithCanvas2D(
319
320
  * 获取 STOCH 标题信息(供 paneTitle 使用)
320
321
  */
321
322
  export function getSTOCHTitleInfo(
322
- index: number,
323
- n: number,
324
- m: number,
323
+ _data: KLineData[],
324
+ index: number | null,
325
+ params: Record<string, number | boolean | string>,
325
326
  pluginHost: PluginHost,
326
- paneId: string = 'sub_STOCH',
327
- theme: 'light' | 'dark' = 'light',
328
- isAsiaMarket?: boolean
327
+ paneId: string,
329
328
  ): { name: string; params: number[]; values: Array<{ label: string; value: number; color: string }> } | null {
330
- const colors = resolveThemeColors(theme, isAsiaMarket)
329
+ if (index === null) return null
330
+ const n = (params.n as number) ?? 9
331
+ const m = (params.m as number) ?? 3
332
+ const colors = resolveThemeColors('light')
331
333
  const state = pluginHost.getSharedState<STOCHRenderState>(createSTOCHStateKey(paneId))
332
334
  if (!state) return null
333
335
 
@@ -351,17 +353,11 @@ export function getSTOCHTitleInfo(
351
353
  name: 'stoch',
352
354
  displayName: 'STOCH',
353
355
  category: 'oscillator',
354
- stateKey: createSTOCHStateKey,
355
356
  defaultPaneId: 'sub_STOCH',
356
357
  visibleState: { compose: createFixedRangePointVisibleStateComposer('stoch', EMPTY_STOCH_STATE, ['k', 'd'] as const) },
357
358
  scaleRendererFactory: createStochScaleRendererPlugin,
358
- updateConfig: (scheduler, params, paneId) => {
359
- (scheduler as IndicatorScheduler).updateIndicatorConfig('stoch', params, paneId)
360
- },
361
- applyResult: (host, state, paneId) => {
362
- host.setSharedState(createSTOCHStateKey(paneId), state as any, 'indicator_scheduler')
363
- },
364
- runtime: { configKey:'stoch', defaultConfig:{n:9,m:3,showK:true,showD:true}, computeKey:'calcSTOCHData', compute:(data,c)=>calcSTOCHData(data,c.n,c.m) },
359
+ getTitleInfo: getSTOCHTitleInfo,
360
+ runtime: { defaultConfig:{n:9,m:3,showK:true,showD:true}, computeKey:'calcSTOCHData', compute:(data,c)=>calcSTOCHData(data,c.n,c.m) },
365
361
  })
366
362
  class STOCHIndicatorDefinition {
367
363
  static rendererFactory = createSTOCHRendererPlugin
@@ -8,6 +8,8 @@ import { createFixedUnitVisibleStateComposer } from '../../indicators/visibleSta
8
8
  import { resolveStateKey } from '../../indicators/indicatorMetadata'
9
9
  import type { IndicatorScheduler, StructureSchedulerConfig } from '../../indicators/scheduler'
10
10
  import { calcStructureData } from '../../indicators/calculators'
11
+ import type { TitleInfo } from '../../indicators/indicatorMetadata'
12
+ import type { KLineData } from '../../../types/price'
11
13
 
12
14
  const LABEL_FONT = '11px sans-serif'
13
15
 
@@ -111,23 +113,43 @@ export function createStructureRendererPlugin(options: { paneId?: string } = {})
111
113
  }
112
114
  }
113
115
 
116
+ export function getStructureTitleInfo(
117
+ _data: KLineData[],
118
+ index: number | null,
119
+ params: Record<string, number | boolean | string>,
120
+ host: PluginHost,
121
+ paneId: string,
122
+ ): TitleInfo | null {
123
+ if (index === null) return null
124
+ const leftWindow = (params.leftWindow as number) ?? 5
125
+ const rightWindow = (params.rightWindow as number) ?? 2
126
+ const colors = resolveThemeColors('light')
127
+ const state = host.getSharedState<StructureRenderState>(createStructureStateKey(paneId))
128
+
129
+ const values: Array<{ label: string; value: number; color: string }> = []
130
+ if (state && state.series.swings.length > 0) {
131
+ values.push({ label: 'Swings', value: state.series.swings.length, color: colors.structure.hh })
132
+ values.push({ label: 'Events', value: state.series.events.length, color: colors.structure.choch })
133
+ }
134
+
135
+ return {
136
+ name: 'Structure',
137
+ params: [leftWindow, rightWindow],
138
+ values,
139
+ }
140
+ }
141
+
114
142
  @Indicator({
115
143
  name: 'structure',
116
144
  displayName: 'Structure',
117
145
  category: 'sub',
118
- stateKey: createStructureStateKey,
119
146
  defaultPaneId: 'sub_Structure',
120
147
  allowMainPane: true,
121
148
  mainPane: { rendererName: 'structure_main', toActiveConfig: (params, active) => ({ ...params, showSwingLabels: active, showBOS: active, showCHOCH: active }) },
122
149
  scale: { indicatorKey: 'structure', label: 'Structure', decimals: 2 },
150
+ getTitleInfo: getStructureTitleInfo,
123
151
  visibleState: { compose: createFixedUnitVisibleStateComposer('structure', EMPTY_STRUCTURE_STATE) },
124
- updateConfig: (scheduler, params, paneId) => {
125
- (scheduler as IndicatorScheduler).updateIndicatorConfig('structure', params, paneId)
126
- },
127
- applyResult: (host, state, paneId) => {
128
- host.setSharedState(createStructureStateKey(paneId), state as any, 'indicator_scheduler')
129
- },
130
- runtime: { configKey:'structure', defaultConfig:{leftWindow:5,rightWindow:2,breakoutSource:'close',showSwingLabels:true,showBOS:true,showCHOCH:true,showProvisional:true}, computeKey:'calcStructureData', compute:(data,c)=>calcStructureData(data,c.leftWindow,c.rightWindow,c.breakoutSource) },
152
+ runtime: { defaultConfig:{leftWindow:5,rightWindow:2,breakoutSource:'close',showSwingLabels:true,showBOS:true,showCHOCH:true,showProvisional:true}, computeKey:'calcStructureData', compute:(data,c)=>calcStructureData(data,c.leftWindow,c.rightWindow,c.breakoutSource) },
131
153
  })
132
154
  class StructureIndicatorDefinition {
133
155
  static rendererFactory = createStructureRendererPlugin
@@ -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 { 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'
8
9
  import { calcSuperTrendData } from '../../indicators/calculators'
9
10
  import { createValuePointVisibleStateComposer } from '../../indicators/visibleStateComposers'
@@ -100,23 +101,38 @@ export function createSuperTrendRendererPlugin(options: SuperTrendRendererOption
100
101
  }
101
102
  }
102
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
+
103
125
  @Indicator({
104
126
  name: 'supertrend',
105
127
  displayName: 'SuperTrend',
128
+ getTitleInfo: getSuperTrendTitleInfo,
106
129
  category: 'oscillator',
107
- stateKey: createSuperTrendStateKey,
108
130
  defaultPaneId: 'sub_SuperTrend',
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).updateIndicatorConfig('supertrend', params, paneId)
115
- },
116
- applyResult: (host, state, paneId) => {
117
- host.setSharedState(createSuperTrendStateKey(paneId), state as any, 'indicator_scheduler')
118
- },
119
- runtime: { configKey:'supertrend', defaultConfig:{atrPeriod:10,multiplier:3,showSuperTrend:true}, computeKey:'calcSuperTrendData', compute:(data,c)=>calcSuperTrendData(data,c.atrPeriod,c.multiplier) },
135
+ runtime: { defaultConfig:{atrPeriod:10,multiplier:3,showSuperTrend:true}, computeKey:'calcSuperTrendData', compute:(data,c)=>calcSuperTrendData(data,c.atrPeriod,c.multiplier) },
120
136
  })
121
137
  class SuperTrendIndicatorDefinition {
122
138
  static rendererFactory = createSuperTrendRendererPlugin
@@ -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 { 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'
9
10
  import { calcTEMAData } from '../../indicators/calculators'
@@ -121,23 +122,40 @@ export function createTEMARendererPlugin(options: TEMARendererOptions = {}): Ren
121
122
  }
122
123
  }
123
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
+
124
148
  @Indicator({
125
149
  name: 'tema',
126
150
  displayName: 'TEMA',
151
+ getTitleInfo: getTEMATitleInfo,
127
152
  category: 'main',
128
- stateKey: createTEMAStateKey,
129
153
  defaultPaneId: 'main',
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).updateIndicatorConfig('tema', params, paneId)
136
- },
137
- applyResult: (host, state, paneId) => {
138
- host.setSharedState(createTEMAStateKey(paneId), state as any, 'indicator_scheduler')
139
- },
140
- runtime: { configKey:'tema', defaultConfig:{period:14,showTEMA:true}, computeKey:'calcTEMAData', compute:(data,c)=>calcTEMAData(data,c.period) },
158
+ runtime: { defaultConfig:{period:14,showTEMA:true}, computeKey:'calcTEMAData', compute:(data,c)=>calcTEMAData(data,c.period) },
141
159
  })
142
160
  class TEMADefinition {
143
161
  static rendererFactory = createTEMARendererPlugin