# tradehk 指标引擎详解 > 返回:[tradehk 文档中心](./README.md) > 源文件:`client/src/lib/indicators.ts` ## 概述 tradehk 的指标引擎实现了 16 个技术指标,分为**基础构建块**和**应用指标**两层。所有指标均为纯函数,输入 K 线数组,输出数值数组(与输入等长,不足计算的位置填 `NaN`)。 ## 基础构建块(内部函数) 这些函数不直接对外暴露,但被多个指标复用: | 函数 | 说明 | 被哪些指标使用 | |------|------|----------------| | `calculateTR(highs, lows, closes)` | 真实波动幅度(True Range) | ATR、SuperTrend、DMI | | `calculateRMA(values, period)` | Wilder 平滑移动平均(RMA) | ATR、RSI、DMI | | `calculateStdDev(closes, period)` | 标准差 | 布林带、TTM Squeeze | ### 真实波动幅度(TR) **公式**:`TR = max(High - Low, |High - Close_prev|, |Low - Close_prev|)` **意义**:衡量当前K线的真实波动范围,考虑了跳空缺口。 ### Wilder RMA **公式**:`RMA[i] = RMA[i-1] × (period-1)/period + value[i] / period` **与 EMA 的区别**:EMA 的平滑系数为 `2/(period+1)`,RMA 为 `1/period`,RMA 更平滑、反应更慢。 --- ## 常开指标(核心信号引擎始终计算) ### 1. MA(简单移动平均线) ``` 函数:calculateMA(closes, period) 默认参数:MA10(period=10)、MA100(period=100) 公式:MA[i] = sum(closes[i-period+1 .. i]) / period ``` **信号规则**(在 generateSignal 中): - 价格 > MA10 且 MA10 > MA100 → `bullishCount += 1`(多头排列) - 价格 < MA10 且 MA10 < MA100 → `bearishCount += 1`(空头排列) **名词解释**:→ [MA 名词解释](../名词解释/EMA-指数移动平均线.md) --- ### 2. EMA(指数移动平均线) ``` 函数:calculateEMA(closes, period) 平滑系数:k = 2 / (period + 1) 公式:EMA[i] = closes[i] × k + EMA[i-1] × (1-k) ``` **在 tradehk 中的用途**: - 计算 EWO(EMA5 - EMA35) - 计算 MACD(EMA10 - EMA20,信号线 EMA10) - 可选叠加显示(emaPeriods 配置,默认 [12, 26]) **名词解释**:→ [EMA 名词解释](../名词解释/EMA-指数移动平均线.md) --- ### 3. EWO(艾略特波浪振荡器) ``` 函数:calculateEWO(closes) 公式:EWO = EMA(5) - EMA(35) 颜色规则:EWO >= 0 → 绿色(多头);EWO < 0 → 红色(空头) ``` **信号规则**(权重最高,+2分): - EWO 由负转正(红→绿穿越)→ `bullishCount += 2` - EWO 由正转负(绿→红穿越)→ `bearishCount += 2` - EWO > 0 但未穿越 → `bullishCount += 1` - EWO < 0 但未穿越 → `bearishCount += 1` **大周期偏向中的权重**:EWO 在 `assessBigTimeframeBias` 中权重为 2(最高),其他指标权重均为 1。 **EWO 转换通知**:当 EWO 发生颜色转换时,`marketEngine.ts` 的 `evaluateEwoTurnForUser` 函数会检测并推送飞书通知。 **名词解释**:→ [EWO 名词解释](../名词解释/EWO-艾略特波浪振荡器.md) --- ### 4. MACD(指数平滑异同移动平均线) ``` 函数:calculateMACD(closes, fastPeriod=10, slowPeriod=20, signalPeriod=10) 注意:tradehk 使用 (10, 20, 10) 而非标准 (12, 26, 9) MACD线 = EMA(10) - EMA(20) 信号线 = EMA(MACD线, 10) 柱状图 = MACD线 - 信号线 ``` **信号规则**: - MACD 上穿信号线(金叉)→ `bullishCount += 2` - MACD 下穿信号线(死叉)→ `bearishCount += 2` - 柱状图 > 0 且扩大 → `bullishCount += 1` - 柱状图 < 0 且扩大 → `bearishCount += 1` **大周期偏向中**:MACD线 vs 信号线(+1)+ 柱状图方向(+1),共最多 +2 分。 **名词解释**:→ [MACD 名词解释](../名词解释/MACD-指数移动平均线.md) --- ### 5. AO(动量振荡器,Awesome Oscillator) ``` 函数:calculateAO(highs, lows) 公式:AO = SMA(中间价, 5) - SMA(中间价, 34) 中间价 = (High + Low) / 2 ``` **信号规则**: - AO 上穿零轴 → `bullishCount += 1` - AO 下穿零轴 → `bearishCount += 1` **大周期偏向中**:AO 方向(+1)。 **名词解释**:→ [AO 名词解释](../名词解释/AO-动量振荡器.md) --- ## 可选指标(由 IndicatorParams 控制开关) ### 6. RSI(相对强弱指数) ``` 函数:calculateRSI(closes, period=14) 算法:使用 Wilder RMA 平滑 公式:RS = 平均涨幅 / 平均跌幅;RSI = 100 - 100/(1+RS) 默认参数:period=14, overbought=70, oversold=30 开关:signalUseRsi(默认 true) ``` **信号规则**: - RSI < 30(超卖)→ `bullishCount += 1` - RSI > 70(超买)→ `bearishCount += 1` - RSI 从超卖区回升穿越30 → `bullishCount += 1`(反转确认) - RSI 从超买区回落穿越70 → `bearishCount += 1`(反转确认) **名词解释**:→ [RSI 名词解释](../名词解释/RSI-相对强弱指数.md) --- ### 7. KDJ(随机指标衍生版) ``` 函数:calculateKDJ(highs, lows, closes, period=9, kSmooth=3, dSmooth=3) RSV = (Close - LowestLow) / (HighestHigh - LowestLow) × 100 K = RMA(RSV, kSmooth) D = RMA(K, dSmooth) J = 3K - 2D 开关:signalUseKdj(默认 false) ``` **信号规则**: - K 低位金叉(K上穿D且K<30)→ `bullishCount += 2`(强信号) - K 普通金叉 → `bullishCount += 1` - K 高位死叉(K下穿D且K>70)→ `bearishCount += 2`(强信号) - K 普通死叉 → `bearishCount += 1` **名词解释**:→ [KDJ 名词解释](../名词解释/KDJ-随机指标衍生版.md) --- ### 8. Stoch(随机指标) ``` 函数:calculateStoch(highs, lows, closes, period=14, smooth=3) %K = (Close - LowestLow) / (HighestHigh - LowestLow) × 100 %D = SMA(%K, smooth) 开关:signalUseStoch(默认 false) ``` **信号规则**: - K < 20 且 D < 20 → `bullishCount += 1`(超卖) - K > 80 且 D > 80 → `bearishCount += 1`(超买) **名词解释**:→ [Stoch 名词解释](../名词解释/Stoch-随机指标.md) --- ### 9. StochRSI(随机相对强弱指数) ``` 函数:calculateStochRSI(closes, rsiPeriod=14, stochPeriod=14, kSmooth=3, dSmooth=3) 先计算 RSI 序列,再对 RSI 序列做 Stoch 计算 开关:无独立信号开关(仅图表显示) ``` **名词解释**:→ [StochRSI 名词解释](../名词解释/StochRSI-随机相对强弱指数.md) --- ### 10. 布林带(Bollinger Bands) ``` 函数:calculateBollingerBands(closes, period=20, stdDev=2) 中轨 = SMA(closes, 20) 上轨 = 中轨 + 2 × StdDev 下轨 = 中轨 - 2 × StdDev 开关:signalUseBollinger(默认 true) ``` **信号规则**: - 价格触及下轨 → `bullishCount += 1`(超卖反弹) - 价格触及上轨 → `bearishCount += 1`(超买回落) - 带宽 < 2%(极度收窄)→ 警告提示"即将变盘"(不影响评分) **名词解释**:→ [布林带名词解释](../名词解释/布林带.md) --- ### 11. MFI(资金流量指数) ``` 函数:calculateMFI(highs, lows, closes, volumes, period=14) 典型价格 = (High + Low + Close) / 3 资金流量 = 典型价格 × 成交量 正负流量分别累加,MFI = 100 - 100/(1 + 正流量/负流量) 开关:无独立信号开关(仅图表显示) ``` **名词解释**:→ [MFI 名词解释](../名词解释/MFI-资金流量指数.md) --- ### 12. OBV(能量潮) ``` 函数:calculateOBV(closes, volumes) OBV[i] = OBV[i-1] + volume(若收涨)或 - volume(若收跌) 开关:无独立信号开关(仅图表显示) ``` **名词解释**:→ [OBV 名词解释](../名词解释/OBV-能量潮指标.md) --- ### 13. DMI/ADX(趋向运动指标) ``` 函数:calculateDMI(highs, lows, closes, period=14) +DI = 100 × RMA(+DM, period) / ATR -DI = 100 × RMA(-DM, period) / ATR ADX = RMA(|+DI - -DI| / (+DI + -DI) × 100, period) 开关:signalUseDmi(默认 false) ``` **信号规则**(仅在 ADX > 25 强趋势时生效): - +DI 上穿 -DI(金叉)→ `bullishCount += 2` - +DI 下穿 -DI(死叉)→ `bearishCount += 2` - +DI > -DI(多头趋势)→ `bullishCount += 1` - -DI > +DI(空头趋势)→ `bearishCount += 1` **名词解释**:→ [ADX 名词解释](../名词解释/ADX-平均趋向指数.md) --- ### 14. SuperTrend(超级趋势指标) ``` 函数:calculateSuperTrend(highs, lows, closes, period=10, multiplier=3) 基础上轨 = (High + Low)/2 + multiplier × ATR(period) 基础下轨 = (High + Low)/2 - multiplier × ATR(period) 方向:direction = 1(多头)或 -1(空头) 开关:signalUseSuperTrend(默认 false) ``` **信号规则**: - 方向由 -1 转 1(转多)→ `bullishCount += 2` - 方向由 1 转 -1(转空)→ `bearishCount += 2` - 方向为 1(多头趋势中)→ `bullishCount += 1` - 方向为 -1(空头趋势中)→ `bearishCount += 1` **名词解释**:→ [SuperTrend 名词解释](../名词解释/SuperTrend-超级趋势指标.md) --- ### 15. ATR(平均真实波动幅度) ``` 函数:calculateATR(highs, lows, closes, period=14) ATR = RMA(TR, period) ``` **在 tradehk 中的用途**:被 SuperTrend 和 DMI 内部使用,不直接显示为独立指标。 **名词解释**:→ [ATR 名词解释](../名词解释/ATR-平均真实波动幅度.md) --- ### 16. TTM Squeeze(挤压动量指标) ``` 函数:calculateTTMSqueeze(highs, lows, closes, bbPeriod=20, kcPeriod=20) Squeeze 状态:布林带完全在肯特纳通道内 → squeeze=true(蓄势) 柱状图 = Close - (最高最低中点 + 布林带中轨) / 2 ``` **信号规则**:柱状图方向反映动量,squeeze=true 时为蓄势状态,突破后方向即为行情方向。 **名词解释**:→ [TTM Squeeze 名词解释](../名词解释/TTM-Squeeze-挤压动量指标.md) --- ## 成交量收缩检测 ``` 函数:detectVolumeContraction(volumes) 逻辑:最近5根K线平均成交量 < 前20根K线平均成交量 × 0.7 ``` 当检测到缩量时,在信号原因列表中添加警告提示,但**不影响评分**。 --- ## 指标参数配置接口 所有指标参数通过 `IndicatorParams` 接口统一管理,详见:[类型系统参考](./类型系统参考.md) ## 相关文档 - [信号评分引擎](./信号评分引擎.md) — 了解各指标如何组合评分 - [大周期偏向判定](./大周期偏向判定.md) — 了解 EWO/MACD/AO 在大周期中的权重 - [EWO 阈值过滤完整流程](../../12_信号系统优化/EWO阈值过滤完整落地流程.md) — 优化建议 --- ## 附录:数据说明与补充 本附录旨在对指标引擎中涉及的关键概念、数据规范及应用提供更详尽的说明,以帮助使用者更深刻地理解和应用这些工具。 ### 一、核心指标深度解析 本文将对文档中提到的核心技术指标进行补充说明,涵盖其数据属性、应用场景及内部链接,以便于读者进行更深入的研究和应用。 #### 1. 移动平均线 (MA / EMA) 移动平均线是技术分析中最基础也最重要的工具之一,用于平滑价格数据,识别趋势方向。tradehk 系统中同时使用了简单移动平均(MA)和指数移动平均(EMA)。 **数据说明** | 属性 | 说明 | | :--- | :--- | | **计算公式** | MA: $$ MA_N(i) = \frac{1}{N} \sum_{k=0}^{N-1} C_{i-k} $$
EMA: $$ EMA_N(i) = \frac{2}{N+1} \times C_i + \left(1 - \frac{2}{N+1}\right) \times EMA_N(i-1) $$ | | **数据范围** | 与标的资产的价格范围保持一致。 | | **单位** | 与标的资产的价格单位相同,如 USD、CNY。 | | **精度要求** | 为保证计算的准确性,建议至少保留 4 位小数。 | | **数据来源** | [K线](../../wiki/名词解释/K线.md)的收盘价(Close)序列。 | **量化交易应用场景** 1. **趋势跟踪策略**:构建均线多头/空头排列策略。例如,当短期均线(如 MA10)上穿长期均线(如 MA100),且价格位于所有均线之上时,产生买入信号;反之则产生卖出信号。这是典型的[趋势跟踪](../../wiki/名词解释/趋势跟踪.md)系统。 2. **动态支撑与阻力**:将长期均线(如 EMA120)视为动态的支撑位或阻力位。当价格回调至该均线附近并出现反弹迹象时,可视为潜在的入场机会。 3. **回归策略**:当价格大幅偏离其长期均线时,可建立均值回归模型,预期价格会向均线回归,从而进行反向交易。 #### 2. EWO (艾略特波浪振荡器) EWO 通过计算两条不同周期的 EMA 之差,来衡量市场的动能和潜在的波浪结构,是 tradehk 信号引擎中的核心权重指标。 **数据说明** | 属性 | 说明 | | :--- | :--- | | **计算公式** | $$ EWO(i) = EMA_{5}(C_i) - EMA_{35}(C_i) $$ | | **数据范围** | 理论上无界,但通常围绕 0 轴在一定范围内波动。 | | **单位** | 与标的资产的价格单位相同。 | | **精度要求** | 建议保留 4 位小数。 | | **数据来源** | 基于[K线](../../wiki/名词解释/K线.md)收盘价计算的 EMA(5) 和 EMA(35)。 | **量化交易应用场景** 1. **主趋势识别**:EWO 的正负值可作为判断当前市场主导力量的依据。EWO > 0 表明多头占优,策略应以做多为主;EWO < 0 表明空头占优,策略应以做空为主。tradehk 的大周期偏向判定正是基于此逻辑。 2. **零轴穿越信号**:EWO 由负转正(上穿零轴)被视为强烈的买入信号,反之则为强烈的卖出信号。这通常标志着一轮新趋势的开始,可用于构建突破策略。 #### 3. MACD (指数平滑异同移动平均线) MACD 是一个经典的趋势和动量指标,通过计算快慢速EMA的离差(DIF)和其本身的EMA(DEA),来捕捉价格动能的变化。 **数据说明** | 属性 | 说明 | | :--- | :--- | | **计算公式** | $$ DIF(i) = EMA_{fast}(C_i) - EMA_{slow}(C_i) $$
$$ DEA(i) = EMA_{signal}(DIF_i) $$
$$ MACD_{Hist}(i) = DIF(i) - DEA(i) $$ | | **数据范围** | 理论上无界。 | | **单位** | 与标的资产的价格单位相同。 | | **精度要求** | 建议保留 4-6 位小数,以精确捕捉交叉点。 | | **数据来源** | [K线](../../wiki/名词解释/K线.md)收盘价序列。 | **量化交易应用场景** 1. **金叉/死叉策略**:当 DIF 线(MACD 线)自下而上穿过 DEA 线(信号线)形成“金叉”,为买入信号;反之形成“死叉”,为卖出信号。这是最常见的 MACD 应用方式。 2. **背离交易**:当价格创出新高而 MACD 指标未能创出新高时,形成“顶背离”,是潜在的下跌信号。反之,当价格创出新低而 MACD 未能创出新低时,形成“底背离”,是潜在的上涨信号。可用于[逆势交易](../../wiki/名词解释/逆势交易.md)。 #### 4. RSI (相对强弱指数) RSI 是一个动量振荡器,衡量价格变动的速度和变化,用于判断市场的超买超卖状态。 **数据说明** | 属性 | 说明 | | :--- | :--- | | **计算公式** | $$ RS = \frac{RMA(U, N)}{RMA(D, N)} $$
$$ RSI = 100 - \frac{100}{1 + RS} $$
其中 U 为上涨期数,D 为下跌期数。 | | **数据范围** | 0 至 100。 | | **单位** | 无。 | | **精度要求** | 建议保留 2 位小数。 | | **数据来源** | [K线](../../wiki/名词解释/K线.md)收盘价序列。 | **量化交易应用场景** 1. **超买超卖策略**:当 RSI 进入超买区(如 > 70)并出现回落迹象时,执行卖出操作;当 RSI 进入超卖区(如 < 30)并出现回升迹象时,执行买入操作。这是典型的振荡市策略。 2. **RSI 背离**:与 MACD 类似,RSI 的背离也是重要的交易信号,常用于捕捉趋势反转点。 ### 二、指标参数参考表 下表整理了 tradehk 指标引擎中各核心指标的可配置参数、系统默认值及推荐的调整范围,供策略开发者参考。 | 指标 | 参数 | 推荐值/默认值 | 取值范围 | 说明 | | :--- | :--- | :--- | :--- | :--- | | **MA** | `period` | 10, 100 | 5 ~ 200 | 周期越短越灵敏,越长越平滑。 | | **EMA** | `period` | 12, 26 | 5 ~ 200 | 用于计算 MACD 和 EWO 的基础。 | | **MACD** | `fastPeriod` | 10 (非标) | 5 ~ 20 | 快速 EMA 周期。 | | | `slowPeriod` | 20 (非标) | 20 ~ 50 | 慢速 EMA 周期。 | | | `signalPeriod` | 10 (非标) | 7 ~ 12 | 信号线(DEA)的 EMA 周期。 | | **RSI** | `period` | 14 | 7 ~ 30 | 计算 RSI 的时间窗口。 | | | `overbought` | 70 | 60 ~ 80 | 超买阈值。 | | | `oversold` | 30 | 20 ~ 40 | 超卖阈值。 | | **KDJ** | `period` | 9 | 9 ~ 21 | 计算 RSV 的时间窗口。 | | | `kSmooth` | 3 | 3 ~ 7 | K 值的平滑周期。 | | | `dSmooth` | 3 | 3 ~ 7 | D 值的平滑周期。 | | **Bollinger Bands** | `period` | 20 | 10 ~ 30 | 中轨 MA 的周期。 | | | `stdDev` | 2 | 1.5 ~ 3.0 | 标准差倍数,决定带宽。 | | **SuperTrend** | `period` | 10 | 7 ~ 21 | ATR 计算周期。 | | | `multiplier` | 3 | 2.0 ~ 5.0 | ATR 乘数,决定趋势线的偏移量。 | | **DMI/ADX** | `period` | 14 | 7 ~ 21 | +DI, -DI, ADX 的计算周期。 | ### 三、数据格式规范 为确保指标引擎的正确运行,输入的数据需遵循以下格式规范: - **输入数据结构**:所有指标函数接收的输入为标准的 K 线数组,其数据结构定义如下: ```json [ { "timestamp": 1672531200000, // Unix 时间戳 (毫秒) "open": 30000.1, "high": 30500.5, "low": 29800.0, "close": 30450.2, "volume": 1234.56 }, // ... more K-line objects ] ``` - **字段类型**: - `timestamp`: `number` (整数) - `open`, `high`, `low`, `close`, `volume`: `number` (浮点数) - **时间戳格式**:必须使用 **Unix 时间戳(毫秒)**,确保时间序列的准确性和一致性。 - **输出数据结构**:指标函数返回一个与输入等长的 `number[]` 数组。在计算周期不足无法生成有效指标值的位置,使用 `NaN` 进行填充。 ### 四、常见误区与正确理解 1. **误区一:指标万能论** - **错误理解**:认为某个或某组指标可以完美预测市场,信号一出现就立即交易。 - **正确理解**:任何技术指标都是对过去价格数据的统计和加工,具有滞后性。它们是辅助决策的工具,而非水晶球。必须结合市场结构、[成交量](../../wiki/名词解释/成交量.md)分析、宏观环境等多维度信息进行综合判断。 2. **误区二:参数神圣化** - **错误理解**:痴迷于寻找一组“最优参数”,并认为这组参数永远有效。 - **正确理解**:市场是动态变化的,不存在一劳永逸的“最优参数”。参数需要根据不同的交易品种、时间周期和市场环境进行适配和调整。过度优化(Overfitting)参数会导致策略在样本外表现急剧下降。 3. **误区三:忽略指标适用环境** - **错误理解**:在所有市场环境下使用同一类指标。例如,在强趋势市场中使用振荡指标(如 RSI, Stoch)。 - **正确理解**:不同指标有不同的适用场景。趋势指标(如 MA, MACD, SuperTrend)适用于趋势明显的市场;振荡指标(如 RSI, KDJ)适用于区间盘整市场。应首先判断当前市场状态,再选择合适的指标工具。 4. **误区四:只看金叉/死叉,不看位置** - **错误理解**:只要 MACD 或 KDJ 出现金叉就买入,出现死叉就卖出。 - **正确理解**:交叉信号的可靠性与其发生的位置密切相关。例如,KDJ 在超卖区(<20)的金叉远比在 50 中轴附近的金叉更具参考价值。MACD 在零轴上方的金叉通常表示多头趋势的延续,而在零轴下方的金叉可能只是下跌趋势中的一次反弹。