在实现ADX指标时,如何准确计算+DI和-DI是关键难点。常见问题是:在计算真实波幅(TR)、上升方向动向(+DM)和下降方向动移(-DM)后,未正确进行平滑处理,导致+DI和-DI失真。例如,直接使用原始DM值而非14周期指数或简单移动平均,或在TR为零时未合理处理除零异常。此外,初学者常忽略方向线的平滑机制,误用单日DM/TR比值作为最终结果。如何基于Wilders平滑法(如前一日平滑值×13 + 当日值)精确递推+DI与-DI?这是确保ADX计算准确的核心环节。
1条回答 默认 最新
祁圆圆 2025-09-24 15:11关注1. ADX指标中的+DI与-DI计算:基础概念解析
平均方向指数(ADX)是Welles Wilder提出的技术分析工具,用于衡量趋势强度。其核心组成部分包括正方向指标(+DI)、负方向指标(-DI)和ADX本身。其中,+DI和-DI的准确计算是整个系统可靠性的基石。
在开始计算前,必须先理解三个关键中间变量:
- 真实波幅(True Range, TR):取以下三者最大值:
- 当日高点与低点之差(High - Low)
- |High - 前一日收盘|
- |Low - 前一日收盘|
- +DM(Positive Directional Movement):若当日High - 前日High > 前日Low - 当日Low且前者为正,则+DM = High - 前日High;否则为0。
- -DM(Negative Directional Movement):反之,若前日Low - 当日Low > 当日High - 前日High且前者为正,则-DM = 前日Low - 当日Low;否则为0。
这些原始值虽反映短期动向变化,但直接使用会导致噪声过大。
2. 平滑处理的重要性与Wilders平滑法原理
未经平滑的+DM、-DM和TR序列波动剧烈,无法稳定反映趋势方向。因此,Wilders引入了一种特殊的指数加权移动平均机制——即“Wilders平滑”:
周期数(n) 平滑因子α 递推公式 14 1/14 ≈ 0.0714 SMMA = (前一日SMMA × 13 + 当日值) / 14 9 1/9 ≈ 0.1111 同理可得 n 1/n SMMA_t = (SMMA_{t-1} × (n-1) + X_t) / n 这种平滑方式等价于EMA的一种变体,但起始初始化需特别注意:首期SMMA通常用前n日简单平均作为种子值。
例如,在计算TR的14周期SMMA时,前14天的TR求算术平均,作为第14天的初始SMMA(TR)。
3. 关键难点一:+DM与-DM的平滑处理流程
常见错误在于直接将单日+DM/TR比值当作+DI输出。正确的做法如下:
- 对+DM序列进行14周期Wilders平滑,得到平滑后+DM14
- 对-DM序列进行同样处理,得-DM14
- 对TR序列也执行14周期Wilders平滑,得TR14
代码示例如下(Python风格伪代码):
def wilders_smooth(series, n=14): smoothed = [np.nan] * len(series) smoothed[n-1] = np.mean(series[:n]) # 初始值 for i in range(n, len(series)): smoothed[i] = (smoothed[i-1] * (n-1) + series[i]) / n return smoothed # 应用于+DM, -DM, TR plus_dm_smooth = wilders_smooth(plus_dm_values) minus_dm_smooth = wilders_smooth(minus_dm_values) tr_smooth = wilders_smooth(true_ranges)此步骤确保了所有输入变量在同一时间尺度上具备可比性。
4. 关键难点二:避免除零异常与数值稳定性处理
当市场处于横盘状态时,可能出现连续多日价格不变的情况,导致TR为零。此时若直接计算+DI或-DI,会出现除以零的异常:
+DI = (+DM₁₄ / TR₁₄) × 100 -DI = (-DM₁₄ / TR₁₄) × 100解决方案包括:
- 判断TR₁₄是否接近零(如小于1e-8),若是则设+DI = 0 或保持前值
- 使用条件判断防止浮点异常
- 在数据预处理阶段剔除无效K线(如无交易记录)
实际工程中建议采用安全除法函数:
def safe_div(a, b, default=0.0): return a / b if abs(b) > 1e-8 else default5. 完整+DI与-DI递推实现逻辑流程图
graph TD A[获取OHLC数据] --> B[计算每日TR, +DM, -DM] B --> C{是否满14周期?} C -- 否 --> D[累积原始值] C -- 是 --> E[计算首期SMMA(+DM), SMMA(-DM), SMMA(TR)] D --> F[继续积累] E --> G[进入递推阶段] G --> H[应用Wilders公式更新各SMMA] H --> I[计算+DI = (SMMA(+DM)/SMMA(TR)) * 100] I --> J[计算-DI = (SMMA(-DM)/SMMA(TR)) * 100] J --> K[输出+DI/-DI序列]该流程强调了从原始数据到最终指标的完整生命周期管理,尤其关注初始窗口填充和平滑启动问题。
6. 实践中的典型误用案例对比分析
错误类型 表现形式 后果 修正方案 未平滑直接比值 用当日+DM/TR作+DI 剧烈跳变,假信号频发 强制使用Wilders平滑后的分母与分子 错误初始化 SMMA初值设为0或第一项 前若干周期失真 使用前n项均值初始化 忽略TR为零 程序崩溃或NaN传播 后续指标中断 加入安全除法与边界检测 周期不一致 +DM用SMA而TR用EMA 比例失衡 统一使用Wilders平滑 动态周期调整缺失 固定14周期不适应不同品种 灵敏度偏差 支持参数化配置 这些问题在高频回测系统中尤为敏感,可能导致策略误判。
本回答被题主选为最佳回答 , 对您是否有帮助呢?解决 无用评论 打赏 举报- 真实波幅(True Range, TR):取以下三者最大值: