@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.
- package/README.md +201 -201
- package/README.zh-CN.md +201 -201
- package/dist/controllers/index.d.ts +1 -0
- package/dist/controllers/index.d.ts.map +1 -1
- package/dist/controllers/index.js +1 -0
- package/dist/controllers/index.js.map +1 -1
- package/dist/engine/chart.d.ts +11 -19
- package/dist/engine/chart.d.ts.map +1 -1
- package/dist/engine/chart.js +92 -109
- package/dist/engine/chart.js.map +1 -1
- package/dist/engine/renderers/Indicator/indicatorData.d.ts +1 -0
- package/dist/engine/renderers/Indicator/indicatorData.d.ts.map +1 -1
- package/dist/engine/renderers/Indicator/indicatorData.js +1 -1
- package/dist/engine/renderers/Indicator/indicatorData.js.map +1 -1
- package/dist/engine/renderers/webgl/candleSurface.js +47 -47
- package/dist/engine/subPaneManager.d.ts +4 -0
- package/dist/engine/subPaneManager.d.ts.map +1 -1
- package/dist/engine/subPaneManager.js +13 -0
- package/dist/engine/subPaneManager.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.d.ts.map +1 -1
- package/dist/version.js +1 -2
- package/dist/version.js.map +1 -1
- package/package.json +129 -122
- package/src/__tests__/signal.test.ts +124 -124
- package/src/config/chartSettings.ts +66 -66
- package/src/controllers/__tests__/drawing.test.ts +214 -214
- package/src/controllers/__tests__/indicatorSelector.test.ts +481 -481
- package/src/controllers/__tests__/toolbar.test.ts +225 -225
- package/src/controllers/createChartController.ts +665 -665
- package/src/controllers/createDrawingController.ts +96 -96
- package/src/controllers/createIndicatorSelectorController.ts +307 -307
- package/src/controllers/createToolbarController.ts +146 -146
- package/src/controllers/index.ts +20 -19
- package/src/controllers/types.ts +284 -284
- package/src/engine/__tests__/chart.dpr.test.ts +401 -401
- package/src/engine/__tests__/paneRenderer.resize.test.ts +92 -92
- package/src/engine/chart-store.ts +121 -121
- package/src/engine/chart.d.ts +617 -617
- package/src/engine/chart.ts +2803 -2815
- package/src/engine/controller/__tests__/interaction.dpr.test.ts +259 -259
- package/src/engine/controller/interaction.ts +722 -722
- package/src/engine/controller/markerInteraction.ts +130 -130
- package/src/engine/controller/pinchTracker.ts +82 -82
- package/src/engine/controller/tooltipPosition.ts +48 -48
- package/src/engine/draw/__tests__/pixelAlign.spec.ts +176 -176
- package/src/engine/draw/pixelAlign.ts +259 -259
- package/src/engine/drawing/index.ts +655 -655
- package/src/engine/drawing/interaction.ts +842 -842
- package/src/engine/drawing/plugin.ts +343 -343
- package/src/engine/indicators/__tests__/__fixtures__/golden/atr.json +38 -38
- package/src/engine/indicators/__tests__/__fixtures__/golden/dema.json +14 -14
- package/src/engine/indicators/__tests__/__fixtures__/golden/hma.json +14 -14
- package/src/engine/indicators/__tests__/__fixtures__/golden/index.ts +55 -55
- package/src/engine/indicators/__tests__/__fixtures__/golden/kama.json +14 -14
- package/src/engine/indicators/__tests__/__fixtures__/golden/tema.json +14 -14
- package/src/engine/indicators/__tests__/__fixtures__/golden/wma.json +40 -40
- package/src/engine/indicators/__tests__/__fixtures__/synthetic.ts +65 -65
- package/src/engine/indicators/__tests__/_propertyAssertions.ts +76 -76
- package/src/engine/indicators/__tests__/atr.test.ts +153 -153
- package/src/engine/indicators/__tests__/calculators.test.ts +614 -614
- package/src/engine/indicators/__tests__/cmf-mfi.test.ts +100 -100
- package/src/engine/indicators/__tests__/dema.test.ts +73 -73
- package/src/engine/indicators/__tests__/donchian.test.ts +70 -70
- package/src/engine/indicators/__tests__/hma.test.ts +73 -73
- package/src/engine/indicators/__tests__/ichimoku.test.ts +105 -105
- package/src/engine/indicators/__tests__/kama.test.ts +80 -80
- package/src/engine/indicators/__tests__/keltner.test.ts +65 -65
- package/src/engine/indicators/__tests__/pivot-fib.test.ts +110 -110
- package/src/engine/indicators/__tests__/roc.test.ts +68 -68
- package/src/engine/indicators/__tests__/sar.test.ts +86 -86
- package/src/engine/indicators/__tests__/scheduler.test.ts +831 -831
- package/src/engine/indicators/__tests__/soa.test.ts +533 -533
- package/src/engine/indicators/__tests__/structure.test.ts +110 -110
- package/src/engine/indicators/__tests__/supertrend.test.ts +65 -65
- package/src/engine/indicators/__tests__/tema.test.ts +68 -68
- package/src/engine/indicators/__tests__/trix.test.ts +70 -70
- package/src/engine/indicators/__tests__/volatility.test.ts +117 -117
- package/src/engine/indicators/__tests__/volume.test.ts +115 -115
- package/src/engine/indicators/__tests__/volumeProfile.test.ts +74 -74
- package/src/engine/indicators/__tests__/vwap.test.ts +69 -69
- package/src/engine/indicators/__tests__/wma.test.ts +112 -112
- package/src/engine/indicators/__tests__/zones.test.ts +95 -95
- package/src/engine/indicators/atrState.ts +27 -27
- package/src/engine/indicators/bollState.ts +51 -51
- package/src/engine/indicators/calculators.ts +2593 -2593
- package/src/engine/indicators/cciState.ts +25 -25
- package/src/engine/indicators/chaikinVolState.ts +32 -32
- package/src/engine/indicators/cmfState.ts +27 -27
- package/src/engine/indicators/demaState.ts +27 -27
- package/src/engine/indicators/donchianState.ts +43 -43
- package/src/engine/indicators/eneState.ts +43 -43
- package/src/engine/indicators/expmaState.ts +43 -43
- package/src/engine/indicators/fastkState.ts +25 -25
- package/src/engine/indicators/fibState.ts +41 -41
- package/src/engine/indicators/hmaState.ts +27 -27
- package/src/engine/indicators/hvState.ts +28 -28
- package/src/engine/indicators/ichimokuState.ts +70 -70
- package/src/engine/indicators/indicator.worker.ts +169 -169
- package/src/engine/indicators/indicatorDefinitionRegistry.ts +62 -62
- package/src/engine/indicators/indicatorMetadata.ts +110 -110
- package/src/engine/indicators/indicatorRegistry.ts +106 -106
- package/src/engine/indicators/indicatorRuntime.ts +1548 -1548
- package/src/engine/indicators/kamaState.ts +34 -34
- package/src/engine/indicators/keltnerState.ts +49 -49
- package/src/engine/indicators/kstState.ts +42 -42
- package/src/engine/indicators/maState.ts +36 -36
- package/src/engine/indicators/macdState.ts +76 -76
- package/src/engine/indicators/mfiState.ts +27 -27
- package/src/engine/indicators/momState.ts +25 -25
- package/src/engine/indicators/obvState.ts +25 -25
- package/src/engine/indicators/parkinsonState.ts +28 -28
- package/src/engine/indicators/pivotState.ts +51 -51
- package/src/engine/indicators/pvtState.ts +25 -25
- package/src/engine/indicators/rocState.ts +27 -27
- package/src/engine/indicators/rsiState.ts +65 -65
- package/src/engine/indicators/sarState.ts +41 -41
- package/src/engine/indicators/scheduler.ts +1205 -1205
- package/src/engine/indicators/soa.ts +352 -352
- package/src/engine/indicators/stateComposer.ts +1262 -1262
- package/src/engine/indicators/stochState.ts +26 -26
- package/src/engine/indicators/structureState.ts +69 -69
- package/src/engine/indicators/supertrendState.ts +37 -37
- package/src/engine/indicators/temaState.ts +27 -27
- package/src/engine/indicators/trixState.ts +35 -35
- package/src/engine/indicators/vmaState.ts +27 -27
- package/src/engine/indicators/volumeProfileState.ts +63 -63
- package/src/engine/indicators/vwapState.ts +29 -29
- package/src/engine/indicators/wmaState.ts +27 -27
- package/src/engine/indicators/wmsrState.ts +25 -25
- package/src/engine/indicators/workerProtocol.ts +613 -613
- package/src/engine/indicators/zonesState.ts +47 -47
- package/src/engine/layout/pane.ts +161 -161
- package/src/engine/marker/registry.ts +265 -265
- package/src/engine/paneRenderer.ts +169 -169
- package/src/engine/renderers/Indicator/atr.ts +237 -237
- package/src/engine/renderers/Indicator/boll.ts +317 -317
- package/src/engine/renderers/Indicator/cci.ts +275 -275
- package/src/engine/renderers/Indicator/chaikinVol.ts +138 -138
- package/src/engine/renderers/Indicator/cmf.ts +137 -137
- package/src/engine/renderers/Indicator/dema.ts +136 -136
- package/src/engine/renderers/Indicator/donchian.ts +137 -137
- package/src/engine/renderers/Indicator/ene.ts +271 -271
- package/src/engine/renderers/Indicator/expma.ts +197 -197
- package/src/engine/renderers/Indicator/fastk.ts +316 -316
- package/src/engine/renderers/Indicator/fib.ts +141 -141
- package/src/engine/renderers/Indicator/hma.ts +136 -136
- package/src/engine/renderers/Indicator/hv.ts +124 -124
- package/src/engine/renderers/Indicator/ichimoku.ts +181 -181
- package/src/engine/renderers/Indicator/index.ts +241 -241
- package/src/engine/renderers/Indicator/indicatorData.ts +650 -650
- package/src/engine/renderers/Indicator/kama.ts +136 -136
- package/src/engine/renderers/Indicator/keltner.ts +137 -137
- package/src/engine/renderers/Indicator/kst.ts +302 -302
- package/src/engine/renderers/Indicator/ma.ts +200 -200
- package/src/engine/renderers/Indicator/macd.ts +477 -477
- package/src/engine/renderers/Indicator/macdLegend.ts +141 -141
- package/src/engine/renderers/Indicator/mainIndicatorLegend.ts +272 -272
- package/src/engine/renderers/Indicator/mfi.ts +142 -142
- package/src/engine/renderers/Indicator/mom.ts +311 -311
- package/src/engine/renderers/Indicator/obv.ts +123 -123
- package/src/engine/renderers/Indicator/parkinson.ts +124 -124
- package/src/engine/renderers/Indicator/pivot.ts +131 -131
- package/src/engine/renderers/Indicator/pvt.ts +123 -123
- package/src/engine/renderers/Indicator/roc.ts +143 -143
- package/src/engine/renderers/Indicator/rsi.ts +390 -390
- package/src/engine/renderers/Indicator/sar.ts +113 -113
- package/src/engine/renderers/Indicator/scale/atr_scale.ts +19 -19
- package/src/engine/renderers/Indicator/scale/cci_scale.ts +19 -19
- package/src/engine/renderers/Indicator/scale/fastk_scale.ts +19 -19
- package/src/engine/renderers/Indicator/scale/indicator_scale.ts +204 -204
- package/src/engine/renderers/Indicator/scale/kst_scale.ts +19 -19
- package/src/engine/renderers/Indicator/scale/macd_scale.ts +22 -22
- package/src/engine/renderers/Indicator/scale/mom_scale.ts +19 -19
- package/src/engine/renderers/Indicator/scale/rsi_scale.ts +19 -19
- package/src/engine/renderers/Indicator/scale/stoch_scale.ts +19 -19
- package/src/engine/renderers/Indicator/scale/volume_scale.ts +26 -26
- package/src/engine/renderers/Indicator/scale/wmsr_scale.ts +19 -19
- package/src/engine/renderers/Indicator/stoch.ts +359 -359
- package/src/engine/renderers/Indicator/structure.ts +126 -126
- package/src/engine/renderers/Indicator/subPaneConfig.ts +265 -265
- package/src/engine/renderers/Indicator/supertrend.ts +115 -115
- package/src/engine/renderers/Indicator/tema.ts +136 -136
- package/src/engine/renderers/Indicator/trix.ts +158 -158
- package/src/engine/renderers/Indicator/vma.ts +124 -124
- package/src/engine/renderers/Indicator/volumeProfile.ts +125 -125
- package/src/engine/renderers/Indicator/vwap.ts +123 -123
- package/src/engine/renderers/Indicator/wma.ts +136 -136
- package/src/engine/renderers/Indicator/wmsr.ts +328 -328
- package/src/engine/renderers/Indicator/zones.ts +104 -104
- package/src/engine/renderers/__tests__/boll.renderer.test.ts +314 -314
- package/src/engine/renderers/__tests__/ene.renderer.test.ts +305 -305
- package/src/engine/renderers/__tests__/expma.renderer.test.ts +279 -279
- package/src/engine/renderers/__tests__/ma.renderer.test.ts +426 -426
- package/src/engine/renderers/__tests__/mainIndicatorLegend.renderer.test.ts +502 -502
- package/src/engine/renderers/__tests__/yAxis.renderer.test.ts +173 -173
- package/src/engine/renderers/candle.ts +459 -459
- package/src/engine/renderers/crosshair.ts +69 -69
- package/src/engine/renderers/customMarkers.ts +162 -162
- package/src/engine/renderers/extremaMarkers.ts +246 -246
- package/src/engine/renderers/gridLines.ts +90 -90
- package/src/engine/renderers/lastPrice.ts +97 -97
- package/src/engine/renderers/paneTitle.ts +136 -136
- package/src/engine/renderers/subVolume.ts +236 -236
- package/src/engine/renderers/timeAxis.ts +121 -121
- package/src/engine/renderers/webgl/candleSurface.ts +955 -955
- package/src/engine/renderers/webgl/sharedWebGLSurface.ts +146 -146
- package/src/engine/renderers/yAxis.ts +105 -105
- package/src/engine/scale/__tests__/logFormula.spec.ts +148 -148
- package/src/engine/scale/logFormula.ts +130 -130
- package/src/engine/scale/price.ts +39 -39
- package/src/engine/scale/priceScale.ts +264 -264
- package/src/engine/subPaneManager.ts +442 -427
- package/src/engine/theme/colors.ts +642 -642
- package/src/engine/theme/fonts.ts +20 -20
- package/src/engine/utils/klineConfig.ts +49 -49
- package/src/engine/utils/tickCount.ts +11 -11
- package/src/engine/utils/tickPosition.ts +214 -214
- package/src/engine/utils/zoom.ts +83 -83
- package/src/engine/viewport/viewport.ts +67 -67
- package/src/index.ts +3 -3
- package/src/plugin/ConfigManager.ts +93 -93
- package/src/plugin/EventBus.ts +77 -77
- package/src/plugin/HookSystem.ts +106 -106
- package/src/plugin/PluginHost.ts +243 -243
- package/src/plugin/PluginRegistry.ts +92 -92
- package/src/plugin/StateStore.ts +73 -73
- package/src/plugin/index.ts +19 -19
- package/src/plugin/rendererPluginManager.ts +368 -368
- package/src/plugin/stateKeys.ts +8 -8
- package/src/plugin/types.ts +526 -526
- package/src/reactivity/index.ts +2 -2
- package/src/reactivity/signal.ts +119 -119
- package/src/semantic/controller.ts +251 -251
- package/src/semantic/drawShape.ts +260 -260
- package/src/semantic/index.ts +28 -28
- package/src/semantic/schema.json +256 -256
- package/src/semantic/types.ts +251 -251
- package/src/semantic/validator.ts +349 -349
- package/src/types/kLine.ts +13 -13
- package/src/types/price.ts +56 -56
- package/src/types/volumePrice.ts +33 -33
- package/src/utils/dateFormat.ts +208 -208
- package/src/utils/kLineDraw/axis.ts +562 -562
- package/src/utils/priceToY.ts +34 -34
- package/src/utils/volumePrice.ts +202 -202
- package/src/version.ts +1 -1
package/src/utils/priceToY.ts
CHANGED
|
@@ -1,34 +1,34 @@
|
|
|
1
|
-
export function priceToY(
|
|
2
|
-
price: number,
|
|
3
|
-
maxPrice: number,
|
|
4
|
-
minPrice: number,
|
|
5
|
-
canvasHeight: number,
|
|
6
|
-
paddingTop: number,
|
|
7
|
-
paddingBottom: number,
|
|
8
|
-
): number {
|
|
9
|
-
const range = maxPrice - minPrice || 1
|
|
10
|
-
const ratio = (price - minPrice) / range
|
|
11
|
-
|
|
12
|
-
const viewHeight = Math.max(1, canvasHeight - paddingTop - paddingBottom)
|
|
13
|
-
return paddingTop + viewHeight * (1 - ratio)
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* 将逻辑像素 y 反算回价格
|
|
18
|
-
* - y 是相对于绘图区顶部的逻辑像素坐标(不含额外 translate)
|
|
19
|
-
* - paddingTop/paddingBottom 需与 priceToY 使用一致
|
|
20
|
-
*/
|
|
21
|
-
export function yToPrice(
|
|
22
|
-
y: number,
|
|
23
|
-
maxPrice: number,
|
|
24
|
-
minPrice: number,
|
|
25
|
-
canvasHeight: number,
|
|
26
|
-
paddingTop: number,
|
|
27
|
-
paddingBottom: number,
|
|
28
|
-
): number {
|
|
29
|
-
const range = maxPrice - minPrice || 1
|
|
30
|
-
const viewHeight = Math.max(1, canvasHeight - paddingTop - paddingBottom)
|
|
31
|
-
const clampedY = Math.min(Math.max(y, paddingTop), paddingTop + viewHeight)
|
|
32
|
-
const ratio = 1 - (clampedY - paddingTop) / viewHeight
|
|
33
|
-
return minPrice + ratio * range
|
|
34
|
-
}
|
|
1
|
+
export function priceToY(
|
|
2
|
+
price: number,
|
|
3
|
+
maxPrice: number,
|
|
4
|
+
minPrice: number,
|
|
5
|
+
canvasHeight: number,
|
|
6
|
+
paddingTop: number,
|
|
7
|
+
paddingBottom: number,
|
|
8
|
+
): number {
|
|
9
|
+
const range = maxPrice - minPrice || 1
|
|
10
|
+
const ratio = (price - minPrice) / range
|
|
11
|
+
|
|
12
|
+
const viewHeight = Math.max(1, canvasHeight - paddingTop - paddingBottom)
|
|
13
|
+
return paddingTop + viewHeight * (1 - ratio)
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* 将逻辑像素 y 反算回价格
|
|
18
|
+
* - y 是相对于绘图区顶部的逻辑像素坐标(不含额外 translate)
|
|
19
|
+
* - paddingTop/paddingBottom 需与 priceToY 使用一致
|
|
20
|
+
*/
|
|
21
|
+
export function yToPrice(
|
|
22
|
+
y: number,
|
|
23
|
+
maxPrice: number,
|
|
24
|
+
minPrice: number,
|
|
25
|
+
canvasHeight: number,
|
|
26
|
+
paddingTop: number,
|
|
27
|
+
paddingBottom: number,
|
|
28
|
+
): number {
|
|
29
|
+
const range = maxPrice - minPrice || 1
|
|
30
|
+
const viewHeight = Math.max(1, canvasHeight - paddingTop - paddingBottom)
|
|
31
|
+
const clampedY = Math.min(Math.max(y, paddingTop), paddingTop + viewHeight)
|
|
32
|
+
const ratio = 1 - (clampedY - paddingTop) / viewHeight
|
|
33
|
+
return minPrice + ratio * range
|
|
34
|
+
}
|
package/src/utils/volumePrice.ts
CHANGED
|
@@ -1,203 +1,203 @@
|
|
|
1
|
-
import type { KLineData } from '../types/price'
|
|
2
|
-
import { VolumePriceRelation, type VolumePriceConfig, DEFAULT_VOLUME_PRICE_CONFIG } from '../types/volumePrice'
|
|
3
|
-
|
|
4
|
-
// 重新导出默认配置,方便外部使用
|
|
5
|
-
export { DEFAULT_VOLUME_PRICE_CONFIG }
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* 成交量前缀和计算器
|
|
9
|
-
* 用于优化成交量移动平均的计算,避免重复遍历
|
|
10
|
-
*/
|
|
11
|
-
export class VolumePrefixSum {
|
|
12
|
-
private prefixSum: number[] = []
|
|
13
|
-
private dataLength: number = 0
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* 构建前缀和数组
|
|
17
|
-
* @param data - K线数据数组
|
|
18
|
-
*/
|
|
19
|
-
build(data: KLineData[]): void {
|
|
20
|
-
const len = data.length
|
|
21
|
-
if (len === 0) {
|
|
22
|
-
this.prefixSum = []
|
|
23
|
-
this.dataLength = 0
|
|
24
|
-
return
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
this.prefixSum = [0]
|
|
28
|
-
|
|
29
|
-
for (let i = 0; i < len; i++) {
|
|
30
|
-
this.prefixSum.push(this.prefixSum[i]! + (data[i]?.volume ?? 0))
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
this.dataLength = len
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* 查询区间 [start, end] 的成交量之和
|
|
38
|
-
* @param start - 起始索引(包含)
|
|
39
|
-
* @param end - 结束索引(包含)
|
|
40
|
-
* @returns 区间成交量之和
|
|
41
|
-
*/
|
|
42
|
-
query(start: number, end: number): number {
|
|
43
|
-
if (start < 0 || end >= this.dataLength || start > end) {
|
|
44
|
-
return 0
|
|
45
|
-
}
|
|
46
|
-
return this.prefixSum[end + 1]! - this.prefixSum[start]!
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* 计算成交量移动平均
|
|
51
|
-
* @param index - 当前K线索引
|
|
52
|
-
* @param period - 计算周期
|
|
53
|
-
* @returns 成交量移动平均值
|
|
54
|
-
*/
|
|
55
|
-
getVolumeMA(index: number, period: number): number {
|
|
56
|
-
if (index < period - 1) return 0
|
|
57
|
-
const start = index - period + 1
|
|
58
|
-
const sum = this.query(start, index)
|
|
59
|
-
return sum / period
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* 获取数据长度
|
|
64
|
-
*/
|
|
65
|
-
get length(): number {
|
|
66
|
-
return this.dataLength
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
// 全局前缀和实例(可选,用于简化调用)
|
|
71
|
-
let globalPrefixSum: VolumePrefixSum | null = null
|
|
72
|
-
let cachedData: KLineData[] | null = null
|
|
73
|
-
|
|
74
|
-
/**
|
|
75
|
-
* 获取或创建前缀和实例
|
|
76
|
-
* 检测数据引用是否变化,自动重建前缀和
|
|
77
|
-
*/
|
|
78
|
-
function getPrefixSum(data: KLineData[]): VolumePrefixSum {
|
|
79
|
-
if (!globalPrefixSum || cachedData !== data) {
|
|
80
|
-
globalPrefixSum = new VolumePrefixSum()
|
|
81
|
-
globalPrefixSum.build(data)
|
|
82
|
-
cachedData = data
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
return globalPrefixSum
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
/**
|
|
89
|
-
* 计算量价关系
|
|
90
|
-
*
|
|
91
|
-
* @param data - K线数据数组
|
|
92
|
-
* @param index - 要分析的K线索引
|
|
93
|
-
* @param config - 量价关系计算配置
|
|
94
|
-
* @returns 量价关系类型
|
|
95
|
-
*/
|
|
96
|
-
export function analyzeVolumePriceRelation(
|
|
97
|
-
data: KLineData[],
|
|
98
|
-
index: number,
|
|
99
|
-
config: VolumePriceConfig
|
|
100
|
-
): VolumePriceRelation {
|
|
101
|
-
const curVolume = data[index]?.volume
|
|
102
|
-
if (index < 1 || index >= data.length || !curVolume) {
|
|
103
|
-
return VolumePriceRelation.OTHERS
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
const { volumeAmplifyThreshold, volumeShrinkThreshold, avgPeriod } = config
|
|
107
|
-
|
|
108
|
-
// 使用前缀和优化计算 MA
|
|
109
|
-
const prefixSum = getPrefixSum(data)
|
|
110
|
-
const volumeMA = prefixSum.getVolumeMA(index, avgPeriod)
|
|
111
|
-
|
|
112
|
-
// 判断价格方向
|
|
113
|
-
const currentKLine = data[index]
|
|
114
|
-
if (!currentKLine) return VolumePriceRelation.OTHERS
|
|
115
|
-
const priceChange = currentKLine.close - currentKLine.open
|
|
116
|
-
const isRising = priceChange > 0
|
|
117
|
-
const isFalling = priceChange < 0
|
|
118
|
-
|
|
119
|
-
// 判断成交量变化
|
|
120
|
-
const isVolumeAmplified = curVolume > volumeMA * volumeAmplifyThreshold
|
|
121
|
-
const isVolumeShrunk = curVolume < volumeMA * volumeShrinkThreshold
|
|
122
|
-
|
|
123
|
-
// 1. 量价齐升(放量上涨)
|
|
124
|
-
if (isRising && isVolumeAmplified) {
|
|
125
|
-
return VolumePriceRelation.RISE_WITH_VOLUME
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
// 2. 量价背离(缩量上涨)
|
|
129
|
-
if (isRising && isVolumeShrunk) {
|
|
130
|
-
return VolumePriceRelation.RISE_WITHOUT_VOLUME
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
// 3. 量增价跌
|
|
134
|
-
if (isFalling && isVolumeAmplified) {
|
|
135
|
-
return VolumePriceRelation.FALL_WITH_VOLUME
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
// 4. 量缩价跌
|
|
139
|
-
if (isFalling && isVolumeShrunk) {
|
|
140
|
-
return VolumePriceRelation.FALL_WITHOUT_VOLUME
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
return VolumePriceRelation.OTHERS
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
/**
|
|
147
|
-
* 批量计算量价关系(推荐用于渲染器中)
|
|
148
|
-
* 显式传入前缀和实例,避免重复构建
|
|
149
|
-
*
|
|
150
|
-
* @param data - K线数据数组
|
|
151
|
-
* @param startIndex - 起始索引
|
|
152
|
-
* @param endIndex - 结束索引
|
|
153
|
-
* @param config - 量价关系计算配置
|
|
154
|
-
* @returns 量价关系数组
|
|
155
|
-
*/
|
|
156
|
-
export function analyzeVolumePriceRelationBatch(
|
|
157
|
-
data: KLineData[],
|
|
158
|
-
startIndex: number,
|
|
159
|
-
endIndex: number,
|
|
160
|
-
config: VolumePriceConfig = DEFAULT_VOLUME_PRICE_CONFIG
|
|
161
|
-
): VolumePriceRelation[] {
|
|
162
|
-
const prefixSum = new VolumePrefixSum()
|
|
163
|
-
prefixSum.build(data)
|
|
164
|
-
|
|
165
|
-
const results: VolumePriceRelation[] = []
|
|
166
|
-
const { volumeAmplifyThreshold, volumeShrinkThreshold, avgPeriod } = config
|
|
167
|
-
|
|
168
|
-
for (let index = startIndex; index < endIndex && index < data.length; index++) {
|
|
169
|
-
const curVolume = data[index]?.volume
|
|
170
|
-
if (index < 1 || !curVolume) {
|
|
171
|
-
results.push(VolumePriceRelation.OTHERS)
|
|
172
|
-
continue
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
const volumeMA = prefixSum.getVolumeMA(index, avgPeriod)
|
|
176
|
-
const currentKLine = data[index]
|
|
177
|
-
|
|
178
|
-
if (!currentKLine) {
|
|
179
|
-
results.push(VolumePriceRelation.OTHERS)
|
|
180
|
-
continue
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
const priceChange = currentKLine.close - currentKLine.open
|
|
184
|
-
const isRising = priceChange > 0
|
|
185
|
-
const isFalling = priceChange < 0
|
|
186
|
-
const isVolumeAmplified = curVolume > volumeMA * volumeAmplifyThreshold
|
|
187
|
-
const isVolumeShrunk = curVolume < volumeMA * volumeShrinkThreshold
|
|
188
|
-
|
|
189
|
-
if (isRising && isVolumeAmplified) {
|
|
190
|
-
results.push(VolumePriceRelation.RISE_WITH_VOLUME)
|
|
191
|
-
} else if (isRising && isVolumeShrunk) {
|
|
192
|
-
results.push(VolumePriceRelation.RISE_WITHOUT_VOLUME)
|
|
193
|
-
} else if (isFalling && isVolumeAmplified) {
|
|
194
|
-
results.push(VolumePriceRelation.FALL_WITH_VOLUME)
|
|
195
|
-
} else if (isFalling && isVolumeShrunk) {
|
|
196
|
-
results.push(VolumePriceRelation.FALL_WITHOUT_VOLUME)
|
|
197
|
-
} else {
|
|
198
|
-
results.push(VolumePriceRelation.OTHERS)
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
return results
|
|
1
|
+
import type { KLineData } from '../types/price'
|
|
2
|
+
import { VolumePriceRelation, type VolumePriceConfig, DEFAULT_VOLUME_PRICE_CONFIG } from '../types/volumePrice'
|
|
3
|
+
|
|
4
|
+
// 重新导出默认配置,方便外部使用
|
|
5
|
+
export { DEFAULT_VOLUME_PRICE_CONFIG }
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* 成交量前缀和计算器
|
|
9
|
+
* 用于优化成交量移动平均的计算,避免重复遍历
|
|
10
|
+
*/
|
|
11
|
+
export class VolumePrefixSum {
|
|
12
|
+
private prefixSum: number[] = []
|
|
13
|
+
private dataLength: number = 0
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* 构建前缀和数组
|
|
17
|
+
* @param data - K线数据数组
|
|
18
|
+
*/
|
|
19
|
+
build(data: KLineData[]): void {
|
|
20
|
+
const len = data.length
|
|
21
|
+
if (len === 0) {
|
|
22
|
+
this.prefixSum = []
|
|
23
|
+
this.dataLength = 0
|
|
24
|
+
return
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
this.prefixSum = [0]
|
|
28
|
+
|
|
29
|
+
for (let i = 0; i < len; i++) {
|
|
30
|
+
this.prefixSum.push(this.prefixSum[i]! + (data[i]?.volume ?? 0))
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
this.dataLength = len
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* 查询区间 [start, end] 的成交量之和
|
|
38
|
+
* @param start - 起始索引(包含)
|
|
39
|
+
* @param end - 结束索引(包含)
|
|
40
|
+
* @returns 区间成交量之和
|
|
41
|
+
*/
|
|
42
|
+
query(start: number, end: number): number {
|
|
43
|
+
if (start < 0 || end >= this.dataLength || start > end) {
|
|
44
|
+
return 0
|
|
45
|
+
}
|
|
46
|
+
return this.prefixSum[end + 1]! - this.prefixSum[start]!
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* 计算成交量移动平均
|
|
51
|
+
* @param index - 当前K线索引
|
|
52
|
+
* @param period - 计算周期
|
|
53
|
+
* @returns 成交量移动平均值
|
|
54
|
+
*/
|
|
55
|
+
getVolumeMA(index: number, period: number): number {
|
|
56
|
+
if (index < period - 1) return 0
|
|
57
|
+
const start = index - period + 1
|
|
58
|
+
const sum = this.query(start, index)
|
|
59
|
+
return sum / period
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* 获取数据长度
|
|
64
|
+
*/
|
|
65
|
+
get length(): number {
|
|
66
|
+
return this.dataLength
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// 全局前缀和实例(可选,用于简化调用)
|
|
71
|
+
let globalPrefixSum: VolumePrefixSum | null = null
|
|
72
|
+
let cachedData: KLineData[] | null = null
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* 获取或创建前缀和实例
|
|
76
|
+
* 检测数据引用是否变化,自动重建前缀和
|
|
77
|
+
*/
|
|
78
|
+
function getPrefixSum(data: KLineData[]): VolumePrefixSum {
|
|
79
|
+
if (!globalPrefixSum || cachedData !== data) {
|
|
80
|
+
globalPrefixSum = new VolumePrefixSum()
|
|
81
|
+
globalPrefixSum.build(data)
|
|
82
|
+
cachedData = data
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return globalPrefixSum
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* 计算量价关系
|
|
90
|
+
*
|
|
91
|
+
* @param data - K线数据数组
|
|
92
|
+
* @param index - 要分析的K线索引
|
|
93
|
+
* @param config - 量价关系计算配置
|
|
94
|
+
* @returns 量价关系类型
|
|
95
|
+
*/
|
|
96
|
+
export function analyzeVolumePriceRelation(
|
|
97
|
+
data: KLineData[],
|
|
98
|
+
index: number,
|
|
99
|
+
config: VolumePriceConfig
|
|
100
|
+
): VolumePriceRelation {
|
|
101
|
+
const curVolume = data[index]?.volume
|
|
102
|
+
if (index < 1 || index >= data.length || !curVolume) {
|
|
103
|
+
return VolumePriceRelation.OTHERS
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const { volumeAmplifyThreshold, volumeShrinkThreshold, avgPeriod } = config
|
|
107
|
+
|
|
108
|
+
// 使用前缀和优化计算 MA
|
|
109
|
+
const prefixSum = getPrefixSum(data)
|
|
110
|
+
const volumeMA = prefixSum.getVolumeMA(index, avgPeriod)
|
|
111
|
+
|
|
112
|
+
// 判断价格方向
|
|
113
|
+
const currentKLine = data[index]
|
|
114
|
+
if (!currentKLine) return VolumePriceRelation.OTHERS
|
|
115
|
+
const priceChange = currentKLine.close - currentKLine.open
|
|
116
|
+
const isRising = priceChange > 0
|
|
117
|
+
const isFalling = priceChange < 0
|
|
118
|
+
|
|
119
|
+
// 判断成交量变化
|
|
120
|
+
const isVolumeAmplified = curVolume > volumeMA * volumeAmplifyThreshold
|
|
121
|
+
const isVolumeShrunk = curVolume < volumeMA * volumeShrinkThreshold
|
|
122
|
+
|
|
123
|
+
// 1. 量价齐升(放量上涨)
|
|
124
|
+
if (isRising && isVolumeAmplified) {
|
|
125
|
+
return VolumePriceRelation.RISE_WITH_VOLUME
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// 2. 量价背离(缩量上涨)
|
|
129
|
+
if (isRising && isVolumeShrunk) {
|
|
130
|
+
return VolumePriceRelation.RISE_WITHOUT_VOLUME
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// 3. 量增价跌
|
|
134
|
+
if (isFalling && isVolumeAmplified) {
|
|
135
|
+
return VolumePriceRelation.FALL_WITH_VOLUME
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// 4. 量缩价跌
|
|
139
|
+
if (isFalling && isVolumeShrunk) {
|
|
140
|
+
return VolumePriceRelation.FALL_WITHOUT_VOLUME
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
return VolumePriceRelation.OTHERS
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* 批量计算量价关系(推荐用于渲染器中)
|
|
148
|
+
* 显式传入前缀和实例,避免重复构建
|
|
149
|
+
*
|
|
150
|
+
* @param data - K线数据数组
|
|
151
|
+
* @param startIndex - 起始索引
|
|
152
|
+
* @param endIndex - 结束索引
|
|
153
|
+
* @param config - 量价关系计算配置
|
|
154
|
+
* @returns 量价关系数组
|
|
155
|
+
*/
|
|
156
|
+
export function analyzeVolumePriceRelationBatch(
|
|
157
|
+
data: KLineData[],
|
|
158
|
+
startIndex: number,
|
|
159
|
+
endIndex: number,
|
|
160
|
+
config: VolumePriceConfig = DEFAULT_VOLUME_PRICE_CONFIG
|
|
161
|
+
): VolumePriceRelation[] {
|
|
162
|
+
const prefixSum = new VolumePrefixSum()
|
|
163
|
+
prefixSum.build(data)
|
|
164
|
+
|
|
165
|
+
const results: VolumePriceRelation[] = []
|
|
166
|
+
const { volumeAmplifyThreshold, volumeShrinkThreshold, avgPeriod } = config
|
|
167
|
+
|
|
168
|
+
for (let index = startIndex; index < endIndex && index < data.length; index++) {
|
|
169
|
+
const curVolume = data[index]?.volume
|
|
170
|
+
if (index < 1 || !curVolume) {
|
|
171
|
+
results.push(VolumePriceRelation.OTHERS)
|
|
172
|
+
continue
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
const volumeMA = prefixSum.getVolumeMA(index, avgPeriod)
|
|
176
|
+
const currentKLine = data[index]
|
|
177
|
+
|
|
178
|
+
if (!currentKLine) {
|
|
179
|
+
results.push(VolumePriceRelation.OTHERS)
|
|
180
|
+
continue
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
const priceChange = currentKLine.close - currentKLine.open
|
|
184
|
+
const isRising = priceChange > 0
|
|
185
|
+
const isFalling = priceChange < 0
|
|
186
|
+
const isVolumeAmplified = curVolume > volumeMA * volumeAmplifyThreshold
|
|
187
|
+
const isVolumeShrunk = curVolume < volumeMA * volumeShrinkThreshold
|
|
188
|
+
|
|
189
|
+
if (isRising && isVolumeAmplified) {
|
|
190
|
+
results.push(VolumePriceRelation.RISE_WITH_VOLUME)
|
|
191
|
+
} else if (isRising && isVolumeShrunk) {
|
|
192
|
+
results.push(VolumePriceRelation.RISE_WITHOUT_VOLUME)
|
|
193
|
+
} else if (isFalling && isVolumeAmplified) {
|
|
194
|
+
results.push(VolumePriceRelation.FALL_WITH_VOLUME)
|
|
195
|
+
} else if (isFalling && isVolumeShrunk) {
|
|
196
|
+
results.push(VolumePriceRelation.FALL_WITHOUT_VOLUME)
|
|
197
|
+
} else {
|
|
198
|
+
results.push(VolumePriceRelation.OTHERS)
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
return results
|
|
203
203
|
}
|
package/src/version.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const VERSION = "0.7.
|
|
1
|
+
export const VERSION = "0.7.5"
|