# My語言怎么實現DMI量化交易策略
## 一、DMI指標原理概述
DMI(Directional Movement Index)方向移動指標是由J.Welles Wilder開發的技術分析工具,主要用于判斷市場趨勢強度和方向。該指標包含四個核心組件:
1. **+DI(正向指標)**:反映上升趨勢強度
2. **-DI(負向指標)**:反映下降趨勢強度
3. **ADX(平均趨向指數)**:衡量整體趨勢強度
4. **ADXR(平均趨向指數評級)**:ADX的平滑版本
經典交易規則:
- 當+DI上穿-DI且ADX>25時,產生買入信號
- 當-DI上穿+DI且ADX>20時,產生賣出信號
## 二、My語言環境準備
### 2.1 開發環境配置
```my
// 檢查并導入必要庫
if not library_exists("quant") then
import quant as q
end
// 設置回測參數
start_time = "2020-01-01"
end_time = "2023-12-31"
capital = 100000
commission = 0.0005 // 萬五手續費
// 獲取滬深300指數數據
function get_data()
data = q.get_history(
symbol="000300.SH",
start=start_time,
end=end_time,
frequency="1d",
fields=["open","high","low","close","volume"]
)
return data
end
function calc_tr(high, low, prev_close)
tr1 = high - low
tr2 = abs(high - prev_close)
tr3 = abs(low - prev_close)
return max(tr1, tr2, tr3)
end
function calc_dm(high, prev_high, low, prev_low)
up_move = high - prev_high
down_move = prev_low - low
+dm = up_move > down_move and up_move > 0 ? up_move : 0
-dm = down_move > up_move and down_move > 0 ? down_move : 0
return +dm, -dm
end
function dmi(data, period=14)
// 初始化數組
len = length(data.close)
+di = array(len)
-di = array(len)
adx = array(len)
// 計算初始值
for i = 1 to period
+di[i] = 0
-di[i] = 0
adx[i] = 0
end
// 主計算循環
for i = period+1 to len
// 計算平滑TR和DM
tr_sum = 0
+dm_sum = 0
-dm_sum = 0
for j = i-period+1 to i
tr = calc_tr(data.high[j], data.low[j], data.close[j-1])
+dm, -dm = calc_dm(data.high[j], data.high[j-1],
data.low[j], data.low[j-1])
tr_sum += tr
+dm_sum += +dm
-dm_sum += -dm
end
// 計算DI值
+di[i] = 100 * (+dm_sum / tr_sum)
-di[i] = 100 * (-dm_sum / tr_sum)
// 計算DX和ADX
dx = 100 * abs(+di[i] - -di[i]) / (+di[i] + -di[i])
adx[i] = i == period+1 ? dx : (adx[i-1]*(period-1) + dx)/period
end
return +di, -di, adx
end
function generate_signals(data)
+di, -di, adx = dmi(data)
signals = array(length(data.close))
position = 0 // 0:空倉 1:多頭 -1:空頭
for i = 2 to length(data.close)
// 多頭信號:+DI上穿-DI且ADX>25
if +di[i] > -di[i] and +di[i-1] <= -di[i-1] and adx[i] > 25
signals[i] = 1
position = 1
// 空頭信號:-DI上穿+DI且ADX>20
elseif -di[i] > +di[i] and -di[i-1] <= +di[i-1] and adx[i] > 20
signals[i] = -1
position = -1
// 持倉延續
else
signals[i] = position
end
end
return signals
end
function backtest(data, signals)
returns = array(length(data.close))
equity = array(length(data.close))
equity[1] = capital
for i = 2 to length(data.close)
// 計算收益率
if signals[i-1] == 1 // 多頭
ret = (data.close[i]/data.close[i-1] - 1) - commission
elseif signals[i-1] == -1 // 空頭
ret = (1 - data.close[i]/data.close[i-1]) - commission
else
ret = 0
end
returns[i] = ret
equity[i] = equity[i-1] * (1 + ret)
end
return equity, returns
end
function optimize_parameters(data)
best_sharpe = -inf
best_period = 0
best_adx_th = 0
// 參數搜索空間
for period = 10 to 20 step 2
for adx_th = 15 to 30 step 5
+di, -di, adx = dmi(data, period)
signals = generate_signals_modified(data, +di, -di, adx, adx_th)
equity, returns = backtest(data, signals)
sharpe = calculate_sharpe(returns)
if sharpe > best_sharpe
best_sharpe = sharpe
best_period = period
best_adx_th = adx_th
end
end
end
return best_period, best_adx_th
end
function add_stoploss(signals, data, stoploss_pct=0.05)
modified_signals = copy(signals)
entry_price = 0
for i = 2 to length(data.close)
// 記錄入場價格
if signals[i] !=0 and signals[i-1] ==0
entry_price = data.close[i]
end
// 檢查止損
if signals[i] ==1 and (data.close[i] < entry_price*(1-stoploss_pct))
modified_signals[i] = 0
elseif signals[i] ==-1 and (data.close[i] > entry_price*(1+stoploss_pct))
modified_signals[i] = 0
end
end
return modified_signals
end
function evaluate(equity, returns)
// 年化收益率
annual_return = (equity[-1]/equity[1])^(252/length(returns)) - 1
// 最大回撤
max_drawdown = 0
peak = equity[1]
for i = 2 to length(equity)
if equity[i] > peak
peak = equity[i]
end
dd = (peak - equity[i])/peak
if dd > max_drawdown
max_drawdown = dd
end
end
// 夏普比率
sharpe = mean(returns)/std(returns) * sqrt(252)
return {
"annual_return": annual_return,
"max_drawdown": max_drawdown,
"sharpe_ratio": sharpe,
"win_rate": calculate_win_rate(returns)
}
end
// 主程序
function main()
// 1. 數據準備
data = get_data()
// 2. 參數優化(可選)
best_period, best_adx_th = optimize_parameters(data)
// 3. 生成信號
+di, -di, adx = dmi(data, best_period)
signals = generate_signals_modified(data, +di, -di, adx, best_adx_th)
signals = add_stoploss(signals, data)
// 4. 回測評估
equity, returns = backtest(data, signals)
metrics = evaluate(equity, returns)
// 5. 結果可視化
plot_results(data, equity, signals)
return metrics
end
// 執行策略
performance = main()
print(performance)
”`
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。