@363045841yyt/klinechart-core 0.7.11 → 0.7.12

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 (191) hide show
  1. package/dist/engine/indicators/indicator.worker.js +32 -4
  2. package/dist/engine/indicators/indicator.worker.js.map +1 -1
  3. package/dist/engine/indicators/indicatorDefinitionRegistry.d.ts +3 -2
  4. package/dist/engine/indicators/indicatorDefinitionRegistry.d.ts.map +1 -1
  5. package/dist/engine/indicators/indicatorDefinitionRegistry.js.map +1 -1
  6. package/dist/engine/indicators/indicatorMetadata.d.ts +27 -1
  7. package/dist/engine/indicators/indicatorMetadata.d.ts.map +1 -1
  8. package/dist/engine/indicators/indicatorMetadata.js.map +1 -1
  9. package/dist/engine/indicators/indicatorRuntime.d.ts +12 -117
  10. package/dist/engine/indicators/indicatorRuntime.d.ts.map +1 -1
  11. package/dist/engine/indicators/indicatorRuntime.js +123 -1308
  12. package/dist/engine/indicators/indicatorRuntime.js.map +1 -1
  13. package/dist/engine/indicators/scheduler.d.ts +3 -142
  14. package/dist/engine/indicators/scheduler.d.ts.map +1 -1
  15. package/dist/engine/indicators/scheduler.js +59 -431
  16. package/dist/engine/indicators/scheduler.js.map +1 -1
  17. package/dist/engine/indicators/stateComposer.d.ts.map +1 -1
  18. package/dist/engine/indicators/stateComposer.js +15 -47
  19. package/dist/engine/indicators/stateComposer.js.map +1 -1
  20. package/dist/engine/indicators/workerProtocol.d.ts +12 -36
  21. package/dist/engine/indicators/workerProtocol.d.ts.map +1 -1
  22. package/dist/engine/indicators/workerProtocol.js.map +1 -1
  23. package/dist/engine/renderers/Indicator/atr.d.ts.map +1 -1
  24. package/dist/engine/renderers/Indicator/atr.js +9 -3
  25. package/dist/engine/renderers/Indicator/atr.js.map +1 -1
  26. package/dist/engine/renderers/Indicator/boll.d.ts.map +1 -1
  27. package/dist/engine/renderers/Indicator/boll.js +4 -2
  28. package/dist/engine/renderers/Indicator/boll.js.map +1 -1
  29. package/dist/engine/renderers/Indicator/cci.d.ts.map +1 -1
  30. package/dist/engine/renderers/Indicator/cci.js +9 -3
  31. package/dist/engine/renderers/Indicator/cci.js.map +1 -1
  32. package/dist/engine/renderers/Indicator/chaikinVol.d.ts.map +1 -1
  33. package/dist/engine/renderers/Indicator/chaikinVol.js +8 -2
  34. package/dist/engine/renderers/Indicator/chaikinVol.js.map +1 -1
  35. package/dist/engine/renderers/Indicator/cmf.d.ts.map +1 -1
  36. package/dist/engine/renderers/Indicator/cmf.js +8 -2
  37. package/dist/engine/renderers/Indicator/cmf.js.map +1 -1
  38. package/dist/engine/renderers/Indicator/dema.d.ts.map +1 -1
  39. package/dist/engine/renderers/Indicator/dema.js +3 -2
  40. package/dist/engine/renderers/Indicator/dema.js.map +1 -1
  41. package/dist/engine/renderers/Indicator/donchian.d.ts.map +1 -1
  42. package/dist/engine/renderers/Indicator/donchian.js +3 -2
  43. package/dist/engine/renderers/Indicator/donchian.js.map +1 -1
  44. package/dist/engine/renderers/Indicator/ene.d.ts.map +1 -1
  45. package/dist/engine/renderers/Indicator/ene.js +5 -3
  46. package/dist/engine/renderers/Indicator/ene.js.map +1 -1
  47. package/dist/engine/renderers/Indicator/expma.d.ts.map +1 -1
  48. package/dist/engine/renderers/Indicator/expma.js +3 -1
  49. package/dist/engine/renderers/Indicator/expma.js.map +1 -1
  50. package/dist/engine/renderers/Indicator/fastk.d.ts.map +1 -1
  51. package/dist/engine/renderers/Indicator/fastk.js +9 -3
  52. package/dist/engine/renderers/Indicator/fastk.js.map +1 -1
  53. package/dist/engine/renderers/Indicator/fib.d.ts.map +1 -1
  54. package/dist/engine/renderers/Indicator/fib.js +3 -2
  55. package/dist/engine/renderers/Indicator/fib.js.map +1 -1
  56. package/dist/engine/renderers/Indicator/hma.d.ts.map +1 -1
  57. package/dist/engine/renderers/Indicator/hma.js +3 -2
  58. package/dist/engine/renderers/Indicator/hma.js.map +1 -1
  59. package/dist/engine/renderers/Indicator/hv.d.ts.map +1 -1
  60. package/dist/engine/renderers/Indicator/hv.js +3 -2
  61. package/dist/engine/renderers/Indicator/hv.js.map +1 -1
  62. package/dist/engine/renderers/Indicator/ichimoku.d.ts.map +1 -1
  63. package/dist/engine/renderers/Indicator/ichimoku.js +3 -2
  64. package/dist/engine/renderers/Indicator/ichimoku.js.map +1 -1
  65. package/dist/engine/renderers/Indicator/kama.d.ts.map +1 -1
  66. package/dist/engine/renderers/Indicator/kama.js +3 -2
  67. package/dist/engine/renderers/Indicator/kama.js.map +1 -1
  68. package/dist/engine/renderers/Indicator/keltner.d.ts.map +1 -1
  69. package/dist/engine/renderers/Indicator/keltner.js +3 -2
  70. package/dist/engine/renderers/Indicator/keltner.js.map +1 -1
  71. package/dist/engine/renderers/Indicator/kst.d.ts.map +1 -1
  72. package/dist/engine/renderers/Indicator/kst.js +4 -3
  73. package/dist/engine/renderers/Indicator/kst.js.map +1 -1
  74. package/dist/engine/renderers/Indicator/ma.d.ts.map +1 -1
  75. package/dist/engine/renderers/Indicator/ma.js +6 -1
  76. package/dist/engine/renderers/Indicator/ma.js.map +1 -1
  77. package/dist/engine/renderers/Indicator/macd.js +2 -2
  78. package/dist/engine/renderers/Indicator/macd.js.map +1 -1
  79. package/dist/engine/renderers/Indicator/mfi.d.ts.map +1 -1
  80. package/dist/engine/renderers/Indicator/mfi.js +8 -2
  81. package/dist/engine/renderers/Indicator/mfi.js.map +1 -1
  82. package/dist/engine/renderers/Indicator/mom.d.ts.map +1 -1
  83. package/dist/engine/renderers/Indicator/mom.js +9 -3
  84. package/dist/engine/renderers/Indicator/mom.js.map +1 -1
  85. package/dist/engine/renderers/Indicator/obv.d.ts.map +1 -1
  86. package/dist/engine/renderers/Indicator/obv.js +8 -2
  87. package/dist/engine/renderers/Indicator/obv.js.map +1 -1
  88. package/dist/engine/renderers/Indicator/parkinson.d.ts.map +1 -1
  89. package/dist/engine/renderers/Indicator/parkinson.js +3 -2
  90. package/dist/engine/renderers/Indicator/parkinson.js.map +1 -1
  91. package/dist/engine/renderers/Indicator/pivot.d.ts.map +1 -1
  92. package/dist/engine/renderers/Indicator/pivot.js +3 -2
  93. package/dist/engine/renderers/Indicator/pivot.js.map +1 -1
  94. package/dist/engine/renderers/Indicator/pvt.d.ts.map +1 -1
  95. package/dist/engine/renderers/Indicator/pvt.js +8 -2
  96. package/dist/engine/renderers/Indicator/pvt.js.map +1 -1
  97. package/dist/engine/renderers/Indicator/roc.d.ts.map +1 -1
  98. package/dist/engine/renderers/Indicator/roc.js +8 -2
  99. package/dist/engine/renderers/Indicator/roc.js.map +1 -1
  100. package/dist/engine/renderers/Indicator/rsi.d.ts.map +1 -1
  101. package/dist/engine/renderers/Indicator/rsi.js +7 -3
  102. package/dist/engine/renderers/Indicator/rsi.js.map +1 -1
  103. package/dist/engine/renderers/Indicator/sar.d.ts.map +1 -1
  104. package/dist/engine/renderers/Indicator/sar.js +3 -2
  105. package/dist/engine/renderers/Indicator/sar.js.map +1 -1
  106. package/dist/engine/renderers/Indicator/stoch.d.ts.map +1 -1
  107. package/dist/engine/renderers/Indicator/stoch.js +4 -3
  108. package/dist/engine/renderers/Indicator/stoch.js.map +1 -1
  109. package/dist/engine/renderers/Indicator/structure.d.ts.map +1 -1
  110. package/dist/engine/renderers/Indicator/structure.js +3 -2
  111. package/dist/engine/renderers/Indicator/structure.js.map +1 -1
  112. package/dist/engine/renderers/Indicator/supertrend.d.ts.map +1 -1
  113. package/dist/engine/renderers/Indicator/supertrend.js +3 -2
  114. package/dist/engine/renderers/Indicator/supertrend.js.map +1 -1
  115. package/dist/engine/renderers/Indicator/tema.d.ts.map +1 -1
  116. package/dist/engine/renderers/Indicator/tema.js +3 -2
  117. package/dist/engine/renderers/Indicator/tema.js.map +1 -1
  118. package/dist/engine/renderers/Indicator/trix.d.ts.map +1 -1
  119. package/dist/engine/renderers/Indicator/trix.js +3 -2
  120. package/dist/engine/renderers/Indicator/trix.js.map +1 -1
  121. package/dist/engine/renderers/Indicator/vma.d.ts.map +1 -1
  122. package/dist/engine/renderers/Indicator/vma.js +8 -2
  123. package/dist/engine/renderers/Indicator/vma.js.map +1 -1
  124. package/dist/engine/renderers/Indicator/volumeProfile.d.ts.map +1 -1
  125. package/dist/engine/renderers/Indicator/volumeProfile.js +3 -2
  126. package/dist/engine/renderers/Indicator/volumeProfile.js.map +1 -1
  127. package/dist/engine/renderers/Indicator/vwap.d.ts.map +1 -1
  128. package/dist/engine/renderers/Indicator/vwap.js +8 -2
  129. package/dist/engine/renderers/Indicator/vwap.js.map +1 -1
  130. package/dist/engine/renderers/Indicator/wma.d.ts.map +1 -1
  131. package/dist/engine/renderers/Indicator/wma.js +3 -2
  132. package/dist/engine/renderers/Indicator/wma.js.map +1 -1
  133. package/dist/engine/renderers/Indicator/wmsr.d.ts.map +1 -1
  134. package/dist/engine/renderers/Indicator/wmsr.js +9 -3
  135. package/dist/engine/renderers/Indicator/wmsr.js.map +1 -1
  136. package/dist/engine/renderers/Indicator/zones.d.ts.map +1 -1
  137. package/dist/engine/renderers/Indicator/zones.js +3 -2
  138. package/dist/engine/renderers/Indicator/zones.js.map +1 -1
  139. package/dist/version.d.ts +1 -1
  140. package/dist/version.js +1 -1
  141. package/package.json +6 -2
  142. package/src/engine/indicators/__tests__/registerBuiltins.test.ts +14 -22
  143. package/src/engine/indicators/__tests__/scheduler.test.ts +14 -14
  144. package/src/engine/indicators/__tests__/stateComposer.test.ts +7 -4
  145. package/src/engine/indicators/indicator.worker.ts +36 -4
  146. package/src/engine/indicators/indicatorDefinitionRegistry.ts +3 -1
  147. package/src/engine/indicators/indicatorMetadata.ts +29 -1
  148. package/src/engine/indicators/indicatorRuntime.ts +120 -1447
  149. package/src/engine/indicators/scheduler.ts +57 -485
  150. package/src/engine/indicators/stateComposer.ts +16 -60
  151. package/src/engine/indicators/workerProtocol.ts +14 -36
  152. package/src/engine/renderers/Indicator/atr.ts +9 -3
  153. package/src/engine/renderers/Indicator/boll.ts +4 -2
  154. package/src/engine/renderers/Indicator/cci.ts +9 -3
  155. package/src/engine/renderers/Indicator/chaikinVol.ts +8 -2
  156. package/src/engine/renderers/Indicator/cmf.ts +8 -2
  157. package/src/engine/renderers/Indicator/dema.ts +3 -2
  158. package/src/engine/renderers/Indicator/donchian.ts +3 -2
  159. package/src/engine/renderers/Indicator/ene.ts +5 -3
  160. package/src/engine/renderers/Indicator/expma.ts +3 -1
  161. package/src/engine/renderers/Indicator/fastk.ts +9 -3
  162. package/src/engine/renderers/Indicator/fib.ts +3 -2
  163. package/src/engine/renderers/Indicator/hma.ts +3 -2
  164. package/src/engine/renderers/Indicator/hv.ts +3 -2
  165. package/src/engine/renderers/Indicator/ichimoku.ts +3 -2
  166. package/src/engine/renderers/Indicator/kama.ts +3 -2
  167. package/src/engine/renderers/Indicator/keltner.ts +3 -2
  168. package/src/engine/renderers/Indicator/kst.ts +4 -3
  169. package/src/engine/renderers/Indicator/ma.ts +3 -2
  170. package/src/engine/renderers/Indicator/macd.ts +9 -9
  171. package/src/engine/renderers/Indicator/mfi.ts +8 -2
  172. package/src/engine/renderers/Indicator/mom.ts +9 -3
  173. package/src/engine/renderers/Indicator/obv.ts +8 -2
  174. package/src/engine/renderers/Indicator/parkinson.ts +3 -2
  175. package/src/engine/renderers/Indicator/pivot.ts +3 -2
  176. package/src/engine/renderers/Indicator/pvt.ts +8 -2
  177. package/src/engine/renderers/Indicator/roc.ts +8 -2
  178. package/src/engine/renderers/Indicator/rsi.ts +4 -3
  179. package/src/engine/renderers/Indicator/sar.ts +3 -2
  180. package/src/engine/renderers/Indicator/stoch.ts +4 -3
  181. package/src/engine/renderers/Indicator/structure.ts +3 -2
  182. package/src/engine/renderers/Indicator/supertrend.ts +3 -2
  183. package/src/engine/renderers/Indicator/tema.ts +3 -2
  184. package/src/engine/renderers/Indicator/trix.ts +3 -2
  185. package/src/engine/renderers/Indicator/vma.ts +8 -2
  186. package/src/engine/renderers/Indicator/volumeProfile.ts +3 -2
  187. package/src/engine/renderers/Indicator/vwap.ts +8 -2
  188. package/src/engine/renderers/Indicator/wma.ts +3 -2
  189. package/src/engine/renderers/Indicator/wmsr.ts +9 -3
  190. package/src/engine/renderers/Indicator/zones.ts +3 -2
  191. package/src/version.ts +1 -1
@@ -20,52 +20,13 @@ import type { IndicatorWorkerResponse } from './workerProtocol'
20
20
  import { isWorkerResponse, PROTOCOL_VERSION } from './workerProtocol'
21
21
  import { composeRenderStates, composeVisibleSubIndicatorStates, computeMainIndicatorPriceRange } from './stateComposer'
22
22
  import type {
23
- BOLLSchedulerConfig,
24
- EXPMASchedulerConfig,
25
- ENESchedulerConfig,
26
- RSISchedulerConfig,
27
- CCISchedulerConfig,
28
- STOCHSchedulerConfig,
29
- MOMSchedulerConfig,
30
- WMSRSchedulerConfig,
31
- KSTSchedulerConfig,
32
- FASTKSchedulerConfig,
33
- MACDSchedulerConfig,
34
- ATRSchedulerConfig,
35
- WMASchedulerConfig,
36
- DEMASchedulerConfig,
37
- TEMASchedulerConfig,
38
- HMASchedulerConfig,
39
- KAMASchedulerConfig,
40
- SARSchedulerConfig,
41
- SuperTrendSchedulerConfig,
42
- KeltnerSchedulerConfig,
43
- DonchianSchedulerConfig,
44
- IchimokuSchedulerConfig,
45
- ROCSchedulerConfig,
46
- TRIXSchedulerConfig,
47
- HVSchedulerConfig,
48
- ParkinsonSchedulerConfig,
49
- ChaikinVolSchedulerConfig,
50
- VMASchedulerConfig,
51
- OBVSchedulerConfig,
52
- PVTSchedulerConfig,
53
- VWAPSchedulerConfig,
54
- CMFSchedulerConfig,
55
- MFISchedulerConfig,
56
- PivotSchedulerConfig,
57
- FibSchedulerConfig,
58
- StructureSchedulerConfig,
59
- ZonesSchedulerConfig,
60
- VolumeProfileSchedulerConfig,
61
23
  IndicatorConfigSnapshot,
62
24
  IndicatorSeriesBundle,
25
+ SerializedRuntimeDescriptor,
63
26
  } from './workerProtocol'
64
- import type { MAFlags } from './calculators'
65
27
  import { IndicatorRegistry } from './indicatorRegistry'
66
28
  import { resolveStateKey, type IndicatorMetadata } from './indicatorMetadata'
67
29
  import type { BaseIndicatorState } from '../../plugin'
68
-
69
30
  // Default constants for default config
70
31
  import { DEFAULT_ATR_PERIOD } from './atrState'
71
32
  import { DEFAULT_WMA_PERIOD } from './wmaState'
@@ -159,6 +120,7 @@ export class IndicatorScheduler {
159
120
  // 当前数据和配置快照
160
121
  private currentData: KLineData[] = []
161
122
  private configSnapshot: IndicatorConfigSnapshot = this.getDefaultConfig()
123
+ private paneIdOverrides = new Map<string, string>()
162
124
 
163
125
  // Worker 相关
164
126
  private worker: Worker | null = null
@@ -202,6 +164,21 @@ export class IndicatorScheduler {
202
164
  console.warn(`[IndicatorScheduler] '${meta.name}' already registered, overwriting`)
203
165
  }
204
166
  this.registry.register(meta)
167
+ if (meta.runtime && this.inlineRuntime) {
168
+ this.inlineRuntime.addDescriptor(meta.runtime)
169
+ }
170
+ if (meta.runtime && this.useWorker && this.worker && this.workerReady) {
171
+ const rt = meta.runtime
172
+ this.worker.postMessage({
173
+ type: 'addDescriptor',
174
+ descriptor: {
175
+ configKey: rt.configKey,
176
+ paneIdKey: rt.paneIdKey,
177
+ defaultConfig: typeof rt.defaultConfig === 'function' ? (rt.defaultConfig as () => any)() : rt.defaultConfig,
178
+ computeKey: rt.computeKey,
179
+ } as SerializedRuntimeDescriptor,
180
+ })
181
+ }
205
182
  this.configVersion++
206
183
  this.triggerRecompute()
207
184
  console.log(`[IndicatorScheduler] Registered indicator '${meta.name}' (${meta.displayName})`)
@@ -403,41 +380,6 @@ export class IndicatorScheduler {
403
380
  showPOC: true,
404
381
  showValueArea: true,
405
382
  },
406
- rsiPaneId: 'sub_RSI',
407
- cciPaneId: 'sub_CCI',
408
- stochPaneId: 'sub_STOCH',
409
- momPaneId: 'sub_MOM',
410
- wmsrPaneId: 'sub_WMSR',
411
- kstPaneId: 'sub_KST',
412
- fastkPaneId: 'sub_FASTK',
413
- macdPaneId: 'sub_MACD',
414
- atrPaneId: 'sub_ATR',
415
- wmaPaneId: 'sub_WMA',
416
- demaPaneId: 'sub_DEMA',
417
- temaPaneId: 'sub_TEMA',
418
- hmaPaneId: 'sub_HMA',
419
- kamaPaneId: 'sub_KAMA',
420
- sarPaneId: 'sub_SAR',
421
- supertrendPaneId: 'sub_SuperTrend',
422
- keltnerPaneId: 'sub_Keltner',
423
- donchianPaneId: 'sub_Donchian',
424
- ichimokuPaneId: 'sub_Ichimoku',
425
- rocPaneId: 'sub_ROC',
426
- trixPaneId: 'sub_TRIX',
427
- hvPaneId: 'sub_HV',
428
- parkinsonPaneId: 'sub_Parkinson',
429
- chaikinVolPaneId: 'sub_ChaikinVol',
430
- vmaPaneId: 'sub_VMA',
431
- obvPaneId: 'sub_OBV',
432
- pvtPaneId: 'sub_PVT',
433
- vwapPaneId: 'sub_VWAP',
434
- cmfPaneId: 'sub_CMF',
435
- mfiPaneId: 'sub_MFI',
436
- pivotPaneId: 'sub_Pivot',
437
- fibPaneId: 'sub_Fib',
438
- structurePaneId: 'sub_Structure',
439
- zonesPaneId: 'sub_Zones',
440
- volumeProfilePaneId: 'sub_VolumeProfile',
441
383
  }
442
384
  }
443
385
 
@@ -456,8 +398,7 @@ export class IndicatorScheduler {
456
398
  return false
457
399
  }
458
400
  try {
459
- // Vite 模块 Worker
460
- const workerUrl = new URL('./indicator.worker.ts', import.meta.url)
401
+ const workerUrl = new URL('./indicator.worker.js', import.meta.url)
461
402
  console.log('[IndicatorScheduler] Creating worker from:', workerUrl.href)
462
403
  this.worker = new Worker(workerUrl, { type: 'module' })
463
404
  console.log('[IndicatorScheduler] Worker created, waiting for ready...')
@@ -466,7 +407,6 @@ export class IndicatorScheduler {
466
407
  console.error('[IndicatorScheduler] Worker error:', err)
467
408
  this.fallbackToInline()
468
409
  }
469
- // 发送 init
470
410
  this.worker.postMessage({
471
411
  type: 'init',
472
412
  protocolVersion: PROTOCOL_VERSION,
@@ -480,7 +420,10 @@ export class IndicatorScheduler {
480
420
 
481
421
  private initInlineRuntime(): void {
482
422
  console.log('[IndicatorScheduler] Using INLINE runtime (fallback)')
483
- this.inlineRuntime = new IndicatorRuntime()
423
+ const runtimeDescs = this.registry.getAll()
424
+ .filter(m => m.runtime)
425
+ .map(m => m.runtime!)
426
+ this.inlineRuntime = new IndicatorRuntime(runtimeDescs)
484
427
  this.useWorker = false
485
428
  this.workerReady = true
486
429
  }
@@ -519,7 +462,19 @@ export class IndicatorScheduler {
519
462
  this.workerReady = true
520
463
  this.useWorker = true
521
464
  console.log('[IndicatorScheduler] Worker READY - using Worker backend')
522
- // Worker 就绪后补算一次,但仅在有数据时(避免空数据产出 Infinity 极值)
465
+ for (const meta of this.registry.getAll()) {
466
+ if (!meta.runtime) continue
467
+ const rt = meta.runtime
468
+ this.worker!.postMessage({
469
+ type: 'addDescriptor',
470
+ descriptor: {
471
+ configKey: rt.configKey,
472
+ paneIdKey: rt.paneIdKey,
473
+ defaultConfig: typeof rt.defaultConfig === 'function' ? (rt.defaultConfig as () => any)() : rt.defaultConfig,
474
+ computeKey: rt.computeKey,
475
+ } as SerializedRuntimeDescriptor,
476
+ })
477
+ }
523
478
  if (this.currentData.length > 0) {
524
479
  this.triggerRecompute()
525
480
  }
@@ -605,9 +560,7 @@ export class IndicatorScheduler {
605
560
  meta.displayName,
606
561
  )
607
562
 
608
- const paneId = meta.paneIdField
609
- ? (this.configSnapshot as unknown as Record<string, string>)[meta.paneIdField as string]
610
- : meta.defaultPaneId
563
+ const paneId = this.paneIdOverrides.get(meta.name) ?? meta.defaultPaneId
611
564
 
612
565
  meta.applyResult(this.pluginHost, state as BaseIndicatorState, paneId)
613
566
  }
@@ -634,9 +587,7 @@ export class IndicatorScheduler {
634
587
 
635
588
  let state: unknown
636
589
  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
590
+ const paneId = this.paneIdOverrides.get(meta.name) ?? meta.defaultPaneId
640
591
  const current = this.pluginHost.getSharedState<BaseIndicatorState & { visibleMin?: number; visibleMax?: number }>(
641
592
  resolveStateKey(meta.stateKey, paneId),
642
593
  )
@@ -663,9 +614,7 @@ export class IndicatorScheduler {
663
614
  meta.displayName,
664
615
  )
665
616
 
666
- const paneId = meta.paneIdField
667
- ? (this.configSnapshot as unknown as Record<string, string>)[meta.paneIdField as string]
668
- : meta.defaultPaneId
617
+ const paneId = this.paneIdOverrides.get(meta.name) ?? meta.defaultPaneId
669
618
 
670
619
  meta.applyResult(this.pluginHost, state as BaseIndicatorState, paneId)
671
620
  if (meta.category === 'main') {
@@ -681,8 +630,7 @@ export class IndicatorScheduler {
681
630
  const activeIds = this.getActiveSubPaneIds?.() ?? []
682
631
  const mask: Record<string, boolean> = {}
683
632
  for (const meta of this.registry.getAll()) {
684
- if (!meta.paneIdField) continue
685
- const paneId = (this.configSnapshot as unknown as Record<string, string>)[meta.paneIdField as string] ?? meta.defaultPaneId
633
+ const paneId = this.paneIdOverrides.get(meta.name) ?? meta.defaultPaneId
686
634
  mask[meta.name] = activeIds.includes(paneId) || !!(meta.allowMainPane && paneId === 'main')
687
635
  }
688
636
  return mask
@@ -695,8 +643,7 @@ export class IndicatorScheduler {
695
643
 
696
644
  const cfg: Record<string, unknown> = { ...this.configSnapshot }
697
645
  for (const meta of this.registry.getAll()) {
698
- if (!meta.paneIdField) continue
699
- const paneId = cfg[meta.paneIdField] as string
646
+ const paneId = this.paneIdOverrides.get(meta.name) ?? meta.defaultPaneId
700
647
  if (!activeIds.includes(paneId) && paneId !== 'main') {
701
648
  const subCfg = { ...(cfg[meta.name] as Record<string, unknown>) }
702
649
  for (const k of Object.keys(subCfg)) {
@@ -745,404 +692,26 @@ export class IndicatorScheduler {
745
692
  }
746
693
  }
747
694
 
748
- /**
749
- * MA 配置变更
750
- */
751
- updateMAConfig(config: MAFlags): void {
752
- this.configSnapshot.ma = { ...config }
753
- this.configVersion++
754
- this.triggerRecompute()
755
- }
756
-
757
- /**
758
- * BOLL 配置变更
759
- */
760
- updateBOLLConfig(config: Partial<BOLLSchedulerConfig>): void {
761
- this.configSnapshot.boll = { ...this.configSnapshot.boll, ...config }
762
- this.configVersion++
763
- this.triggerRecompute()
764
- }
765
-
766
- /**
767
- * EXPMA 配置变更
768
- */
769
- updateEXPMAConfig(config: Partial<EXPMASchedulerConfig>): void {
770
- this.configSnapshot.expma = { ...this.configSnapshot.expma, ...config }
771
- this.configVersion++
772
- this.triggerRecompute()
773
- }
774
-
775
- /**
776
- * ENE 配置变更
777
- */
778
- updateENEConfig(config: Partial<ENESchedulerConfig>): void {
779
- this.configSnapshot.ene = { ...this.configSnapshot.ene, ...config }
780
- this.configVersion++
781
- this.triggerRecompute()
782
- }
783
-
784
- /**
785
- * RSI 配置变更
786
- */
787
- updateRSIConfig(config: Partial<RSISchedulerConfig>, paneId?: string): void {
788
- if (paneId !== undefined) {
789
- this.configSnapshot.rsiPaneId = paneId
790
- }
791
- this.configSnapshot.rsi = { ...this.configSnapshot.rsi, ...config }
792
- this.configVersion++
793
- this.triggerRecompute()
794
- }
795
-
796
- /**
797
- * CCI 配置变更
798
- */
799
- updateCCIConfig(config: Partial<CCISchedulerConfig>, paneId?: string): void {
800
- if (paneId !== undefined) {
801
- this.configSnapshot.cciPaneId = paneId
802
- }
803
- this.configSnapshot.cci = { ...this.configSnapshot.cci, ...config }
804
- this.configVersion++
805
- this.triggerRecompute()
806
- }
807
-
808
- /**
809
- * STOCH 配置变更
810
- */
811
- updateSTOCHConfig(config: Partial<STOCHSchedulerConfig>, paneId?: string): void {
812
- if (paneId !== undefined) {
813
- this.configSnapshot.stochPaneId = paneId
814
- }
815
- this.configSnapshot.stoch = { ...this.configSnapshot.stoch, ...config }
816
- this.configVersion++
817
- this.triggerRecompute()
818
- }
819
-
820
- /**
821
- * MOM 配置变更
822
- */
823
- updateMOMConfig(config: Partial<MOMSchedulerConfig>, paneId?: string): void {
824
- if (paneId !== undefined) {
825
- this.configSnapshot.momPaneId = paneId
826
- }
827
- this.configSnapshot.mom = { ...this.configSnapshot.mom, ...config }
828
- this.configVersion++
829
- this.triggerRecompute()
830
- }
831
-
832
- /**
833
- * WMSR 配置变更
834
- */
835
- updateWMSRConfig(config: Partial<WMSRSchedulerConfig>, paneId?: string): void {
836
- if (paneId !== undefined) {
837
- this.configSnapshot.wmsrPaneId = paneId
838
- }
839
- this.configSnapshot.wmsr = { ...this.configSnapshot.wmsr, ...config }
840
- this.configVersion++
841
- this.triggerRecompute()
842
- }
843
-
844
- /**
845
- * KST 配置变更
846
- */
847
- updateKSTConfig(config: Partial<KSTSchedulerConfig>, paneId?: string): void {
848
- if (paneId !== undefined) {
849
- this.configSnapshot.kstPaneId = paneId
850
- }
851
- this.configSnapshot.kst = { ...this.configSnapshot.kst, ...config }
852
- this.configVersion++
853
- this.triggerRecompute()
854
- }
855
-
856
- /**
857
- * FASTK 配置变更
858
- */
859
- updateFASTKConfig(config: Partial<FASTKSchedulerConfig>, paneId?: string): void {
860
- if (paneId !== undefined) {
861
- this.configSnapshot.fastkPaneId = paneId
862
- }
863
- this.configSnapshot.fastk = { ...this.configSnapshot.fastk, ...config }
864
- this.configVersion++
865
- this.triggerRecompute()
866
- }
867
-
868
- /**
869
- * MACD 配置变更
870
- */
871
- updateMACDConfig(config: Partial<MACDSchedulerConfig>, paneId?: string): void {
872
- if (paneId !== undefined) {
873
- this.configSnapshot.macdPaneId = paneId
874
- }
875
- this.configSnapshot.macd = { ...this.configSnapshot.macd, ...config }
876
- this.configVersion++
877
- this.triggerRecompute()
878
- }
879
-
880
- /**
881
- * ATR 配置变更
882
- */
883
- updateATRConfig(config: Partial<ATRSchedulerConfig>, paneId?: string): void {
884
- if (paneId !== undefined) {
885
- this.configSnapshot.atrPaneId = paneId
886
- }
887
- this.configSnapshot.atr = { ...this.configSnapshot.atr, ...config }
888
- this.configVersion++
889
- this.triggerRecompute()
890
- }
891
-
892
- /**
893
- * WMA 配置变更
894
- */
895
- updateWMAConfig(config: Partial<WMASchedulerConfig>, paneId?: string): void {
896
- if (paneId !== undefined) {
897
- this.configSnapshot.wmaPaneId = paneId
898
- }
899
- this.configSnapshot.wma = { ...this.configSnapshot.wma, ...config }
900
- this.configVersion++
901
- this.triggerRecompute()
902
- }
903
-
904
- /**
905
- * DEMA 配置变更
906
- */
907
- updateDEMAConfig(config: Partial<DEMASchedulerConfig>, paneId?: string): void {
908
- if (paneId !== undefined) {
909
- this.configSnapshot.demaPaneId = paneId
910
- }
911
- this.configSnapshot.dema = { ...this.configSnapshot.dema, ...config }
912
- this.configVersion++
913
- this.triggerRecompute()
914
- }
915
-
916
- /**
917
- * TEMA 配置变更
918
- */
919
- updateTEMAConfig(config: Partial<TEMASchedulerConfig>, paneId?: string): void {
920
- if (paneId !== undefined) {
921
- this.configSnapshot.temaPaneId = paneId
922
- }
923
- this.configSnapshot.tema = { ...this.configSnapshot.tema, ...config }
924
- this.configVersion++
925
- this.triggerRecompute()
926
- }
927
695
 
928
696
  /**
929
- * HMA 配置变更
697
+ * 通用指标配置变更入口
930
698
  */
931
- updateHMAConfig(config: Partial<HMASchedulerConfig>, paneId?: string): void {
932
- if (paneId !== undefined) {
933
- this.configSnapshot.hmaPaneId = paneId
699
+ updateIndicatorConfig(indicatorId: string, config: Record<string, unknown>, paneId?: string): void {
700
+ const meta = this.registry.get(indicatorId)
701
+ if (!meta?.runtime) {
702
+ console.warn(`[IndicatorScheduler] Unknown or unregistered indicator: ${indicatorId}`)
703
+ return
934
704
  }
935
- this.configSnapshot.hma = { ...this.configSnapshot.hma, ...config }
936
- this.configVersion++
937
- this.triggerRecompute()
938
- }
939
-
940
- /**
941
- * KAMA 配置变更
942
- */
943
- updateKAMAConfig(config: Partial<KAMASchedulerConfig>, paneId?: string): void {
705
+ const rt = meta.runtime
706
+ // Update paneId if provided
944
707
  if (paneId !== undefined) {
945
- this.configSnapshot.kamaPaneId = paneId
708
+ this.paneIdOverrides.set(indicatorId, paneId)
946
709
  }
947
- this.configSnapshot.kama = { ...this.configSnapshot.kama, ...config }
948
- this.configVersion++
949
- this.triggerRecompute()
950
- }
951
-
952
- /**
953
- * SAR 配置变更
954
- */
955
- updateSARConfig(config: Partial<SARSchedulerConfig>, paneId?: string): void {
956
- if (paneId !== undefined) {
957
- this.configSnapshot.sarPaneId = paneId
710
+ // Merge config
711
+ ;(this.configSnapshot as any)[rt.configKey] = {
712
+ ...((this.configSnapshot as any)[rt.configKey] ?? {}),
713
+ ...config,
958
714
  }
959
- this.configSnapshot.sar = { ...this.configSnapshot.sar, ...config }
960
- this.configVersion++
961
- this.triggerRecompute()
962
- }
963
-
964
- /**
965
- * SuperTrend 配置变更
966
- */
967
- updateSuperTrendConfig(config: Partial<SuperTrendSchedulerConfig>, paneId?: string): void {
968
- if (paneId !== undefined) this.configSnapshot.supertrendPaneId = paneId
969
- this.configSnapshot.supertrend = { ...this.configSnapshot.supertrend, ...config }
970
- this.configVersion++
971
- this.triggerRecompute()
972
- }
973
-
974
- /**
975
- * Keltner 配置变更
976
- */
977
- updateKeltnerConfig(config: Partial<KeltnerSchedulerConfig>, paneId?: string): void {
978
- if (paneId !== undefined) this.configSnapshot.keltnerPaneId = paneId
979
- this.configSnapshot.keltner = { ...this.configSnapshot.keltner, ...config }
980
- this.configVersion++
981
- this.triggerRecompute()
982
- }
983
-
984
- /**
985
- * Donchian 配置变更
986
- */
987
- updateDonchianConfig(config: Partial<DonchianSchedulerConfig>, paneId?: string): void {
988
- if (paneId !== undefined) this.configSnapshot.donchianPaneId = paneId
989
- this.configSnapshot.donchian = { ...this.configSnapshot.donchian, ...config }
990
- this.configVersion++
991
- this.triggerRecompute()
992
- }
993
-
994
- /**
995
- * Ichimoku 配置变更
996
- */
997
- updateIchimokuConfig(config: Partial<IchimokuSchedulerConfig>, paneId?: string): void {
998
- if (paneId !== undefined) this.configSnapshot.ichimokuPaneId = paneId
999
- this.configSnapshot.ichimoku = { ...this.configSnapshot.ichimoku, ...config }
1000
- this.configVersion++
1001
- this.triggerRecompute()
1002
- }
1003
-
1004
- /**
1005
- * ROC 配置变更
1006
- */
1007
- updateROCConfig(config: Partial<ROCSchedulerConfig>, paneId?: string): void {
1008
- if (paneId !== undefined) this.configSnapshot.rocPaneId = paneId
1009
- this.configSnapshot.roc = { ...this.configSnapshot.roc, ...config }
1010
- this.configVersion++
1011
- this.triggerRecompute()
1012
- }
1013
-
1014
- /**
1015
- * TRIX 配置变更
1016
- */
1017
- updateTRIXConfig(config: Partial<TRIXSchedulerConfig>, paneId?: string): void {
1018
- if (paneId !== undefined) this.configSnapshot.trixPaneId = paneId
1019
- this.configSnapshot.trix = { ...this.configSnapshot.trix, ...config }
1020
- this.configVersion++
1021
- this.triggerRecompute()
1022
- }
1023
-
1024
- /**
1025
- * HV 配置变更
1026
- */
1027
- updateHVConfig(config: Partial<HVSchedulerConfig>, paneId?: string): void {
1028
- if (paneId !== undefined) this.configSnapshot.hvPaneId = paneId
1029
- this.configSnapshot.hv = { ...this.configSnapshot.hv, ...config }
1030
- this.configVersion++
1031
- this.triggerRecompute()
1032
- }
1033
-
1034
- /**
1035
- * Parkinson 配置变更
1036
- */
1037
- updateParkinsonConfig(config: Partial<ParkinsonSchedulerConfig>, paneId?: string): void {
1038
- if (paneId !== undefined) this.configSnapshot.parkinsonPaneId = paneId
1039
- this.configSnapshot.parkinson = { ...this.configSnapshot.parkinson, ...config }
1040
- this.configVersion++
1041
- this.triggerRecompute()
1042
- }
1043
-
1044
- /**
1045
- * ChaikinVol 配置变更
1046
- */
1047
- updateChaikinVolConfig(config: Partial<ChaikinVolSchedulerConfig>, paneId?: string): void {
1048
- if (paneId !== undefined) this.configSnapshot.chaikinVolPaneId = paneId
1049
- this.configSnapshot.chaikinVol = { ...this.configSnapshot.chaikinVol, ...config }
1050
- this.configVersion++
1051
- this.triggerRecompute()
1052
- }
1053
-
1054
- /**
1055
- * VMA 配置变更
1056
- */
1057
- updateVMAConfig(config: Partial<VMASchedulerConfig>, paneId?: string): void {
1058
- if (paneId !== undefined) this.configSnapshot.vmaPaneId = paneId
1059
- this.configSnapshot.vma = { ...this.configSnapshot.vma, ...config }
1060
- this.configVersion++
1061
- this.triggerRecompute()
1062
- }
1063
-
1064
- /**
1065
- * OBV 配置变更
1066
- */
1067
- updateOBVConfig(config: Partial<OBVSchedulerConfig>, paneId?: string): void {
1068
- if (paneId !== undefined) this.configSnapshot.obvPaneId = paneId
1069
- this.configSnapshot.obv = { ...this.configSnapshot.obv, ...config }
1070
- this.configVersion++
1071
- this.triggerRecompute()
1072
- }
1073
-
1074
- /**
1075
- * PVT 配置变更
1076
- */
1077
- updatePVTConfig(config: Partial<PVTSchedulerConfig>, paneId?: string): void {
1078
- if (paneId !== undefined) this.configSnapshot.pvtPaneId = paneId
1079
- this.configSnapshot.pvt = { ...this.configSnapshot.pvt, ...config }
1080
- this.configVersion++
1081
- this.triggerRecompute()
1082
- }
1083
-
1084
- /**
1085
- * VWAP 配置变更
1086
- */
1087
- updateVWAPConfig(config: Partial<VWAPSchedulerConfig>, paneId?: string): void {
1088
- if (paneId !== undefined) this.configSnapshot.vwapPaneId = paneId
1089
- this.configSnapshot.vwap = { ...this.configSnapshot.vwap, ...config }
1090
- this.configVersion++
1091
- this.triggerRecompute()
1092
- }
1093
-
1094
- /** CMF 配置变更 */
1095
- updateCMFConfig(config: Partial<CMFSchedulerConfig>, paneId?: string): void {
1096
- if (paneId !== undefined) this.configSnapshot.cmfPaneId = paneId
1097
- this.configSnapshot.cmf = { ...this.configSnapshot.cmf, ...config }
1098
- this.configVersion++
1099
- this.triggerRecompute()
1100
- }
1101
-
1102
- /** MFI 配置变更 */
1103
- updateMFIConfig(config: Partial<MFISchedulerConfig>, paneId?: string): void {
1104
- if (paneId !== undefined) this.configSnapshot.mfiPaneId = paneId
1105
- this.configSnapshot.mfi = { ...this.configSnapshot.mfi, ...config }
1106
- this.configVersion++
1107
- this.triggerRecompute()
1108
- }
1109
-
1110
- /** Pivot 配置变更 */
1111
- updatePivotConfig(config: Partial<PivotSchedulerConfig>, paneId?: string): void {
1112
- if (paneId !== undefined) this.configSnapshot.pivotPaneId = paneId
1113
- this.configSnapshot.pivot = { ...this.configSnapshot.pivot, ...config }
1114
- this.configVersion++
1115
- this.triggerRecompute()
1116
- }
1117
-
1118
- /** Fib 配置变更 */
1119
- updateFibConfig(config: Partial<FibSchedulerConfig>, paneId?: string): void {
1120
- if (paneId !== undefined) this.configSnapshot.fibPaneId = paneId
1121
- this.configSnapshot.fib = { ...this.configSnapshot.fib, ...config }
1122
- this.configVersion++
1123
- this.triggerRecompute()
1124
- }
1125
-
1126
- /** Structure 配置变更 */
1127
- updateStructureConfig(config: Partial<StructureSchedulerConfig>, paneId?: string): void {
1128
- if (paneId !== undefined) this.configSnapshot.structurePaneId = paneId
1129
- this.configSnapshot.structure = { ...this.configSnapshot.structure, ...config }
1130
- this.configVersion++
1131
- this.triggerRecompute()
1132
- }
1133
-
1134
- /** Zones 配置变更 */
1135
- updateZonesConfig(config: Partial<ZonesSchedulerConfig>, paneId?: string): void {
1136
- if (paneId !== undefined) this.configSnapshot.zonesPaneId = paneId
1137
- this.configSnapshot.zones = { ...this.configSnapshot.zones, ...config }
1138
- this.configVersion++
1139
- this.triggerRecompute()
1140
- }
1141
-
1142
- /** Volume Profile 配置变更 */
1143
- updateVolumeProfileConfig(config: Partial<VolumeProfileSchedulerConfig>, paneId?: string): void {
1144
- if (paneId !== undefined) this.configSnapshot.volumeProfilePaneId = paneId
1145
- this.configSnapshot.volumeProfile = { ...this.configSnapshot.volumeProfile, ...config }
1146
715
  this.configVersion++
1147
716
  this.triggerRecompute()
1148
717
  }
@@ -1231,7 +800,10 @@ export class IndicatorScheduler {
1231
800
 
1232
801
  private computeWithInline(): void {
1233
802
  if (!this.inlineRuntime) {
1234
- this.inlineRuntime = new IndicatorRuntime()
803
+ const runtimeDescs = this.registry.getAll()
804
+ .filter(m => m.runtime)
805
+ .map(m => m.runtime!)
806
+ this.inlineRuntime = new IndicatorRuntime(runtimeDescs)
1235
807
  }
1236
808
 
1237
809
  console.log(`[IndicatorScheduler] >> INLINE compute: dataV=${this.dataVersion} configV=${this.configVersion}`)