本篇旨在測試 pandas-ta 套件的趨向指標 DMI (Directional Movement Index) 的 ta.adx() 函式與 df.ta.adx() 方法.
本系列全部文章索引參考 :
11. 計算 DMI (Directional Movement Index) 指標 :
DMI 指標是美國著名的技術分析大師 Welles Wilder 在 1978 年出版的 "New Concepts in Technical TRading Systems" 一書中所提出 (他也是 RSI 與 ATR 指標的發明人), 是唯一具有最高價, 最低價, 與收盤價相對關係, 可分開探討多空力道, 完整分析股價波動情形的指標. DMI 的核心概念是透過比較每天最高價與最低價的變動來了解買賣力量誰佔優勢, 能在多空循環中探求價格上升與下降的均衡點, 適時引導投資人進場或出場.
DMI 由三個主要組件組成, 通常在圖表上以三條線呈現, 摘要整理如下 :
- 正向趨向指標 (+DI) :
用途 : 衡量多頭力量或向上的壓力
意義 : +DI 線上升時表示價格向上移動的強度增加 - 負向趨向指標 (-DI) :
用途 : 衡量空頭力量或向下的壓力
意義 : -DI 線上升表示價格向下移動的強度增加 - 平均趨向指數 (ADX) :
用途 : 衡量整體趨勢的強度 (或稱動能方向無關。
意義 : 這是 DMI 系統中最關鍵的指標. ADX 線上升只表示趨勢 (無論漲跌) 正在變強, ADX 線下降則表示趨勢正在減弱或市場進入盤整. 注意, ADX 只代表趨勢強弱, 不判斷多空方向.
首先計算方向移動 (Directional Movement) +DM 與 -DM, 公式如下 :
+DM = max(High_today − High_yesterday, 0)
−DM = max(Low_yesterday − Low_today, 0)
若 +DM < −DM 則使用 −DM
若 −DM < +DM 則使用 +DM
若同時不成立, 則 +DM 與 −DM 設為 0
其次計算真實波幅 TR (True Range) :
TR = max(
High_today − Low_today,
abs(High_today − Close_yesterday),
abs(Low_today − Close_yesterday)
)
然後用 +DM, -DM, 與 TR 計算方向指標 DI (Directional Indicator) :
+DI = ( 平滑(+DM) / 平滑(TR) ) × 100
−DI = ( 平滑(−DM) / 平滑(TR) ) × 100
最後計算平均趨向指數 ADX (Average Directional indeX) :
DX = abs(+DI − −DI) / (+DI + −DI) × 100
ADX = DX 的平滑移動平均(常用 14 天)
DMI 指標的 +DI 與 -DI 線的相對位置提供了趨勢方向的交易信號 :
| +DX 與 -DX 位置 | 趨勢 | 交易信號 |
|---|---|---|
| +DI > -DI | 多頭趨勢 | 買盤力量佔優,可做多或持有多頭倉位 |
| -DI > +DI | 空頭趨勢 | 賣盤力量佔優,可做空或持有空頭倉位 |
| DI 交叉 | 趨勢發生轉變 | +DI 上穿 -DI 為買入;-DI 上穿 +DI 為賣出 |
DMI 指標的 ADX 線數值用來判斷當前市場狀態並選擇適合的策略 :
| ADX 值 | 市場狀態 | 策略 |
|---|---|---|
| ADX > 25 | 強勢趨勢 | 適合順勢交易、趨勢追蹤或突破策略 |
| ADX 介於 20–25 | 趨勢形成中 (中等強度) | 需謹慎確認,趨勢可能正在醞釀 |
| ADX < 20 | 弱勢趨勢 (盤整) | 避免順勢交易,可使用震盪指標策略 |
整合 +DX, -DX, 與 ADX 交易信號可得下表之交易策略 :
| 指標訊號 | 市場狀態 | 交易策略與建議 |
|---|---|---|
| +DI 上穿 −DI (黃金交叉) |
ADX > 25 強勢多頭 | 多頭進場訊號成立, 可偏積極布局, 適合加碼與順勢操作 |
| ADX 介於 20–25 趨勢醞釀 | 可小量佈局做多, 須等待 ADX 持續上升確認趨勢避免躁進 | |
| ADX < 20 弱勢/盤整 | 不建議進場, 多頭訊號容易失敗, 適合等待突破或震盪策略 | |
| −DI 上穿 +DI (死亡交叉) |
ADX > 25 強勢空頭 | 空頭進場訊號成立, 可做空或減碼持股, 適合追空與破底策略 |
| ADX 介於 20–25 趨勢醞釀 | 可小量部位做空, 須等 ADX 持續升高確認空頭行情 | |
| ADX < 20 弱勢/盤整 | 不建議追空, 行情可能反覆震盪, 適合區間交易策略 |
pandas-ta 套件提供 ta.adx() 計算 DMI 指標, 傳回值均為 DataFrame 物件. 下面程式碼利用 yfinance 取得台股 0050 價量資料來計算 DMI 指標, 並於 K 線圖的副圖中繪製 +DI, -DI, 與 ADX 這 3 條曲線 :
# pandas-ta-dmi.py
import yfinance as yf
import pandas_ta as ta
from kbar import KBar
import pandas as pd
#=========================
# 下載資料
#=========================
df=yf.download('0050.TW', start='2024-11-06', end='2025-01-09', auto_adjust=False)
df.columns=df.columns.map(lambda x: x[0] if isinstance(x, tuple) else x) # 欄位單層化
#=========================
# 計算 DMI 系統 (+DI, -DI, ADX)
# pandas-ta 預設 length=14 天
#=========================
# ta.adx() 函數會返回包含 ADX, +DI (DMP), -DI (DMN) 的 DataFrame
dmi_df=ta.adx(
high=df['High'],
low=df['Low'],
close=df['Close'],
length=14 # 使用預設 14 週期
)
# 將 DMI 結果合併回主 DataFrame
# 欄位名稱預設為 ADX_14, DMP_14, DMN_14
df=df.join(dmi_df)
#=========================
# 使用 pandas 創建常數序列模擬水平線
#=========================
# 創建數值為 20 的常數序列 (用於模擬水平線)
df['HLine_20'] = pd.Series(20, index=df.index)
# 創建數值為 25 的常數序列
df['HLine_25'] = pd.Series(25, index=df.index)
#=========================
# 建 KBar + 繪圖設定
#=========================
kb=KBar(df)
# Panel 2 ➜ DMI 系統
# 繪製 ADX (趨勢強度,通常設為黑色或較粗線)
kb.addplot(df['ADX_14'], panel=2, color='black', width=1.5, ylabel='DMI / ADX')
# 繪製 +DI (多頭力量,綠色)
kb.addplot(df['DMP_14'], panel=2, color='green', width=1.0)
# 繪製 -DI (空頭力量,紅色)
kb.addplot(df['DMN_14'], panel=2, color='red', width=1.0)
# *** 繪製參考線 (使用常數序列) ***
kb.addplot(df['HLine_20'], panel=2, color='gray', linestyle='--', width=0.8)
kb.addplot(df['HLine_25'], panel=2, color='gray', linestyle='--', width=0.8)
#=========================
# 畫圖
#=========================
kb.plot(
volume=True, # Panel 1=Volume
mav=(5, 10), # K線主圖疊 5 & 10 MA
title='K 線圖與 DMI (趨向指標) 系統'
)
結果如下 :
可見 ADX 強度 (左側 Y 軸) 都在 10~12 之間, 遠低於 20, 表示趨勢不明顯, 股價處於盤整狀態, 市場處於弱勢震盪狀態, 交易者應避免使用強勢的趨勢追蹤策略.

沒有留言 :
張貼留言