ADX ダイナミックトレンド戦略

作者: リン・ハーンチャオチャン開催日:2024年1月15日15時32分45秒
タグ:

img

概要

ADXダイナミックトレンド戦略 (ADX Dynamic Trend Strategy) は,市場トレンドの強さと方向性を決定するためにADX指標を使用する定量的な取引戦略である.市場トレンドが存在するかどうかを判断するために平均指数 (ADX) を計算し,トレンドの方向性を決定するためにポジティブ指数 (DI+) とネガティブ指数 (DI-) を計算することによって購入および販売信号を生成する.

取引の論理

この戦略は,まず ADX インディケーターを使用して,市場でトレンドが存在するか判断する. ADX がユーザー定義のキーレベル (23 デフォルト) を上回ると,市場のトレンドが比較的強いことを示唆する. 現在の ADX 値が n 日前の ADX 値 (n はユーザー定義のバックバック期,デフォルト 3 日) より高いとき, ADX が上昇し,市場でトレンドが形成されていることを示唆する.

この戦略は,DI+とDI-を活用して市場傾向の方向性を決定する.DI+がDI-より高ければ,市場の上昇傾向を示します.DI+がDI-より低い場合は,市場の下落傾向を示します.

最後に,この戦略は ADX と DI の分析を組み合わせて,特定の買取・売却信号を生成します.

  1. ADX が上昇し,キーレベルを超え,DI+ が DI- より高いとき,購入信号が生成されます.
  2. ADX が上昇し,キーレベルを超え,DI+ が DI− よりも低いとき,セールシグナルが生成されます.
  3. ADXが減少すると,フラット位置信号が生成されます.

この戦略は移動平均フィルタリングやカスタマイズ可能なバックテストの時間帯などの機能も提供しています

利点分析

ADX ダイナミックトレンド戦略には以下の利点があります.

  1. 市場動向の存在を自動的に検出し,非効率な取引を回避する
  2. トレンドをフォローする市場動向の方向性を自動的に決定する
  3. トレンドが消えたら購入し,トレンドが消えたら平らにするという 明確な論理
  4. 設定可能な移動平均のフィルタリングは,誤ったブレイクを避ける
  5. 過去のテストのバックテストの可変時間範囲
  6. 異なる製品間での最適化のための調整可能な指標パラメータ

リスク分析

この戦略にはいくつかのリスクもあります:

  1. ADX指標は遅延効果があり,初期トレンドの機会を逃している可能性があります
  2. DI に依存するトレンド方向は,DI が敏感であるため,誤った信号を生む可能性があります.
  3. 移動平均フィルターは短期的な機会を見逃す可能性があります
  4. バックテストの不適切な時間枠は,オーバーフィッティングを引き起こす可能性があります
  5. 不適切な指標パラメータが戦略の業績に影響を与える

リスクを軽減するために,次のことを考慮することができます:

  1. ADX パラメータを短縮して遅延を減らす
  2. 偽信号を防ぐためにDIフィルターを削除または調整する
  3. 移動平均期間の短縮
  4. 完全なサンプルテストのためのバックテストの時間枠を拡大
  5. 最適な設定を見つけるためにパラメータを最適化

増進 の 機会

戦略は次の側面から強化される:

  1. 複数の株を対象としたポートフォリオテストで,単一株リスクの多様化
  2. ストップ・ロスのロジックをトレード・ロスの制御に追加する
  3. 精度を向上させるため,シグナル検証のための他の指標と組み合わせる
  4. 買い/売るシグナル生成のための機械学習アルゴリズムを導入
  5. ダイナミック調整のための自動パラメータ調節モジュールを追加

結論

ADXダイナミックトレンド戦略は,トレンドの存在とトレンド方向のDIを決定するためにADXを使用する.トレンドが存在するときに取引信号を生成し,トレンドが消えたときにポジションを平らにする.論理は明確である.トレンドを自動的に検出し,追跡することで,トレンドのない市場で不効率な取引は一定程度回避できる.適切な強化により,この戦略は中長期的定量取引のための強力なツールになることができます.


/*backtest
start: 2024-01-07 00:00:00
end: 2024-01-14 00:00:00
period: 10m
basePeriod: 1m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=4
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © millerrh with inspiration from @9e52f12edd034d28bdd5544e7ff92e 
//The intent behind this study is to look at ADX when it has an increasing slope and is above a user-defined key level (23 default). 
//This is to identify when it is trending.
//It then looks at the DMI levels.  If D+ is above D- and the ADX is sloping upwards and above the key level, it triggers a buy condition.  Opposite for short.
//Can use a user-defined moving average to filter long/short if desried.
// NOTE: THIS IS MEANT TO BE USED IN CONJUNCTION WITH MY "ATX TRIGGER" INDICATOR FOR VISUALIZATION. MAKE SURE SETTINGS ARE THE SAME FOR BOTH.

strategy("ADX | DMI Trend", overlay=true, initial_capital=10000, currency='USD', 
   default_qty_type=strategy.percent_of_equity, default_qty_value=100, commission_type=strategy.commission.percent, commission_value=0.04)

// === BACKTEST RANGE ===
From_Year  = input(defval = 2019, title = "From Year")
From_Month = input(defval = 1, title = "From Month", minval = 1, maxval = 12)
From_Day   = input(defval = 1, title = "From Day", minval = 1, maxval = 31)
To_Year    = input(defval = 9999, title = "To Year")
To_Month   = input(defval = 1, title = "To Month", minval = 1, maxval = 12)
To_Day     = input(defval = 1, title = "To Day", minval = 1, maxval = 31)
Start  = timestamp(From_Year, From_Month, From_Day, 00, 00)  // backtest start window
Finish = timestamp(To_Year, To_Month, To_Day, 23, 59)        // backtest finish window

// == INPUTS ==
// ADX Info
adxlen = input(14, title="ADX Smoothing")
dilen = input(14, title="DI Period")
keyLevel = input(23, title="Keylevel for ADX")
adxLookback = input(3, title="Lookback Period for Slope")

// == FILTERING ==
// Inputs
useMaFilter = input(title = "Use MA for Filtering?", type = input.bool, defval = true)
maType = input(defval="EMA", options=["EMA", "SMA"], title = "MA Type For Filtering")
maLength   = input(defval = 200, title = "MA Period for Filtering", minval = 1)

// Declare function to be able to swap out EMA/SMA
ma(maType, src, length) =>
    maType == "EMA" ? ema(src, length) : sma(src, length) //Ternary Operator (if maType equals EMA, then do ema calc, else do sma calc)
maFilter = ma(maType, close, maLength)
plot(maFilter, title = "Trend Filter MA", color = color.green, linewidth = 3, style = plot.style_line, transp = 50)

// Check to see if the useMaFilter check box is checked, this then inputs this conditional "maFilterCheck" variable into the strategy entry 
maFilterCheck = if useMaFilter == true
    maFilter
else
    close

// == USE BUILT-IN DMI FUNCTION TO DETERMINE ADX AND BULL/BEAR STRENGTH
[diplus, diminus, adx] = dmi(dilen, adxlen)

buySignal = (adx[0]-adx[adxLookback] > 0) and adx > keyLevel and diplus > diminus  and close >= maFilterCheck
// buySignalValue = valuewhen(buySignal, close, 0)
shortSignal = (adx[0]-adx[adxLookback] > 0) and adx > keyLevel and diplus < diminus  and close <= maFilterCheck
// shortSignalValue = valuewhen(shortSignal, close, 0)
sellCoverSignal = adx[0]-adx[adxLookback] < 0

// == ENTRY & EXIT CRITERIA
// Triggers to be TRUE for it to fire of the BUY Signal : (opposite for the SELL signal).
// (1): Price is over the 200 EMA line. (EMA level configurable by the user)
// (2): "D+" is OVER the "D-" line
// (3): RSI 7 is under 30 (for SELL, RSI 7 is over 70)
// 1* = The ultimate is to have a combination line of 3 EMA values, EMA 14, EMA 50 and EMA 200 - And if price is over this "combo" line, then it's a strong signal

// == STRATEGY ENTRIES/EXITS == 
strategy.entry("Long", strategy.long, when = buySignal)
strategy.close("Long", when = sellCoverSignal)
strategy.entry("Short", strategy.short, when = shortSignal)
strategy.close("Short", when = sellCoverSignal)
    
// == ALERTS == 
// alertcondition(buySignal, title='ADX Trigger Buy', message='ADX Trigger Buy')
// alertcondition(sellSignal, title='ADX Trigger Sell', message='ADX Trigger Sell')

もっと