@363045841yyt/klinechart-core 0.7.9 → 0.7.10

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 (234) hide show
  1. package/dist/engine/chart.d.ts.map +1 -1
  2. package/dist/engine/chart.js +39 -229
  3. package/dist/engine/chart.js.map +1 -1
  4. package/dist/engine/indicators/indicatorDefinitionRegistry.d.ts +10 -3
  5. package/dist/engine/indicators/indicatorDefinitionRegistry.d.ts.map +1 -1
  6. package/dist/engine/indicators/indicatorDefinitionRegistry.js +29 -2
  7. package/dist/engine/indicators/indicatorDefinitionRegistry.js.map +1 -1
  8. package/dist/engine/indicators/indicatorMetadata.d.ts +79 -2
  9. package/dist/engine/indicators/indicatorMetadata.d.ts.map +1 -1
  10. package/dist/engine/indicators/indicatorMetadata.js.map +1 -1
  11. package/dist/engine/indicators/indicatorRegistry.d.ts +5 -0
  12. package/dist/engine/indicators/indicatorRegistry.d.ts.map +1 -1
  13. package/dist/engine/indicators/indicatorRegistry.js +49 -5
  14. package/dist/engine/indicators/indicatorRegistry.js.map +1 -1
  15. package/dist/engine/indicators/registerBuiltins.d.ts +42 -0
  16. package/dist/engine/indicators/registerBuiltins.d.ts.map +1 -0
  17. package/dist/engine/indicators/registerBuiltins.js +46 -0
  18. package/dist/engine/indicators/registerBuiltins.js.map +1 -0
  19. package/dist/engine/indicators/scheduler.d.ts +2 -2
  20. package/dist/engine/indicators/scheduler.d.ts.map +1 -1
  21. package/dist/engine/indicators/scheduler.js +41 -11
  22. package/dist/engine/indicators/scheduler.js.map +1 -1
  23. package/dist/engine/indicators/stateComposer.d.ts +6 -4
  24. package/dist/engine/indicators/stateComposer.d.ts.map +1 -1
  25. package/dist/engine/indicators/stateComposer.js +80 -984
  26. package/dist/engine/indicators/stateComposer.js.map +1 -1
  27. package/dist/engine/indicators/visibleStateComposers.d.ts +145 -0
  28. package/dist/engine/indicators/visibleStateComposers.d.ts.map +1 -0
  29. package/dist/engine/indicators/visibleStateComposers.js +469 -0
  30. package/dist/engine/indicators/visibleStateComposers.js.map +1 -0
  31. package/dist/engine/renderers/Indicator/atr.d.ts.map +1 -1
  32. package/dist/engine/renderers/Indicator/atr.js +8 -0
  33. package/dist/engine/renderers/Indicator/atr.js.map +1 -1
  34. package/dist/engine/renderers/Indicator/boll.d.ts.map +1 -1
  35. package/dist/engine/renderers/Indicator/boll.js +47 -0
  36. package/dist/engine/renderers/Indicator/boll.js.map +1 -1
  37. package/dist/engine/renderers/Indicator/cci.d.ts.map +1 -1
  38. package/dist/engine/renderers/Indicator/cci.js +8 -1
  39. package/dist/engine/renderers/Indicator/cci.js.map +1 -1
  40. package/dist/engine/renderers/Indicator/chaikinVol.d.ts.map +1 -1
  41. package/dist/engine/renderers/Indicator/chaikinVol.js +7 -1
  42. package/dist/engine/renderers/Indicator/chaikinVol.js.map +1 -1
  43. package/dist/engine/renderers/Indicator/cmf.d.ts.map +1 -1
  44. package/dist/engine/renderers/Indicator/cmf.js +7 -1
  45. package/dist/engine/renderers/Indicator/cmf.js.map +1 -1
  46. package/dist/engine/renderers/Indicator/dema.d.ts.map +1 -1
  47. package/dist/engine/renderers/Indicator/dema.js +8 -1
  48. package/dist/engine/renderers/Indicator/dema.js.map +1 -1
  49. package/dist/engine/renderers/Indicator/donchian.d.ts.map +1 -1
  50. package/dist/engine/renderers/Indicator/donchian.js +8 -1
  51. package/dist/engine/renderers/Indicator/donchian.js.map +1 -1
  52. package/dist/engine/renderers/Indicator/ene.d.ts.map +1 -1
  53. package/dist/engine/renderers/Indicator/ene.js +45 -0
  54. package/dist/engine/renderers/Indicator/ene.js.map +1 -1
  55. package/dist/engine/renderers/Indicator/expma.d.ts.map +1 -1
  56. package/dist/engine/renderers/Indicator/expma.js +45 -0
  57. package/dist/engine/renderers/Indicator/expma.js.map +1 -1
  58. package/dist/engine/renderers/Indicator/fastk.d.ts.map +1 -1
  59. package/dist/engine/renderers/Indicator/fastk.js +8 -1
  60. package/dist/engine/renderers/Indicator/fastk.js.map +1 -1
  61. package/dist/engine/renderers/Indicator/fib.d.ts.map +1 -1
  62. package/dist/engine/renderers/Indicator/fib.js +8 -1
  63. package/dist/engine/renderers/Indicator/fib.js.map +1 -1
  64. package/dist/engine/renderers/Indicator/hma.d.ts.map +1 -1
  65. package/dist/engine/renderers/Indicator/hma.js +8 -1
  66. package/dist/engine/renderers/Indicator/hma.js.map +1 -1
  67. package/dist/engine/renderers/Indicator/hv.d.ts.map +1 -1
  68. package/dist/engine/renderers/Indicator/hv.js +7 -0
  69. package/dist/engine/renderers/Indicator/hv.js.map +1 -1
  70. package/dist/engine/renderers/Indicator/ichimoku.d.ts.map +1 -1
  71. package/dist/engine/renderers/Indicator/ichimoku.js +8 -1
  72. package/dist/engine/renderers/Indicator/ichimoku.js.map +1 -1
  73. package/dist/engine/renderers/Indicator/index.d.ts +7 -2
  74. package/dist/engine/renderers/Indicator/index.d.ts.map +1 -1
  75. package/dist/engine/renderers/Indicator/index.js +2 -114
  76. package/dist/engine/renderers/Indicator/index.js.map +1 -1
  77. package/dist/engine/renderers/Indicator/kama.d.ts.map +1 -1
  78. package/dist/engine/renderers/Indicator/kama.js +8 -1
  79. package/dist/engine/renderers/Indicator/kama.js.map +1 -1
  80. package/dist/engine/renderers/Indicator/keltner.d.ts.map +1 -1
  81. package/dist/engine/renderers/Indicator/keltner.js +8 -1
  82. package/dist/engine/renderers/Indicator/keltner.js.map +1 -1
  83. package/dist/engine/renderers/Indicator/kst.d.ts.map +1 -1
  84. package/dist/engine/renderers/Indicator/kst.js +8 -0
  85. package/dist/engine/renderers/Indicator/kst.js.map +1 -1
  86. package/dist/engine/renderers/Indicator/ma.d.ts.map +1 -1
  87. package/dist/engine/renderers/Indicator/ma.js +63 -0
  88. package/dist/engine/renderers/Indicator/ma.js.map +1 -1
  89. package/dist/engine/renderers/Indicator/macd.d.ts.map +1 -1
  90. package/dist/engine/renderers/Indicator/macd.js +8 -1
  91. package/dist/engine/renderers/Indicator/macd.js.map +1 -1
  92. package/dist/engine/renderers/Indicator/mfi.d.ts.map +1 -1
  93. package/dist/engine/renderers/Indicator/mfi.js +7 -1
  94. package/dist/engine/renderers/Indicator/mfi.js.map +1 -1
  95. package/dist/engine/renderers/Indicator/mom.d.ts.map +1 -1
  96. package/dist/engine/renderers/Indicator/mom.js +8 -0
  97. package/dist/engine/renderers/Indicator/mom.js.map +1 -1
  98. package/dist/engine/renderers/Indicator/obv.d.ts.map +1 -1
  99. package/dist/engine/renderers/Indicator/obv.js +7 -1
  100. package/dist/engine/renderers/Indicator/obv.js.map +1 -1
  101. package/dist/engine/renderers/Indicator/parkinson.d.ts.map +1 -1
  102. package/dist/engine/renderers/Indicator/parkinson.js +7 -0
  103. package/dist/engine/renderers/Indicator/parkinson.js.map +1 -1
  104. package/dist/engine/renderers/Indicator/pivot.d.ts.map +1 -1
  105. package/dist/engine/renderers/Indicator/pivot.js +8 -1
  106. package/dist/engine/renderers/Indicator/pivot.js.map +1 -1
  107. package/dist/engine/renderers/Indicator/pvt.d.ts.map +1 -1
  108. package/dist/engine/renderers/Indicator/pvt.js +7 -1
  109. package/dist/engine/renderers/Indicator/pvt.js.map +1 -1
  110. package/dist/engine/renderers/Indicator/roc.d.ts.map +1 -1
  111. package/dist/engine/renderers/Indicator/roc.js +7 -1
  112. package/dist/engine/renderers/Indicator/roc.js.map +1 -1
  113. package/dist/engine/renderers/Indicator/rsi.d.ts.map +1 -1
  114. package/dist/engine/renderers/Indicator/rsi.js +8 -1
  115. package/dist/engine/renderers/Indicator/rsi.js.map +1 -1
  116. package/dist/engine/renderers/Indicator/sar.d.ts.map +1 -1
  117. package/dist/engine/renderers/Indicator/sar.js +8 -1
  118. package/dist/engine/renderers/Indicator/sar.js.map +1 -1
  119. package/dist/engine/renderers/Indicator/stoch.d.ts.map +1 -1
  120. package/dist/engine/renderers/Indicator/stoch.js +8 -1
  121. package/dist/engine/renderers/Indicator/stoch.js.map +1 -1
  122. package/dist/engine/renderers/Indicator/structure.d.ts.map +1 -1
  123. package/dist/engine/renderers/Indicator/structure.js +8 -1
  124. package/dist/engine/renderers/Indicator/structure.js.map +1 -1
  125. package/dist/engine/renderers/Indicator/subPaneConfig.d.ts +1 -1
  126. package/dist/engine/renderers/Indicator/subPaneConfig.d.ts.map +1 -1
  127. package/dist/engine/renderers/Indicator/subPaneConfig.js.map +1 -1
  128. package/dist/engine/renderers/Indicator/supertrend.d.ts.map +1 -1
  129. package/dist/engine/renderers/Indicator/supertrend.js +8 -1
  130. package/dist/engine/renderers/Indicator/supertrend.js.map +1 -1
  131. package/dist/engine/renderers/Indicator/tema.d.ts.map +1 -1
  132. package/dist/engine/renderers/Indicator/tema.js +8 -1
  133. package/dist/engine/renderers/Indicator/tema.js.map +1 -1
  134. package/dist/engine/renderers/Indicator/trix.d.ts.map +1 -1
  135. package/dist/engine/renderers/Indicator/trix.js +7 -0
  136. package/dist/engine/renderers/Indicator/trix.js.map +1 -1
  137. package/dist/engine/renderers/Indicator/vma.d.ts.map +1 -1
  138. package/dist/engine/renderers/Indicator/vma.js +7 -0
  139. package/dist/engine/renderers/Indicator/vma.js.map +1 -1
  140. package/dist/engine/renderers/Indicator/volumeProfile.d.ts.map +1 -1
  141. package/dist/engine/renderers/Indicator/volumeProfile.js +7 -1
  142. package/dist/engine/renderers/Indicator/volumeProfile.js.map +1 -1
  143. package/dist/engine/renderers/Indicator/vwap.d.ts.map +1 -1
  144. package/dist/engine/renderers/Indicator/vwap.js +7 -1
  145. package/dist/engine/renderers/Indicator/vwap.js.map +1 -1
  146. package/dist/engine/renderers/Indicator/wma.d.ts.map +1 -1
  147. package/dist/engine/renderers/Indicator/wma.js +8 -1
  148. package/dist/engine/renderers/Indicator/wma.js.map +1 -1
  149. package/dist/engine/renderers/Indicator/wmsr.d.ts.map +1 -1
  150. package/dist/engine/renderers/Indicator/wmsr.js +8 -1
  151. package/dist/engine/renderers/Indicator/wmsr.js.map +1 -1
  152. package/dist/engine/renderers/Indicator/zones.d.ts.map +1 -1
  153. package/dist/engine/renderers/Indicator/zones.js +8 -1
  154. package/dist/engine/renderers/Indicator/zones.js.map +1 -1
  155. package/dist/engine/renderers/extremaMarkers.d.ts.map +1 -1
  156. package/dist/engine/renderers/extremaMarkers.js +0 -22
  157. package/dist/engine/renderers/extremaMarkers.js.map +1 -1
  158. package/dist/engine/renderers/subVolume.d.ts.map +1 -1
  159. package/dist/engine/renderers/subVolume.js +3 -0
  160. package/dist/engine/renderers/subVolume.js.map +1 -1
  161. package/dist/engine/subPaneManager.d.ts +1 -0
  162. package/dist/engine/subPaneManager.d.ts.map +1 -1
  163. package/dist/engine/subPaneManager.js +30 -237
  164. package/dist/engine/subPaneManager.js.map +1 -1
  165. package/dist/semantic/controller.d.ts +9 -4
  166. package/dist/semantic/controller.d.ts.map +1 -1
  167. package/dist/semantic/controller.js +57 -53
  168. package/dist/semantic/controller.js.map +1 -1
  169. package/dist/version.d.ts +1 -1
  170. package/dist/version.d.ts.map +1 -1
  171. package/dist/version.js +1 -1
  172. package/dist/version.js.map +1 -1
  173. package/package.json +1 -1
  174. package/src/engine/chart.ts +49 -229
  175. package/src/engine/indicators/__tests__/indicatorDefinitionRegistry.test.ts +59 -0
  176. package/src/engine/indicators/__tests__/indicatorRegistry.test.ts +62 -0
  177. package/src/engine/indicators/__tests__/registerBuiltins.test.ts +380 -0
  178. package/src/engine/indicators/__tests__/scheduler.test.ts +62 -32
  179. package/src/engine/indicators/__tests__/stateComposer.test.ts +444 -0
  180. package/src/engine/indicators/indicatorDefinitionRegistry.ts +49 -4
  181. package/src/engine/indicators/indicatorMetadata.ts +107 -2
  182. package/src/engine/indicators/indicatorRegistry.ts +54 -5
  183. package/src/engine/indicators/registerBuiltins.ts +47 -0
  184. package/src/engine/indicators/scheduler.ts +61 -13
  185. package/src/engine/indicators/stateComposer.ts +110 -1040
  186. package/src/engine/indicators/visibleStateComposers.ts +734 -0
  187. package/src/engine/renderers/Indicator/__tests__/createSubIndicatorRenderer.test.ts +61 -0
  188. package/src/engine/renderers/Indicator/atr.ts +9 -1
  189. package/src/engine/renderers/Indicator/boll.ts +53 -1
  190. package/src/engine/renderers/Indicator/cci.ts +9 -2
  191. package/src/engine/renderers/Indicator/chaikinVol.ts +8 -2
  192. package/src/engine/renderers/Indicator/cmf.ts +8 -2
  193. package/src/engine/renderers/Indicator/dema.ts +9 -2
  194. package/src/engine/renderers/Indicator/donchian.ts +9 -2
  195. package/src/engine/renderers/Indicator/ene.ts +51 -1
  196. package/src/engine/renderers/Indicator/expma.ts +51 -1
  197. package/src/engine/renderers/Indicator/fastk.ts +9 -2
  198. package/src/engine/renderers/Indicator/fib.ts +9 -2
  199. package/src/engine/renderers/Indicator/hma.ts +9 -2
  200. package/src/engine/renderers/Indicator/hv.ts +8 -1
  201. package/src/engine/renderers/Indicator/ichimoku.ts +9 -2
  202. package/src/engine/renderers/Indicator/index.ts +9 -121
  203. package/src/engine/renderers/Indicator/kama.ts +9 -2
  204. package/src/engine/renderers/Indicator/keltner.ts +9 -2
  205. package/src/engine/renderers/Indicator/kst.ts +9 -1
  206. package/src/engine/renderers/Indicator/ma.ts +69 -0
  207. package/src/engine/renderers/Indicator/macd.ts +9 -2
  208. package/src/engine/renderers/Indicator/mfi.ts +8 -2
  209. package/src/engine/renderers/Indicator/mom.ts +9 -1
  210. package/src/engine/renderers/Indicator/obv.ts +8 -2
  211. package/src/engine/renderers/Indicator/parkinson.ts +8 -1
  212. package/src/engine/renderers/Indicator/pivot.ts +9 -2
  213. package/src/engine/renderers/Indicator/pvt.ts +8 -2
  214. package/src/engine/renderers/Indicator/roc.ts +8 -2
  215. package/src/engine/renderers/Indicator/rsi.ts +9 -2
  216. package/src/engine/renderers/Indicator/sar.ts +9 -2
  217. package/src/engine/renderers/Indicator/stoch.ts +9 -2
  218. package/src/engine/renderers/Indicator/structure.ts +9 -2
  219. package/src/engine/renderers/Indicator/subPaneConfig.ts +1 -1
  220. package/src/engine/renderers/Indicator/supertrend.ts +9 -2
  221. package/src/engine/renderers/Indicator/tema.ts +9 -2
  222. package/src/engine/renderers/Indicator/trix.ts +8 -1
  223. package/src/engine/renderers/Indicator/vma.ts +8 -1
  224. package/src/engine/renderers/Indicator/volumeProfile.ts +8 -2
  225. package/src/engine/renderers/Indicator/vwap.ts +8 -2
  226. package/src/engine/renderers/Indicator/wma.ts +9 -2
  227. package/src/engine/renderers/Indicator/wmsr.ts +9 -2
  228. package/src/engine/renderers/Indicator/zones.ts +9 -2
  229. package/src/engine/renderers/extremaMarkers.ts +0 -24
  230. package/src/engine/renderers/subVolume.ts +3 -0
  231. package/src/engine/subPaneManager.ts +34 -274
  232. package/src/semantic/__tests__/controller.test.ts +84 -0
  233. package/src/semantic/controller.ts +69 -65
  234. package/src/version.ts +1 -1
@@ -8,6 +8,26 @@ import type { IndicatorMetadata } from './indicatorMetadata'
8
8
  */
9
9
  export class IndicatorRegistry {
10
10
  private indicators = new Map<string, IndicatorMetadata>()
11
+ private aliases = new Map<string, string>()
12
+
13
+ private normalize(id: string): string {
14
+ return id.trim().toLowerCase().replace(/[^a-z0-9]/g, '')
15
+ }
16
+
17
+ private indexAlias(alias: string, name: string): void {
18
+ const normalized = this.normalize(alias)
19
+ if (normalized) {
20
+ this.aliases.set(normalized, name)
21
+ }
22
+ }
23
+
24
+ private removeAliasesFor(name: string): void {
25
+ for (const [alias, target] of this.aliases) {
26
+ if (target === name) {
27
+ this.aliases.delete(alias)
28
+ }
29
+ }
30
+ }
11
31
 
12
32
  /**
13
33
  * 注册指标
@@ -28,12 +48,23 @@ export class IndicatorRegistry {
28
48
  throw new Error(`[IndicatorRegistry] rendererFactory is required for indicator '${meta.name}'`)
29
49
  }
30
50
 
51
+ const normalizedName = this.normalize(meta.name)
52
+ if (!normalizedName) {
53
+ throw new Error('[IndicatorRegistry] Indicator name is required')
54
+ }
55
+
31
56
  // 检查重复注册
32
- if (this.indicators.has(meta.name)) {
57
+ if (this.indicators.has(normalizedName)) {
33
58
  console.warn(`[IndicatorRegistry] Indicator '${meta.name}' already registered, overwriting`)
59
+ this.removeAliasesFor(normalizedName)
34
60
  }
35
61
 
36
- this.indicators.set(meta.name, meta as IndicatorMetadata)
62
+ this.indicators.set(normalizedName, meta as IndicatorMetadata)
63
+ this.indexAlias(meta.name, normalizedName)
64
+ this.indexAlias(meta.displayName, normalizedName)
65
+ for (const alias of meta.aliases ?? []) {
66
+ this.indexAlias(alias, normalizedName)
67
+ }
37
68
  }
38
69
 
39
70
  /**
@@ -42,7 +73,14 @@ export class IndicatorRegistry {
42
73
  * @returns 是否成功注销
43
74
  */
44
75
  unregister(name: string): boolean {
45
- return this.indicators.delete(name)
76
+ const normalizedName = this.normalize(name)
77
+ const canonicalName = this.aliases.get(normalizedName) ?? normalizedName
78
+ const meta = this.indicators.get(canonicalName)
79
+ if (!meta) return false
80
+
81
+ this.indicators.delete(canonicalName)
82
+ this.removeAliasesFor(canonicalName)
83
+ return true
46
84
  }
47
85
 
48
86
  /**
@@ -51,7 +89,17 @@ export class IndicatorRegistry {
51
89
  * @returns 元数据或 undefined
52
90
  */
53
91
  get(name: string): IndicatorMetadata | undefined {
54
- return this.indicators.get(name)
92
+ const normalizedName = this.normalize(name)
93
+ const canonicalName = this.aliases.get(normalizedName) ?? normalizedName
94
+ return this.indicators.get(canonicalName)
95
+ }
96
+
97
+ getRequired(name: string): IndicatorMetadata {
98
+ const meta = this.get(name)
99
+ if (!meta) {
100
+ throw new Error(`[IndicatorRegistry] Unknown indicator '${name}'`)
101
+ }
102
+ return meta
55
103
  }
56
104
 
57
105
  /**
@@ -59,7 +107,7 @@ export class IndicatorRegistry {
59
107
  * @param name - 指标名称
60
108
  */
61
109
  has(name: string): boolean {
62
- return this.indicators.has(name)
110
+ return this.get(name) !== undefined
63
111
  }
64
112
 
65
113
  /**
@@ -95,6 +143,7 @@ export class IndicatorRegistry {
95
143
  */
96
144
  clear(): void {
97
145
  this.indicators.clear()
146
+ this.aliases.clear()
98
147
  }
99
148
 
100
149
  /**
@@ -0,0 +1,47 @@
1
+ import '../renderers/subVolume'
2
+ import '../renderers/Indicator/atr'
3
+ import '../renderers/Indicator/boll'
4
+ import '../renderers/Indicator/cci'
5
+ import '../renderers/Indicator/chaikinVol'
6
+ import '../renderers/Indicator/cmf'
7
+ import '../renderers/Indicator/dema'
8
+ import '../renderers/Indicator/donchian'
9
+ import '../renderers/Indicator/ene'
10
+ import '../renderers/Indicator/expma'
11
+ import '../renderers/Indicator/fastk'
12
+ import '../renderers/Indicator/fib'
13
+ import '../renderers/Indicator/hma'
14
+ import '../renderers/Indicator/hv'
15
+ import '../renderers/Indicator/ichimoku'
16
+ import '../renderers/Indicator/kama'
17
+ import '../renderers/Indicator/keltner'
18
+ import '../renderers/Indicator/kst'
19
+ import '../renderers/Indicator/ma'
20
+ import '../renderers/Indicator/macd'
21
+ import '../renderers/Indicator/mfi'
22
+ import '../renderers/Indicator/mom'
23
+ import '../renderers/Indicator/obv'
24
+ import '../renderers/Indicator/parkinson'
25
+ import '../renderers/Indicator/pivot'
26
+ import '../renderers/Indicator/pvt'
27
+ import '../renderers/Indicator/roc'
28
+ import '../renderers/Indicator/rsi'
29
+ import '../renderers/Indicator/sar'
30
+ import '../renderers/Indicator/stoch'
31
+ import '../renderers/Indicator/structure'
32
+ import '../renderers/Indicator/supertrend'
33
+ import '../renderers/Indicator/tema'
34
+ import '../renderers/Indicator/trix'
35
+ import '../renderers/Indicator/vma'
36
+ import '../renderers/Indicator/volumeProfile'
37
+ import '../renderers/Indicator/vwap'
38
+ import '../renderers/Indicator/wma'
39
+ import '../renderers/Indicator/wmsr'
40
+ import '../renderers/Indicator/zones'
41
+ import { getRegisteredIndicatorDefinitions } from './indicatorDefinitionRegistry'
42
+
43
+ const builtinIndicatorDefinitions = getRegisteredIndicatorDefinitions()
44
+
45
+ export function getBuiltinIndicatorDefinitions() {
46
+ return builtinIndicatorDefinitions
47
+ }
@@ -63,7 +63,7 @@ import type {
63
63
  } from './workerProtocol'
64
64
  import type { MAFlags } from './calculators'
65
65
  import { IndicatorRegistry } from './indicatorRegistry'
66
- import type { IndicatorMetadata } from './indicatorMetadata'
66
+ import { resolveStateKey, type IndicatorMetadata } from './indicatorMetadata'
67
67
  import type { BaseIndicatorState } from '../../plugin'
68
68
 
69
69
  // Default constants for default config
@@ -519,8 +519,10 @@ export class IndicatorScheduler {
519
519
  this.workerReady = true
520
520
  this.useWorker = true
521
521
  console.log('[IndicatorScheduler] Worker READY - using Worker backend')
522
- // Worker 就绪后立即补算一次,确保后续走 Worker
523
- this.triggerRecompute()
522
+ // Worker 就绪后补算一次,但仅在有数据时(避免空数据产出 Infinity 极值)
523
+ if (this.currentData.length > 0) {
524
+ this.triggerRecompute()
525
+ }
524
526
  break
525
527
 
526
528
  case 'seriesResult':
@@ -584,7 +586,12 @@ export class IndicatorScheduler {
584
586
 
585
587
  const changed = new Set(bundle._changed)
586
588
  const timestamp = Date.now()
587
- const states = composeRenderStates(bundle, this.visibleRange, timestamp)
589
+ const states = composeRenderStates(
590
+ bundle,
591
+ this.visibleRange,
592
+ timestamp,
593
+ (indicatorId) => this.registry.get(indicatorId),
594
+ )
588
595
 
589
596
  for (const meta of this.registry.getAll()) {
590
597
  if (!changed.has(meta.name)) continue
@@ -606,19 +613,49 @@ export class IndicatorScheduler {
606
613
  }
607
614
  }
608
615
 
609
- /** 仅副图:重算可见范围极值并回调 applyResult(视口变更时同步更新,不走 Worker) */
610
- private updateVisibleStatesOnly(): void {
611
- if (!this.pluginHost || !this.latestResult) return
616
+ /** 重算可见范围极值并回调 applyResult(视口变更时同步更新,不走 Worker) */
617
+ private updateVisibleStatesOnly(): boolean {
618
+ if (!this.pluginHost || !this.latestResult) return false
612
619
 
613
620
  const timestamp = Date.now()
621
+ let mainStates: Record<string, unknown> | null = null
622
+ let mainStateUpdated = false
614
623
  const activeMask = this.buildActiveSubIndicatorMask()
615
- const states = composeVisibleSubIndicatorStates(this.latestResult, this.visibleRange, timestamp, activeMask)
624
+ const subStates = composeVisibleSubIndicatorStates(
625
+ this.latestResult,
626
+ this.visibleRange,
627
+ timestamp,
628
+ activeMask,
629
+ (indicatorId) => this.registry.get(indicatorId),
630
+ ) as Record<string, unknown>
616
631
 
617
632
  for (const meta of this.registry.getAll()) {
618
633
  if (!meta.applyResult) continue
619
- if (!meta.paneIdField && meta.category === 'main') continue
620
634
 
621
- const state = (states as Record<string, unknown>)[meta.name]
635
+ let state: unknown
636
+ if (meta.category === 'main') {
637
+ const paneId = meta.paneIdField
638
+ ? (this.configSnapshot as unknown as Record<string, string>)[meta.paneIdField as string]
639
+ : meta.defaultPaneId
640
+ const current = this.pluginHost.getSharedState<BaseIndicatorState & { visibleMin?: number; visibleMax?: number }>(
641
+ resolveStateKey(meta.stateKey, paneId),
642
+ )
643
+ const currentValid = current &&
644
+ Number.isFinite(current.visibleMin) &&
645
+ Number.isFinite(current.visibleMax) &&
646
+ current.visibleMin! <= current.visibleMax!
647
+ if (currentValid) continue
648
+
649
+ mainStates ??= composeRenderStates(
650
+ this.latestResult,
651
+ this.visibleRange,
652
+ timestamp,
653
+ (indicatorId) => this.registry.get(indicatorId),
654
+ ) as Record<string, unknown>
655
+ state = mainStates[meta.name]
656
+ } else {
657
+ state = subStates[meta.name]
658
+ }
622
659
  if (state === undefined) continue
623
660
 
624
661
  this.checkVisibleExtremes(
@@ -631,7 +668,12 @@ export class IndicatorScheduler {
631
668
  : meta.defaultPaneId
632
669
 
633
670
  meta.applyResult(this.pluginHost, state as BaseIndicatorState, paneId)
671
+ if (meta.category === 'main') {
672
+ mainStateUpdated = true
673
+ }
634
674
  }
675
+
676
+ return mainStateUpdated
635
677
  }
636
678
 
637
679
  /** 遍历注册表,标记当前可见副图,仅这些指标参与计算 */
@@ -696,7 +738,10 @@ export class IndicatorScheduler {
696
738
 
697
739
  // 基于缓存的 series 同步更新极值
698
740
  if (this.latestResult) {
699
- this.updateVisibleStatesOnly()
741
+ const mainStateUpdated = this.updateVisibleStatesOnly()
742
+ if (mainStateUpdated) {
743
+ this.invalidateCallback?.()
744
+ }
700
745
  }
701
746
  }
702
747
 
@@ -1114,11 +1159,13 @@ export class IndicatorScheduler {
1114
1159
  */
1115
1160
  getMainIndicatorPriceRange(): { min: number; max: number } | null {
1116
1161
  if (!this.latestResult) return null
1117
- return computeMainIndicatorPriceRange(
1162
+ const result = computeMainIndicatorPriceRange(
1118
1163
  this.latestResult,
1119
1164
  this.visibleRange,
1120
- this.activeMainIndicators
1165
+ this.activeMainIndicators,
1166
+ (indicatorId) => this.registry.get(indicatorId),
1121
1167
  )
1168
+ return result
1122
1169
  }
1123
1170
 
1124
1171
  /**
@@ -1139,6 +1186,7 @@ export class IndicatorScheduler {
1139
1186
  // ============================================================================
1140
1187
 
1141
1188
  private triggerRecompute(): void {
1189
+ if (this.currentData.length === 0) return
1142
1190
  if (this.useWorker && this.worker && this.workerReady) {
1143
1191
  this.computeWithWorker()
1144
1192
  } else {