欢迎光临
我们一直在努力

Trend:ADX(平均趋向指数)技术指标详解

Trend:ADX(平均趋向指数)技术指标详解

一、ADX的定义

ADX(Average Directional Index,平均趋向指数) 是由技术分析大师威尔斯·威尔德(Welles Wilder)于1978年在《技术交易系统新概念》一书中提出的经典趋势强度指标。ADX不直接指示趋势的方向(上涨或下跌),而是专门用于衡量趋势的强度。

ADX的核心价值在于帮助交易者回答一个关键问题:当前市场到底有没有趋势? 这个判断是决定使用趋势跟踪策略还是震荡策略的前提条件。

ADX的组成部分

完整的ADX指标实际上包含三条曲线:

曲线名称含义作用
ADX线 趋势强度值 衡量趋势强弱,值越高趋势越强
+DI 正向方向指标 衡量上升动能
-DI 负向方向指标 衡量下降动能

注意:三条线的名称在不同平台略有差异——+DI有时写作DMP,-DI有时写作DMN。pandas_ta库返回的列名即为ADX_14、DMP_14、DMN_14。

二、ADX的计算方法

1. 第一步:计算真实波幅(True Range, TR)

TR衡量一根K线的有效波动范围,取以下三个值的最大值:
TRt=max⁡(Ht−Lt,∣Ht−Ct−1∣,∣Lt−Ct−1∣)
\\mathrm{TR}_t = \\max \\left( \\mathrm{H}_t – \\mathrm{L}_t, \\left| \\mathrm{H}_t – \\mathrm{C}_{t-1} \\right|, \\left| \\mathrm{L}_t – \\mathrm{C}_{t-1} \\right| \\right)
TRt=max(HtLt,HtCt1,LtCt1)

2. 第二步:计算方向移动(Directional Movement, DM)

  • +DM:当前最高价比前日最高价向上突破的幅度,即 Ht−Ht−1\\mathrm{H}_t – \\mathrm{H}_{t-1}HtHt1,仅当该值为正且大于-DM时采用,否则为0
  • -DM:前日最低价比当前最低价向下突破的幅度,即 Lt−1−Lt\\mathrm{L}_{t-1} – \\mathrm{L}_tLt1Lt,仅当该值为正且大于+DM时采用,否则为0

核心逻辑:DM衡量的是多头或空头将价格推出前一日交易区间的能力。如果今天的最高价高于前一天的最高价,说明多头力量在增强。

3. 第三步:平滑处理

对TR、+DM、-DM进行Wilder平滑(周期通常为14):
$$
\\begin{aligned}
平滑\\mathrm{TR}_t &= \\mathrm{WilderSMA}(\\mathrm{TR}, 14)_t \\
\\text{平滑+}\\mathrm{DM}_t &= \\mathrm{WilderSMA}(+\\mathrm{DM}, 14)_t \\
\\text{平滑-}\\mathrm{DM}_t &= \\mathrm{WilderSMA}(-\\mathrm{DM}, 14)_t

\\end{aligned}
$$

4. 第四步:计算方向指标(+DI和-DI)

$$

  • \\mathrm{DI}_t = 100 \\times \\frac{平滑+\\mathrm{DM}_t}{平滑\\mathrm{TR}_t} \\
  • \\mathrm{DI}_t = 100 \\times \\frac{平滑-\\mathrm{DM}_t}{平滑\\mathrm{TR}_t}
    $$

5. 第五步:计算DX(Directional Movement Index)

DX衡量+DI与-DI之间的差距,反映趋势强度:
DXt=100×∣+DIt−-DIt∣+DIt+-DIt
\\mathrm{DX}_t = 100 \\times \\frac{|\\text{+}\\mathrm{DI}_t – \\text{-}\\mathrm{DI}_t|}{\\text{+}\\mathrm{DI}_t + \\text{-}\\mathrm{DI}_t}
DXt=100×+DIt+DIt+DItDIt

6. 第六步:计算ADX

ADX是对DX进行平滑得到的最终指标:
ADXt=WilderSMA(DX,14)t
\\mathrm{ADX}_t = \\mathrm{WilderSMA}(\\mathrm{DX}, 14)_t
ADXt=WilderSMA(DX,14)t

pandas_ta的平滑方式说明:pandas_ta的ADX默认使用Wilder平滑(mamode='rma'),与威尔德原始设计一致。用户可通过mamode='sma'参数改用简单移动平均。

三、ADX的使用方法

1. 数值区间判断——趋势强度分级

ADX数值趋势含义操作建议
< 20 无趋势/盘整 不宜使用趋势跟踪策略,考虑震荡策略
20 – 25 趋势开始萌芽 关注趋势发展,做好入场准备
25 – 40 趋势形成中 可考虑顺势交易,信号逐步可靠
40 – 50 强趋势 顺势持仓,趋势较为可靠
> 50 极强趋势 趋势非常强劲,但需警惕过度延伸

2. 方向判断——+DI与-DI的交叉信号

威尔德建议:当**+DI高于-DI时买入**,当**+DI低于-DI时卖出**。

极值点规则(Wilder的改进):在+DI与-DI交叉时,记录交叉日的最高价或最低价作为入场过滤条件:

  • 买入信号(+DI上穿-DI):必须等到价格突破交叉日的最高价后才能入场
  • 卖出信号(+DI下穿-DI):必须等到价格跌破交叉日的最低价后才能入场

3. ADX与DI的配合策略

市场状态信号特征操作
ADX上升 ADX在两条DI线之间上升 趋势正在加强,顺势持仓,这是最适合趋势跟踪的阶段
ADX下降 ADX从高位回落 趋势在减弱,考虑获利了结,不宜加仓
ADX低于两线 ADX在两条DI线下方 市场横盘,等待ADX向上突破发出新趋势信号

4. ADX极值反转信号

当ADX从底部(两条DI线下方)上升4个点以上时(如从9升到13),威尔德认为这是最强烈的信号——宣告新趋势可能刚刚启动。这种信号每年通常只出现一两次,往往对应重要的趋势转折点。

5. 注意事项与局限性

  • 滞后性是ADX的主要缺点:由于经过多次平滑处理,ADX对价格变化的反应较慢,更适合确认趋势而非捕捉拐点。

  • 在震荡市中ADX会反复穿越20线,产生噪音信号。只有在ADX明确高于25且持续上升时才信任趋势信号。

  • ADX本身不指示方向,必须结合+DI/-DI或价格结构判断多空。

四、使用pandas_ta计算ADX

1. 函数完整参数

pandas_ta.trend.adx(high, low, close, length=None, lensig=None, scalar=None, mamode=None, drift=None, offset=None, **kwargs)

参数默认值说明
high 必需 最高价序列
low 必需 最低价序列
close 必需 收盘价序列
length 14 ADX计算周期
mamode ‘rma’ 平滑方式,'rma’为Wilder平滑,'sma’为简单移动平均

注意:ta.adx()函数返回的是包含三列的DataFrame:ADX_14(趋势强度)、DMP_14(即+DI)、DMN_14(即-DI)。直接赋值给单列会报错,需要正确解包。

2. 示例代码

import pandas as pd
import pandas_ta as ta
import numpy as np
import matplotlib.pyplot as plt

# ========== 准备数据 ==========
np.random.seed(42)
dates = pd.date_range(start='2023-01-01', end='2024-12-31', freq='D')
n = len(dates)

# 生成带趋势和周期波动的价格序列
trend = np.linspace(0, 45, n)
cycle = np.sin(np.linspace(0, 6 * np.pi, n)) * 15
noise = np.random.randn(n) * 3
price_series = 100 + trend + cycle + noise

# 添加趋势变化区间
price_series = price_series.astype(float)
for i in range(300, 450):
price_series[i] = price_series[300] + (i300) * 0.2
for i in range(450, 600):
price_series[i] = price_series[450] (i450) * 0.15

df = pd.DataFrame(index=dates[:n])
df['close'] = price_series[:n]
df['high'] = df['close'] + np.abs(np.random.randn(n)) * 2 + 1
df['low'] = df['close'] np.abs(np.random.randn(n)) * 2 1

print("=" * 60)
print("数据预览:")
print(df.head())
print("\\n" + "=" * 60 + "\\n")

# ========== 计算ADX ==========
# 重要:ta.adx()返回三列DataFrame,不能直接赋值给单列
adx_df = ta.adx(df['high'], df['low'], df['close'], length=14)

# 查看返回的DataFrame结构
print("ADX返回列名称:")
print(adx_df.columns.tolist())
print("\\n" + "=" * 60 + "\\n")

# 将三列正确添加到原DataFrame
df['ADX'] = adx_df['ADX_14'] # ADX线:趋势强度
df['PLUS_DI'] = adx_df['DMP_14'] # +DI线:上升动能
df['MINUS_DI'] = adx_df['DMN_14'] # -DI线:下降动能

print("ADX计算结果(最近10行):")
print(df[['close', 'ADX', 'PLUS_DI', 'MINUS_DI']].tail(10))
print("\\n" + "=" * 60 + "\\n")

# ========== 生成趋势强度信号 ==========
df['trend_signal'] = ''
df.loc[df['ADX'] > 40, 'trend_signal'] = '强趋势'
df.loc[(df['ADX'] > 25) & (df['ADX'] <= 40), 'trend_signal'] = '趋势形成'
df.loc[(df['ADX'] > 20) & (df['ADX'] <= 25), 'trend_signal'] = '趋势萌芽'
df.loc[df['ADX'] <= 20, 'trend_signal'] = '无趋势/盘整'

print("趋势强度分布统计:")
print(df['trend_signal'].value_counts())
print("\\n" + "=" * 60 + "\\n")

# ========== 生成方向信号 ==========
# +DI > -DI 且 ADX > 25 时,上升趋势确认
df['long_signal'] = (df['PLUS_DI'] > df['MINUS_DI']) & (df['ADX'] > 25)

# -DI > +DI 且 ADX > 25 时,下降趋势确认
df['short_signal'] = (df['MINUS_DI'] > df['PLUS_DI']) & (df['ADX'] > 25)

print("方向信号统计:")
print(f"上升趋势信号(+DI > -DI 且 ADX > 25)数量:{df['long_signal'].sum()}")
print(f"下降趋势信号(-DI > +DI 且 ADX > 25)数量:{df['short_signal'].sum()}")
print("\\n" + "=" * 60 + "\\n")

# ========== 策略回测 ==========
# 策略:仅在ADX > 25且+DI > -DI时持仓多头
df['position'] = 0
df.loc[df['long_signal'], 'position'] = 1
df.loc[df['short_signal'], 'position'] = 1

df['returns'] = df['close'].pct_change()
df['strategy_returns'] = df['position'].shift(1) * df['returns']

total_return_buyhold = (1 + df['returns']).prod() 1
total_return_strategy = (1 + df['strategy_returns']).prod() 1

print("=" * 60)
print("策略绩效统计(ADX趋势过滤策略回测):")
print(f"买入持有策略总收益率:{total_return_buyhold:.2%}")
print(f"ADX趋势过滤策略总收益率:{total_return_strategy:.2%}")
print("\\n注意:此为简化回测,仅供参考")
print("=" * 60 + "\\n")

# ========== 可视化 ==========
plt.figure(figsize=(14, 10))

plt.subplot(2, 1, 1)
plt.plot(df.index[200:], df['close'][200:],
label='Close Price', linewidth=1.5, color='black')
plt.title('Price Chart (Last 200 days)', fontsize=14)
plt.ylabel('Price')
plt.legend()
plt.grid(True, alpha=0.3)

plt.subplot(2, 1, 2)
plt.plot(df.index[200:], df['ADX'][200:],
label='ADX (14)', linewidth=1.5, color='blue')
plt.plot(df.index[200:], df['PLUS_DI'][200:],
label='+DI', linewidth=1, color='green')
plt.plot(df.index[200:], df['MINUS_DI'][200:],
label='-DI', linewidth=1, color='red')

plt.axhline(y=25, color='gray', linestyle='–', linewidth=1, label='趋势阈值 (25)')
plt.axhline(y=40, color='orange', linestyle=':', linewidth=1, label='强趋势阈值 (40)')
plt.axhline(y=20, color='purple', linestyle=':', linewidth=1, label='盘整阈值 (20)')

plt.title('ADX(平均趋向指数)- 趋势强度判断', fontsize=14)
plt.xlabel('Date')
plt.ylabel('Value')
plt.legend(loc='upper left')
plt.grid(True, alpha=0.3)

plt.tight_layout()
plt.show()

3. 关键注意事项

正确解包返回值:

# 错误写法(会报错:Wrong number of items passed)
df['ADX'] = ta.adx(df['High'], df['Low'], df['Close'], length=14)

# 正确写法
adx_data = ta.adx(df['high'], df['low'], df['close'], length=14)
df['ADX'] = adx_data['ADX_14']
df['PLUS_DI'] = adx_data['DMP_14']
df['MINUS_DI'] = adx_data['DMN_14']

平滑方式调整:如果需要使用简单移动平均(SMA)而非Wilder平滑,可设置mamode='sma':

adx_sma = ta.adx(df['high'], df['low'], df['close'], length=14, mamode='sma')

五、总结

维度特点
核心功能 衡量趋势强度,不指示方向
组成部分 ADX线 + +DI线 + -DI线
关键阈值 20(盘整)、25(趋势形成)、40(强趋势)
核心用法 趋势过滤:ADX>25时才使用趋势跟踪策略
最佳时机 ADX上升且高于两条DI线时为趋势最强劲的阶段
主要局限 滞后性、不适用震荡市、需配合方向判断

实战使用三原则:

  • ADX是过滤器,不是触发器——先看ADX判断“该不该做趋势”,再用+DI/-DI判断“往哪个方向做”
  • ADX上升时顺势持仓,ADX下降时准备离场——ADX的方向比数值本身更有意义,上升代表趋势在加强
  • ADX低于20时停止使用趋势策略——此时市场处于盘整,顺势交易信号不可靠,应切换为震荡策略或观望
  • 赞(0)
    未经允许不得转载:171主机测评 » Trend:ADX(平均趋向指数)技术指标详解
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址