@363045841yyt/klinechart-core 0.7.3 → 0.7.5

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 (247) hide show
  1. package/README.md +201 -201
  2. package/README.zh-CN.md +201 -201
  3. package/dist/controllers/index.d.ts +1 -0
  4. package/dist/controllers/index.d.ts.map +1 -1
  5. package/dist/controllers/index.js +1 -0
  6. package/dist/controllers/index.js.map +1 -1
  7. package/dist/engine/chart.d.ts +11 -19
  8. package/dist/engine/chart.d.ts.map +1 -1
  9. package/dist/engine/chart.js +92 -109
  10. package/dist/engine/chart.js.map +1 -1
  11. package/dist/engine/renderers/Indicator/indicatorData.d.ts +1 -0
  12. package/dist/engine/renderers/Indicator/indicatorData.d.ts.map +1 -1
  13. package/dist/engine/renderers/Indicator/indicatorData.js +1 -1
  14. package/dist/engine/renderers/Indicator/indicatorData.js.map +1 -1
  15. package/dist/engine/renderers/webgl/candleSurface.js +47 -47
  16. package/dist/engine/subPaneManager.d.ts +4 -0
  17. package/dist/engine/subPaneManager.d.ts.map +1 -1
  18. package/dist/engine/subPaneManager.js +13 -0
  19. package/dist/engine/subPaneManager.js.map +1 -1
  20. package/dist/version.d.ts +1 -1
  21. package/dist/version.d.ts.map +1 -1
  22. package/dist/version.js +1 -2
  23. package/dist/version.js.map +1 -1
  24. package/package.json +129 -122
  25. package/src/__tests__/signal.test.ts +124 -124
  26. package/src/config/chartSettings.ts +66 -66
  27. package/src/controllers/__tests__/drawing.test.ts +214 -214
  28. package/src/controllers/__tests__/indicatorSelector.test.ts +481 -481
  29. package/src/controllers/__tests__/toolbar.test.ts +225 -225
  30. package/src/controllers/createChartController.ts +665 -665
  31. package/src/controllers/createDrawingController.ts +96 -96
  32. package/src/controllers/createIndicatorSelectorController.ts +307 -307
  33. package/src/controllers/createToolbarController.ts +146 -146
  34. package/src/controllers/index.ts +20 -19
  35. package/src/controllers/types.ts +284 -284
  36. package/src/engine/__tests__/chart.dpr.test.ts +401 -401
  37. package/src/engine/__tests__/paneRenderer.resize.test.ts +92 -92
  38. package/src/engine/chart-store.ts +121 -121
  39. package/src/engine/chart.d.ts +617 -617
  40. package/src/engine/chart.ts +2803 -2815
  41. package/src/engine/controller/__tests__/interaction.dpr.test.ts +259 -259
  42. package/src/engine/controller/interaction.ts +722 -722
  43. package/src/engine/controller/markerInteraction.ts +130 -130
  44. package/src/engine/controller/pinchTracker.ts +82 -82
  45. package/src/engine/controller/tooltipPosition.ts +48 -48
  46. package/src/engine/draw/__tests__/pixelAlign.spec.ts +176 -176
  47. package/src/engine/draw/pixelAlign.ts +259 -259
  48. package/src/engine/drawing/index.ts +655 -655
  49. package/src/engine/drawing/interaction.ts +842 -842
  50. package/src/engine/drawing/plugin.ts +343 -343
  51. package/src/engine/indicators/__tests__/__fixtures__/golden/atr.json +38 -38
  52. package/src/engine/indicators/__tests__/__fixtures__/golden/dema.json +14 -14
  53. package/src/engine/indicators/__tests__/__fixtures__/golden/hma.json +14 -14
  54. package/src/engine/indicators/__tests__/__fixtures__/golden/index.ts +55 -55
  55. package/src/engine/indicators/__tests__/__fixtures__/golden/kama.json +14 -14
  56. package/src/engine/indicators/__tests__/__fixtures__/golden/tema.json +14 -14
  57. package/src/engine/indicators/__tests__/__fixtures__/golden/wma.json +40 -40
  58. package/src/engine/indicators/__tests__/__fixtures__/synthetic.ts +65 -65
  59. package/src/engine/indicators/__tests__/_propertyAssertions.ts +76 -76
  60. package/src/engine/indicators/__tests__/atr.test.ts +153 -153
  61. package/src/engine/indicators/__tests__/calculators.test.ts +614 -614
  62. package/src/engine/indicators/__tests__/cmf-mfi.test.ts +100 -100
  63. package/src/engine/indicators/__tests__/dema.test.ts +73 -73
  64. package/src/engine/indicators/__tests__/donchian.test.ts +70 -70
  65. package/src/engine/indicators/__tests__/hma.test.ts +73 -73
  66. package/src/engine/indicators/__tests__/ichimoku.test.ts +105 -105
  67. package/src/engine/indicators/__tests__/kama.test.ts +80 -80
  68. package/src/engine/indicators/__tests__/keltner.test.ts +65 -65
  69. package/src/engine/indicators/__tests__/pivot-fib.test.ts +110 -110
  70. package/src/engine/indicators/__tests__/roc.test.ts +68 -68
  71. package/src/engine/indicators/__tests__/sar.test.ts +86 -86
  72. package/src/engine/indicators/__tests__/scheduler.test.ts +831 -831
  73. package/src/engine/indicators/__tests__/soa.test.ts +533 -533
  74. package/src/engine/indicators/__tests__/structure.test.ts +110 -110
  75. package/src/engine/indicators/__tests__/supertrend.test.ts +65 -65
  76. package/src/engine/indicators/__tests__/tema.test.ts +68 -68
  77. package/src/engine/indicators/__tests__/trix.test.ts +70 -70
  78. package/src/engine/indicators/__tests__/volatility.test.ts +117 -117
  79. package/src/engine/indicators/__tests__/volume.test.ts +115 -115
  80. package/src/engine/indicators/__tests__/volumeProfile.test.ts +74 -74
  81. package/src/engine/indicators/__tests__/vwap.test.ts +69 -69
  82. package/src/engine/indicators/__tests__/wma.test.ts +112 -112
  83. package/src/engine/indicators/__tests__/zones.test.ts +95 -95
  84. package/src/engine/indicators/atrState.ts +27 -27
  85. package/src/engine/indicators/bollState.ts +51 -51
  86. package/src/engine/indicators/calculators.ts +2593 -2593
  87. package/src/engine/indicators/cciState.ts +25 -25
  88. package/src/engine/indicators/chaikinVolState.ts +32 -32
  89. package/src/engine/indicators/cmfState.ts +27 -27
  90. package/src/engine/indicators/demaState.ts +27 -27
  91. package/src/engine/indicators/donchianState.ts +43 -43
  92. package/src/engine/indicators/eneState.ts +43 -43
  93. package/src/engine/indicators/expmaState.ts +43 -43
  94. package/src/engine/indicators/fastkState.ts +25 -25
  95. package/src/engine/indicators/fibState.ts +41 -41
  96. package/src/engine/indicators/hmaState.ts +27 -27
  97. package/src/engine/indicators/hvState.ts +28 -28
  98. package/src/engine/indicators/ichimokuState.ts +70 -70
  99. package/src/engine/indicators/indicator.worker.ts +169 -169
  100. package/src/engine/indicators/indicatorDefinitionRegistry.ts +62 -62
  101. package/src/engine/indicators/indicatorMetadata.ts +110 -110
  102. package/src/engine/indicators/indicatorRegistry.ts +106 -106
  103. package/src/engine/indicators/indicatorRuntime.ts +1548 -1548
  104. package/src/engine/indicators/kamaState.ts +34 -34
  105. package/src/engine/indicators/keltnerState.ts +49 -49
  106. package/src/engine/indicators/kstState.ts +42 -42
  107. package/src/engine/indicators/maState.ts +36 -36
  108. package/src/engine/indicators/macdState.ts +76 -76
  109. package/src/engine/indicators/mfiState.ts +27 -27
  110. package/src/engine/indicators/momState.ts +25 -25
  111. package/src/engine/indicators/obvState.ts +25 -25
  112. package/src/engine/indicators/parkinsonState.ts +28 -28
  113. package/src/engine/indicators/pivotState.ts +51 -51
  114. package/src/engine/indicators/pvtState.ts +25 -25
  115. package/src/engine/indicators/rocState.ts +27 -27
  116. package/src/engine/indicators/rsiState.ts +65 -65
  117. package/src/engine/indicators/sarState.ts +41 -41
  118. package/src/engine/indicators/scheduler.ts +1205 -1205
  119. package/src/engine/indicators/soa.ts +352 -352
  120. package/src/engine/indicators/stateComposer.ts +1262 -1262
  121. package/src/engine/indicators/stochState.ts +26 -26
  122. package/src/engine/indicators/structureState.ts +69 -69
  123. package/src/engine/indicators/supertrendState.ts +37 -37
  124. package/src/engine/indicators/temaState.ts +27 -27
  125. package/src/engine/indicators/trixState.ts +35 -35
  126. package/src/engine/indicators/vmaState.ts +27 -27
  127. package/src/engine/indicators/volumeProfileState.ts +63 -63
  128. package/src/engine/indicators/vwapState.ts +29 -29
  129. package/src/engine/indicators/wmaState.ts +27 -27
  130. package/src/engine/indicators/wmsrState.ts +25 -25
  131. package/src/engine/indicators/workerProtocol.ts +613 -613
  132. package/src/engine/indicators/zonesState.ts +47 -47
  133. package/src/engine/layout/pane.ts +161 -161
  134. package/src/engine/marker/registry.ts +265 -265
  135. package/src/engine/paneRenderer.ts +169 -169
  136. package/src/engine/renderers/Indicator/atr.ts +237 -237
  137. package/src/engine/renderers/Indicator/boll.ts +317 -317
  138. package/src/engine/renderers/Indicator/cci.ts +275 -275
  139. package/src/engine/renderers/Indicator/chaikinVol.ts +138 -138
  140. package/src/engine/renderers/Indicator/cmf.ts +137 -137
  141. package/src/engine/renderers/Indicator/dema.ts +136 -136
  142. package/src/engine/renderers/Indicator/donchian.ts +137 -137
  143. package/src/engine/renderers/Indicator/ene.ts +271 -271
  144. package/src/engine/renderers/Indicator/expma.ts +197 -197
  145. package/src/engine/renderers/Indicator/fastk.ts +316 -316
  146. package/src/engine/renderers/Indicator/fib.ts +141 -141
  147. package/src/engine/renderers/Indicator/hma.ts +136 -136
  148. package/src/engine/renderers/Indicator/hv.ts +124 -124
  149. package/src/engine/renderers/Indicator/ichimoku.ts +181 -181
  150. package/src/engine/renderers/Indicator/index.ts +241 -241
  151. package/src/engine/renderers/Indicator/indicatorData.ts +650 -650
  152. package/src/engine/renderers/Indicator/kama.ts +136 -136
  153. package/src/engine/renderers/Indicator/keltner.ts +137 -137
  154. package/src/engine/renderers/Indicator/kst.ts +302 -302
  155. package/src/engine/renderers/Indicator/ma.ts +200 -200
  156. package/src/engine/renderers/Indicator/macd.ts +477 -477
  157. package/src/engine/renderers/Indicator/macdLegend.ts +141 -141
  158. package/src/engine/renderers/Indicator/mainIndicatorLegend.ts +272 -272
  159. package/src/engine/renderers/Indicator/mfi.ts +142 -142
  160. package/src/engine/renderers/Indicator/mom.ts +311 -311
  161. package/src/engine/renderers/Indicator/obv.ts +123 -123
  162. package/src/engine/renderers/Indicator/parkinson.ts +124 -124
  163. package/src/engine/renderers/Indicator/pivot.ts +131 -131
  164. package/src/engine/renderers/Indicator/pvt.ts +123 -123
  165. package/src/engine/renderers/Indicator/roc.ts +143 -143
  166. package/src/engine/renderers/Indicator/rsi.ts +390 -390
  167. package/src/engine/renderers/Indicator/sar.ts +113 -113
  168. package/src/engine/renderers/Indicator/scale/atr_scale.ts +19 -19
  169. package/src/engine/renderers/Indicator/scale/cci_scale.ts +19 -19
  170. package/src/engine/renderers/Indicator/scale/fastk_scale.ts +19 -19
  171. package/src/engine/renderers/Indicator/scale/indicator_scale.ts +204 -204
  172. package/src/engine/renderers/Indicator/scale/kst_scale.ts +19 -19
  173. package/src/engine/renderers/Indicator/scale/macd_scale.ts +22 -22
  174. package/src/engine/renderers/Indicator/scale/mom_scale.ts +19 -19
  175. package/src/engine/renderers/Indicator/scale/rsi_scale.ts +19 -19
  176. package/src/engine/renderers/Indicator/scale/stoch_scale.ts +19 -19
  177. package/src/engine/renderers/Indicator/scale/volume_scale.ts +26 -26
  178. package/src/engine/renderers/Indicator/scale/wmsr_scale.ts +19 -19
  179. package/src/engine/renderers/Indicator/stoch.ts +359 -359
  180. package/src/engine/renderers/Indicator/structure.ts +126 -126
  181. package/src/engine/renderers/Indicator/subPaneConfig.ts +265 -265
  182. package/src/engine/renderers/Indicator/supertrend.ts +115 -115
  183. package/src/engine/renderers/Indicator/tema.ts +136 -136
  184. package/src/engine/renderers/Indicator/trix.ts +158 -158
  185. package/src/engine/renderers/Indicator/vma.ts +124 -124
  186. package/src/engine/renderers/Indicator/volumeProfile.ts +125 -125
  187. package/src/engine/renderers/Indicator/vwap.ts +123 -123
  188. package/src/engine/renderers/Indicator/wma.ts +136 -136
  189. package/src/engine/renderers/Indicator/wmsr.ts +328 -328
  190. package/src/engine/renderers/Indicator/zones.ts +104 -104
  191. package/src/engine/renderers/__tests__/boll.renderer.test.ts +314 -314
  192. package/src/engine/renderers/__tests__/ene.renderer.test.ts +305 -305
  193. package/src/engine/renderers/__tests__/expma.renderer.test.ts +279 -279
  194. package/src/engine/renderers/__tests__/ma.renderer.test.ts +426 -426
  195. package/src/engine/renderers/__tests__/mainIndicatorLegend.renderer.test.ts +502 -502
  196. package/src/engine/renderers/__tests__/yAxis.renderer.test.ts +173 -173
  197. package/src/engine/renderers/candle.ts +459 -459
  198. package/src/engine/renderers/crosshair.ts +69 -69
  199. package/src/engine/renderers/customMarkers.ts +162 -162
  200. package/src/engine/renderers/extremaMarkers.ts +246 -246
  201. package/src/engine/renderers/gridLines.ts +90 -90
  202. package/src/engine/renderers/lastPrice.ts +97 -97
  203. package/src/engine/renderers/paneTitle.ts +136 -136
  204. package/src/engine/renderers/subVolume.ts +236 -236
  205. package/src/engine/renderers/timeAxis.ts +121 -121
  206. package/src/engine/renderers/webgl/candleSurface.ts +955 -955
  207. package/src/engine/renderers/webgl/sharedWebGLSurface.ts +146 -146
  208. package/src/engine/renderers/yAxis.ts +105 -105
  209. package/src/engine/scale/__tests__/logFormula.spec.ts +148 -148
  210. package/src/engine/scale/logFormula.ts +130 -130
  211. package/src/engine/scale/price.ts +39 -39
  212. package/src/engine/scale/priceScale.ts +264 -264
  213. package/src/engine/subPaneManager.ts +442 -427
  214. package/src/engine/theme/colors.ts +642 -642
  215. package/src/engine/theme/fonts.ts +20 -20
  216. package/src/engine/utils/klineConfig.ts +49 -49
  217. package/src/engine/utils/tickCount.ts +11 -11
  218. package/src/engine/utils/tickPosition.ts +214 -214
  219. package/src/engine/utils/zoom.ts +83 -83
  220. package/src/engine/viewport/viewport.ts +67 -67
  221. package/src/index.ts +3 -3
  222. package/src/plugin/ConfigManager.ts +93 -93
  223. package/src/plugin/EventBus.ts +77 -77
  224. package/src/plugin/HookSystem.ts +106 -106
  225. package/src/plugin/PluginHost.ts +243 -243
  226. package/src/plugin/PluginRegistry.ts +92 -92
  227. package/src/plugin/StateStore.ts +73 -73
  228. package/src/plugin/index.ts +19 -19
  229. package/src/plugin/rendererPluginManager.ts +368 -368
  230. package/src/plugin/stateKeys.ts +8 -8
  231. package/src/plugin/types.ts +526 -526
  232. package/src/reactivity/index.ts +2 -2
  233. package/src/reactivity/signal.ts +119 -119
  234. package/src/semantic/controller.ts +251 -251
  235. package/src/semantic/drawShape.ts +260 -260
  236. package/src/semantic/index.ts +28 -28
  237. package/src/semantic/schema.json +256 -256
  238. package/src/semantic/types.ts +251 -251
  239. package/src/semantic/validator.ts +349 -349
  240. package/src/types/kLine.ts +13 -13
  241. package/src/types/price.ts +56 -56
  242. package/src/types/volumePrice.ts +33 -33
  243. package/src/utils/dateFormat.ts +208 -208
  244. package/src/utils/kLineDraw/axis.ts +562 -562
  245. package/src/utils/priceToY.ts +34 -34
  246. package/src/utils/volumePrice.ts +202 -202
  247. package/src/version.ts +1 -1
@@ -1,13 +1,13 @@
1
- import type { KLineData } from './price'
2
-
3
- export type kLineTrend = 'up' | 'down' | 'flat'
4
-
5
- export function getKLineTrend(KLineData: KLineData): kLineTrend {
6
- if (KLineData.open > KLineData.close) {
7
- return 'down'
8
- } else if (KLineData.open < KLineData.close) {
9
- return 'up'
10
- } else {
11
- return 'flat'
12
- }
13
- }
1
+ import type { KLineData } from './price'
2
+
3
+ export type kLineTrend = 'up' | 'down' | 'flat'
4
+
5
+ export function getKLineTrend(KLineData: KLineData): kLineTrend {
6
+ if (KLineData.open > KLineData.close) {
7
+ return 'down'
8
+ } else if (KLineData.open < KLineData.close) {
9
+ return 'up'
10
+ } else {
11
+ return 'flat'
12
+ }
13
+ }
@@ -1,56 +1,56 @@
1
- export interface KLineData {
2
- /* 时间戳(毫秒) */
3
- timestamp: number
4
- /* 开盘价 */
5
- open: number
6
- /* 最高价 */
7
- high: number
8
- /* 最低价 */
9
- low: number
10
- /* 收盘价 */
11
- close: number
12
- /** 股票代码(东财等数据源会提供) */
13
- stockCode?: string
14
- /** 成交量 */
15
- volume?: number
16
- /** 成交额 */
17
- turnover?: number
18
- /** 振幅 */
19
- amplitude?: number
20
- /** 涨跌幅 */
21
- changePercent?: number
22
- /** 涨跌额 */
23
- changeAmount?: number
24
- /** 换手率 */
25
- turnoverRate?: number
26
- }
27
-
28
- export interface KLineDailyDongCaiResponse extends KLineData {
29
- stockCode: string
30
- volume: number
31
- turnover: number
32
- amplitude: number
33
- changePercent: number
34
- changeAmount: number
35
- turnoverRate: number
36
- }
37
-
38
-
39
- export function toKLineData(arr: KLineDailyDongCaiResponse[]): KLineData[] {
40
- return arr
41
- .map((e) => ({
42
- timestamp: e.timestamp,
43
- open: e.open,
44
- high: e.high,
45
- low: e.low,
46
- close: e.close,
47
- stockCode: e.stockCode,
48
- volume: e.volume,
49
- turnover: e.turnover,
50
- amplitude: e.amplitude,
51
- changePercent: e.changePercent,
52
- changeAmount: e.changeAmount,
53
- turnoverRate: e.turnoverRate,
54
- }))
55
- .sort((a, b) => a.timestamp - b.timestamp)
56
- }
1
+ export interface KLineData {
2
+ /* 时间戳(毫秒) */
3
+ timestamp: number
4
+ /* 开盘价 */
5
+ open: number
6
+ /* 最高价 */
7
+ high: number
8
+ /* 最低价 */
9
+ low: number
10
+ /* 收盘价 */
11
+ close: number
12
+ /** 股票代码(东财等数据源会提供) */
13
+ stockCode?: string
14
+ /** 成交量 */
15
+ volume?: number
16
+ /** 成交额 */
17
+ turnover?: number
18
+ /** 振幅 */
19
+ amplitude?: number
20
+ /** 涨跌幅 */
21
+ changePercent?: number
22
+ /** 涨跌额 */
23
+ changeAmount?: number
24
+ /** 换手率 */
25
+ turnoverRate?: number
26
+ }
27
+
28
+ export interface KLineDailyDongCaiResponse extends KLineData {
29
+ stockCode: string
30
+ volume: number
31
+ turnover: number
32
+ amplitude: number
33
+ changePercent: number
34
+ changeAmount: number
35
+ turnoverRate: number
36
+ }
37
+
38
+
39
+ export function toKLineData(arr: KLineDailyDongCaiResponse[]): KLineData[] {
40
+ return arr
41
+ .map((e) => ({
42
+ timestamp: e.timestamp,
43
+ open: e.open,
44
+ high: e.high,
45
+ low: e.low,
46
+ close: e.close,
47
+ stockCode: e.stockCode,
48
+ volume: e.volume,
49
+ turnover: e.turnover,
50
+ amplitude: e.amplitude,
51
+ changePercent: e.changePercent,
52
+ changeAmount: e.changeAmount,
53
+ turnoverRate: e.turnoverRate,
54
+ }))
55
+ .sort((a, b) => a.timestamp - b.timestamp)
56
+ }
@@ -1,33 +1,33 @@
1
- /**
2
- * 量价关系类型枚举
3
- */
4
- export enum VolumePriceRelation {
5
- /** 量价齐升(放量上涨)- 价格上涨且成交量显著放大 */
6
- RISE_WITH_VOLUME = 'rise_with_volume',
7
- /** 量价背离(缩量上涨)- 价格上涨但成交量萎缩 */
8
- RISE_WITHOUT_VOLUME = 'rise_without_volume',
9
- /** 量增价跌 - 价格下跌且成交量放大 */
10
- FALL_WITH_VOLUME = 'fall_with_volume',
11
- /** 量缩价跌 - 价格下跌且成交量萎缩 */
12
- FALL_WITHOUT_VOLUME = 'fall_without_volume',
13
- /** 中性状态 - 其他情况 */
14
- OTHERS = 'others'
15
- }
16
-
17
- /** 量价关系计算配置 */
18
- export interface VolumePriceConfig {
19
- /** 成交量放大阈值(相对于均值的倍数) */
20
- volumeAmplifyThreshold: number
21
- /** 成交量萎缩阈值(相对于均值的倍数) */
22
- volumeShrinkThreshold: number
23
- /** 计算均值的周期 */
24
- avgPeriod: number
25
- }
26
-
27
- /** 默认量价关系计算配置 */
28
- export const DEFAULT_VOLUME_PRICE_CONFIG: VolumePriceConfig = {
29
- volumeAmplifyThreshold: 1.5,
30
- volumeShrinkThreshold: 0.8,
31
- avgPeriod: 20,
32
- }
33
-
1
+ /**
2
+ * 量价关系类型枚举
3
+ */
4
+ export enum VolumePriceRelation {
5
+ /** 量价齐升(放量上涨)- 价格上涨且成交量显著放大 */
6
+ RISE_WITH_VOLUME = 'rise_with_volume',
7
+ /** 量价背离(缩量上涨)- 价格上涨但成交量萎缩 */
8
+ RISE_WITHOUT_VOLUME = 'rise_without_volume',
9
+ /** 量增价跌 - 价格下跌且成交量放大 */
10
+ FALL_WITH_VOLUME = 'fall_with_volume',
11
+ /** 量缩价跌 - 价格下跌且成交量萎缩 */
12
+ FALL_WITHOUT_VOLUME = 'fall_without_volume',
13
+ /** 中性状态 - 其他情况 */
14
+ OTHERS = 'others'
15
+ }
16
+
17
+ /** 量价关系计算配置 */
18
+ export interface VolumePriceConfig {
19
+ /** 成交量放大阈值(相对于均值的倍数) */
20
+ volumeAmplifyThreshold: number
21
+ /** 成交量萎缩阈值(相对于均值的倍数) */
22
+ volumeShrinkThreshold: number
23
+ /** 计算均值的周期 */
24
+ avgPeriod: number
25
+ }
26
+
27
+ /** 默认量价关系计算配置 */
28
+ export const DEFAULT_VOLUME_PRICE_CONFIG: VolumePriceConfig = {
29
+ volumeAmplifyThreshold: 1.5,
30
+ volumeShrinkThreshold: 0.8,
31
+ avgPeriod: 20,
32
+ }
33
+
@@ -1,208 +1,208 @@
1
- /**
2
- * 日期格式化工具函数集合
3
- * 统一管理项目中所有日期相关的格式化逻辑
4
- */
5
-
6
- // ========== 模块级复用的 Intl.DateTimeFormat 实例 ==========
7
- // Intl.DateTimeFormat 构造极其昂贵(~36ms),必须复用
8
- const YMD_FORMATTER = new Intl.DateTimeFormat('zh-CN', {
9
- timeZone: 'Asia/Shanghai',
10
- year: 'numeric',
11
- month: '2-digit',
12
- day: '2-digit',
13
- })
14
-
15
- // ========== 缓存配置 ==========
16
- const YMD_CACHE_SIZE = 1024
17
- const ymdCache = new Map<number, string>()
18
-
19
- /**
20
- * 将时间戳格式化为 YYYYMMDD 格式(纯数字,无分隔符)
21
- * @param timestamp - 时间戳(毫秒)
22
- * @returns 格式化后的日期字符串,例如 "20250114"
23
- *
24
- * @example
25
- * formatDateToYYYYMMDDNoDash(1736793600000) // "20250114"
26
- */
27
- export function formatDateToYYYYMMDDNoDash(timestamp: number): string {
28
- const d = new Date(timestamp)
29
- const year = d.getFullYear()
30
- const month = String(d.getMonth() + 1).padStart(2, '0')
31
- const day = String(d.getDate()).padStart(2, '0')
32
- return `${year}${month}${day}`
33
- }
34
-
35
- /**
36
- * 获取当前日期的 YYYYMMDD 格式(纯数字,无分隔符)
37
- * @returns 当前日期的格式化字符串,例如 "20250114"
38
- *
39
- * @example
40
- * getCurrentDateYYYYMMDD() // "20250114"(根据实际日期)
41
- */
42
- export function getCurrentDateYYYYMMDD(): string {
43
- const d = new Date()
44
- const year = d.getFullYear()
45
- const month = String(d.getMonth() + 1).padStart(2, '0')
46
- const day = String(d.getDate()).padStart(2, '0')
47
- return `${year}${month}${day}`
48
- }
49
-
50
- /**
51
- * 将时间戳格式化为 YYYY-MM-DD 格式(上海时区)
52
- * @param timestamp - 时间戳(毫秒)
53
- * @returns 格式化后的日期字符串,例如 "2025-01-14"
54
- *
55
- * @example
56
- * formatDateToYYYYMMDD(1736793600000) // "2025-01-14"
57
- */
58
- export function formatDateToYYYYMMDD(timestamp: number): string {
59
- // 缓存命中检查
60
- const cached = ymdCache.get(timestamp)
61
- if (cached !== undefined) return cached
62
-
63
- // 使用复用的 formatter,避免每次构造开销
64
- const parts = YMD_FORMATTER.formatToParts(new Date(timestamp))
65
-
66
- // 用 for 循环替代 .reduce,避免临时对象分配
67
- let y = '', m = '', d = ''
68
- for (let i = 0; i < parts.length; i++) {
69
- const p = parts[i]
70
- if (p.type === 'year') y = p.value
71
- else if (p.type === 'month') m = p.value
72
- else if (p.type === 'day') d = p.value
73
- }
74
-
75
- const result = `${y}-${m}-${d}`
76
-
77
- // 写入缓存,防膨胀
78
- if (ymdCache.size >= YMD_CACHE_SIZE) ymdCache.clear()
79
- ymdCache.set(timestamp, result)
80
-
81
- return result
82
- }
83
-
84
- // ========== formatMonthOrYear 缓存 ==========
85
- const MONTH_YEAR_CACHE_SIZE = 512
86
- const monthYearCache = new Map<number, { text: string; isYear: boolean }>()
87
-
88
- /**
89
- * 格式化月份或年份用于显示
90
- * 当年为 1 月时显示年份,其他月份显示"X月"格式
91
- * @param timestamp - 时间戳(毫秒)
92
- * @returns 包含文本和是否为年份的标志
93
- *
94
- * @example
95
- * formatMonthOrYear(1704067200000) // { text: "2024", isYear: true } (2024年1月)
96
- * formatMonthOrYear(1706745600000) // { text: "2月", isYear: false } (2024年2月)
97
- */
98
- export function formatMonthOrYear(timestamp: number): { text: string; isYear: boolean } {
99
- // 缓存命中检查
100
- const cached = monthYearCache.get(timestamp)
101
- if (cached !== undefined) return cached
102
-
103
- const d = new Date(timestamp)
104
- const year = d.getFullYear()
105
- const month = d.getMonth() + 1
106
- // 当年 1 月:直接标注年份;其它月份:标注"X月"
107
- const result = month === 1 ? { text: String(year), isYear: true } : { text: `${month}月`, isYear: false }
108
-
109
- // 写入缓存,防膨胀
110
- if (monthYearCache.size >= MONTH_YEAR_CACHE_SIZE) monthYearCache.clear()
111
- monthYearCache.set(timestamp, result)
112
-
113
- return result
114
- }
115
-
116
- /**
117
- * 生成月份键值用于比较(YYYY-M 格式)
118
- * 注意:月份未补零,用于快速比较月份是否相同
119
- * @param timestamp - 时间戳(毫秒)
120
- * @returns 月份键值,例如 "2025-1"
121
- *
122
- * @example
123
- * monthKey(1736793600000) // "2025-1"
124
- */
125
- /**
126
- * 生成月份键值用于比较
127
- * 返回数字 year * 12 + month,比字符串比较更快且无分配
128
- * 使用 new Date 保证本地时区正确(与显示一致)
129
- *
130
- * @example
131
- * monthKey(1736793600000) // 24301 (2025*12 + 0)
132
- */
133
- export function monthKey(timestamp: number): number {
134
- const d = new Date(timestamp)
135
- return d.getFullYear() * 12 + d.getMonth()
136
- }
137
-
138
- // ========== 便捷别名 ==========
139
-
140
- /**
141
- * formatDateToYYYYMMDD 的别名,保持与历史代码的兼容性
142
- * timestamp 是"上海时区当天 00:00:00"映射到 UTC 的值;显示时强制按上海时区格式化
143
- * @param ts - 时间戳(毫秒)
144
- * @returns 格式化后的日期字符串,例如 "2025-01-14"
145
- */
146
- export const formatShanghaiDate = formatDateToYYYYMMDD
147
-
148
- /**
149
- * formatDateToYYYYMMDD 的别名,用于十字线日期标签显示
150
- * 按上海时区格式化,避免不同时区出现日期偏移
151
- * @param ts - 时间戳(毫秒)
152
- * @returns 格式化后的日期字符串,例如 "2025-01-14"
153
- */
154
- export const formatYMDShanghai = formatDateToYYYYMMDD
155
-
156
- /**
157
- * 查找每个月份第一个K线的索引
158
- * @param data - K线数据数组(按时间升序排列)
159
- * @returns 月边界索引数组,例如 [0, 30, 60] 表示第0、30、60个K线分别是每月的第一个交易日
160
- *
161
- * @example
162
- * // 假设数据:[1/2, 1/3, 2/1, 2/2, 3/1, 3/2]
163
- * findMonthBoundaries(data) // [0, 2, 4]
164
- * // 解释:第0个K线是1月第一个,第2个K线是2月第一个,第4个K线是3月第一个
165
- */
166
- // findMonthBoundaries 缓存
167
- let _cacheDataRef: Array<{ timestamp: number } | undefined> | null = null
168
- let _cacheLen = 0
169
- let _cacheFirstTs = 0
170
- let _cacheLastTs = 0
171
- let _cacheResult: number[] = []
172
-
173
- /**
174
- * 查找每个月份第一个K线的索引
175
- * 结果按数据引用缓存,同一份数据多次调用直接返回缓存
176
- */
177
- export function findMonthBoundaries(data: Array<{ timestamp: number } | undefined>): number[] {
178
- if (data.length === 0) return []
179
-
180
- // 缓存命中:同一引用 + 同长度 + 首尾时间戳不变
181
- if (_cacheDataRef === data && _cacheLen === data.length) {
182
- const firstTs = data[0]?.timestamp
183
- const lastTs = data[data.length - 1]?.timestamp
184
- if (firstTs === _cacheFirstTs && lastTs === _cacheLastTs) {
185
- return _cacheResult
186
- }
187
- }
188
-
189
- const boundaries: number[] = [0]
190
- let lastKey = monthKey(data[0]!.timestamp)
191
-
192
- for (let i = 1; i < data.length; i++) {
193
- const cur = data[i]
194
- if (!cur) continue
195
- const curKey = monthKey(cur.timestamp)
196
- if (curKey !== lastKey) {
197
- boundaries.push(i)
198
- lastKey = curKey
199
- }
200
- }
201
-
202
- _cacheDataRef = data
203
- _cacheLen = data.length
204
- _cacheFirstTs = data[0]?.timestamp ?? 0
205
- _cacheLastTs = data[data.length - 1]?.timestamp ?? 0
206
- _cacheResult = boundaries
207
- return boundaries
208
- }
1
+ /**
2
+ * 日期格式化工具函数集合
3
+ * 统一管理项目中所有日期相关的格式化逻辑
4
+ */
5
+
6
+ // ========== 模块级复用的 Intl.DateTimeFormat 实例 ==========
7
+ // Intl.DateTimeFormat 构造极其昂贵(~36ms),必须复用
8
+ const YMD_FORMATTER = new Intl.DateTimeFormat('zh-CN', {
9
+ timeZone: 'Asia/Shanghai',
10
+ year: 'numeric',
11
+ month: '2-digit',
12
+ day: '2-digit',
13
+ })
14
+
15
+ // ========== 缓存配置 ==========
16
+ const YMD_CACHE_SIZE = 1024
17
+ const ymdCache = new Map<number, string>()
18
+
19
+ /**
20
+ * 将时间戳格式化为 YYYYMMDD 格式(纯数字,无分隔符)
21
+ * @param timestamp - 时间戳(毫秒)
22
+ * @returns 格式化后的日期字符串,例如 "20250114"
23
+ *
24
+ * @example
25
+ * formatDateToYYYYMMDDNoDash(1736793600000) // "20250114"
26
+ */
27
+ export function formatDateToYYYYMMDDNoDash(timestamp: number): string {
28
+ const d = new Date(timestamp)
29
+ const year = d.getFullYear()
30
+ const month = String(d.getMonth() + 1).padStart(2, '0')
31
+ const day = String(d.getDate()).padStart(2, '0')
32
+ return `${year}${month}${day}`
33
+ }
34
+
35
+ /**
36
+ * 获取当前日期的 YYYYMMDD 格式(纯数字,无分隔符)
37
+ * @returns 当前日期的格式化字符串,例如 "20250114"
38
+ *
39
+ * @example
40
+ * getCurrentDateYYYYMMDD() // "20250114"(根据实际日期)
41
+ */
42
+ export function getCurrentDateYYYYMMDD(): string {
43
+ const d = new Date()
44
+ const year = d.getFullYear()
45
+ const month = String(d.getMonth() + 1).padStart(2, '0')
46
+ const day = String(d.getDate()).padStart(2, '0')
47
+ return `${year}${month}${day}`
48
+ }
49
+
50
+ /**
51
+ * 将时间戳格式化为 YYYY-MM-DD 格式(上海时区)
52
+ * @param timestamp - 时间戳(毫秒)
53
+ * @returns 格式化后的日期字符串,例如 "2025-01-14"
54
+ *
55
+ * @example
56
+ * formatDateToYYYYMMDD(1736793600000) // "2025-01-14"
57
+ */
58
+ export function formatDateToYYYYMMDD(timestamp: number): string {
59
+ // 缓存命中检查
60
+ const cached = ymdCache.get(timestamp)
61
+ if (cached !== undefined) return cached
62
+
63
+ // 使用复用的 formatter,避免每次构造开销
64
+ const parts = YMD_FORMATTER.formatToParts(new Date(timestamp))
65
+
66
+ // 用 for 循环替代 .reduce,避免临时对象分配
67
+ let y = '', m = '', d = ''
68
+ for (let i = 0; i < parts.length; i++) {
69
+ const p = parts[i]
70
+ if (p.type === 'year') y = p.value
71
+ else if (p.type === 'month') m = p.value
72
+ else if (p.type === 'day') d = p.value
73
+ }
74
+
75
+ const result = `${y}-${m}-${d}`
76
+
77
+ // 写入缓存,防膨胀
78
+ if (ymdCache.size >= YMD_CACHE_SIZE) ymdCache.clear()
79
+ ymdCache.set(timestamp, result)
80
+
81
+ return result
82
+ }
83
+
84
+ // ========== formatMonthOrYear 缓存 ==========
85
+ const MONTH_YEAR_CACHE_SIZE = 512
86
+ const monthYearCache = new Map<number, { text: string; isYear: boolean }>()
87
+
88
+ /**
89
+ * 格式化月份或年份用于显示
90
+ * 当年为 1 月时显示年份,其他月份显示"X月"格式
91
+ * @param timestamp - 时间戳(毫秒)
92
+ * @returns 包含文本和是否为年份的标志
93
+ *
94
+ * @example
95
+ * formatMonthOrYear(1704067200000) // { text: "2024", isYear: true } (2024年1月)
96
+ * formatMonthOrYear(1706745600000) // { text: "2月", isYear: false } (2024年2月)
97
+ */
98
+ export function formatMonthOrYear(timestamp: number): { text: string; isYear: boolean } {
99
+ // 缓存命中检查
100
+ const cached = monthYearCache.get(timestamp)
101
+ if (cached !== undefined) return cached
102
+
103
+ const d = new Date(timestamp)
104
+ const year = d.getFullYear()
105
+ const month = d.getMonth() + 1
106
+ // 当年 1 月:直接标注年份;其它月份:标注"X月"
107
+ const result = month === 1 ? { text: String(year), isYear: true } : { text: `${month}月`, isYear: false }
108
+
109
+ // 写入缓存,防膨胀
110
+ if (monthYearCache.size >= MONTH_YEAR_CACHE_SIZE) monthYearCache.clear()
111
+ monthYearCache.set(timestamp, result)
112
+
113
+ return result
114
+ }
115
+
116
+ /**
117
+ * 生成月份键值用于比较(YYYY-M 格式)
118
+ * 注意:月份未补零,用于快速比较月份是否相同
119
+ * @param timestamp - 时间戳(毫秒)
120
+ * @returns 月份键值,例如 "2025-1"
121
+ *
122
+ * @example
123
+ * monthKey(1736793600000) // "2025-1"
124
+ */
125
+ /**
126
+ * 生成月份键值用于比较
127
+ * 返回数字 year * 12 + month,比字符串比较更快且无分配
128
+ * 使用 new Date 保证本地时区正确(与显示一致)
129
+ *
130
+ * @example
131
+ * monthKey(1736793600000) // 24301 (2025*12 + 0)
132
+ */
133
+ export function monthKey(timestamp: number): number {
134
+ const d = new Date(timestamp)
135
+ return d.getFullYear() * 12 + d.getMonth()
136
+ }
137
+
138
+ // ========== 便捷别名 ==========
139
+
140
+ /**
141
+ * formatDateToYYYYMMDD 的别名,保持与历史代码的兼容性
142
+ * timestamp 是"上海时区当天 00:00:00"映射到 UTC 的值;显示时强制按上海时区格式化
143
+ * @param ts - 时间戳(毫秒)
144
+ * @returns 格式化后的日期字符串,例如 "2025-01-14"
145
+ */
146
+ export const formatShanghaiDate = formatDateToYYYYMMDD
147
+
148
+ /**
149
+ * formatDateToYYYYMMDD 的别名,用于十字线日期标签显示
150
+ * 按上海时区格式化,避免不同时区出现日期偏移
151
+ * @param ts - 时间戳(毫秒)
152
+ * @returns 格式化后的日期字符串,例如 "2025-01-14"
153
+ */
154
+ export const formatYMDShanghai = formatDateToYYYYMMDD
155
+
156
+ /**
157
+ * 查找每个月份第一个K线的索引
158
+ * @param data - K线数据数组(按时间升序排列)
159
+ * @returns 月边界索引数组,例如 [0, 30, 60] 表示第0、30、60个K线分别是每月的第一个交易日
160
+ *
161
+ * @example
162
+ * // 假设数据:[1/2, 1/3, 2/1, 2/2, 3/1, 3/2]
163
+ * findMonthBoundaries(data) // [0, 2, 4]
164
+ * // 解释:第0个K线是1月第一个,第2个K线是2月第一个,第4个K线是3月第一个
165
+ */
166
+ // findMonthBoundaries 缓存
167
+ let _cacheDataRef: Array<{ timestamp: number } | undefined> | null = null
168
+ let _cacheLen = 0
169
+ let _cacheFirstTs = 0
170
+ let _cacheLastTs = 0
171
+ let _cacheResult: number[] = []
172
+
173
+ /**
174
+ * 查找每个月份第一个K线的索引
175
+ * 结果按数据引用缓存,同一份数据多次调用直接返回缓存
176
+ */
177
+ export function findMonthBoundaries(data: Array<{ timestamp: number } | undefined>): number[] {
178
+ if (data.length === 0) return []
179
+
180
+ // 缓存命中:同一引用 + 同长度 + 首尾时间戳不变
181
+ if (_cacheDataRef === data && _cacheLen === data.length) {
182
+ const firstTs = data[0]?.timestamp
183
+ const lastTs = data[data.length - 1]?.timestamp
184
+ if (firstTs === _cacheFirstTs && lastTs === _cacheLastTs) {
185
+ return _cacheResult
186
+ }
187
+ }
188
+
189
+ const boundaries: number[] = [0]
190
+ let lastKey = monthKey(data[0]!.timestamp)
191
+
192
+ for (let i = 1; i < data.length; i++) {
193
+ const cur = data[i]
194
+ if (!cur) continue
195
+ const curKey = monthKey(cur.timestamp)
196
+ if (curKey !== lastKey) {
197
+ boundaries.push(i)
198
+ lastKey = curKey
199
+ }
200
+ }
201
+
202
+ _cacheDataRef = data
203
+ _cacheLen = data.length
204
+ _cacheFirstTs = data[0]?.timestamp ?? 0
205
+ _cacheLastTs = data[data.length - 1]?.timestamp ?? 0
206
+ _cacheResult = boundaries
207
+ return boundaries
208
+ }