ADX指標に基づくトレンド追跡と短期取引戦略

作者: リン・ハーンチャオチャン開催日:2024年1月22日 17時10分55秒
タグ:

img

概要

この戦略は,スーパートレンド,ピボットポイント,平均真のレンジ (ATR) を組み合わせ,ダイナミックなストップ・ロストラインと,トレンドを判断し追跡するための平均方向運動指数 (ADX) を組み合わせます.この戦略は,短期取引に適しており,レンジに制限された後にトレンドの継続を捉えることができます.引き下げ制御も良好です.

原則

スーパートレンドは,ピボットポイントとATRストップロスの組み合わせで,ダイナミックストップロスの線を突破する価格の方向を判断し,開通方向を決定します.同時に,ADXインジケーターはトレンドの強さを判断し,トレンドが十分に強いときにのみ取引信号を発行します.

ピホットポイントは,先日2日の算術平均値で動的中値を形成する.その後,ATRはATR因数で計算され,倍数され,その後動的中値に加算または減算され,上下線が得られる.価格が上線線を突破すると上昇傾向にある.下線を突破すると下線傾向にある.ADXインジケーターはトレンドの強さを判断し,トレンドが十分に強い場合にのみ取引に参加する.

ストップ・ロスは,最新の価格とATR値に応じて動的に調整され,トレンドをよく追跡できます.

利点分析

この戦略には以下の利点があります.

  1. スーパートレンドインジケーターを使用して,トレンドの走行方向を追跡し,変動する市場によって利益が固定されないようにします.

  2. ADX インディケーターの助けで トレンドの強さを判断し,統合の際に取引の誤りを避ける.

  3. ストップ損失線は ロークイン利益を最大化するために 動的に調整されます

  4. RSIを組み合わせて 買い過ぎや売り過ぎを避ける

  5. 一般的に,戦略パラメータ設定は合理的です. dframe の選択は継続性を考慮します. 利益とストップ損失の設定も良好です.

リスク分析

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

  1. スーパートレンドとMAインジケーターは矛盾する信号を発する可能性があります.

  2. ADX インジケーターは 14 サイクルに設定されており,突発的な出来事には十分敏感ではありません.

  3. RSIパラメータはデフォルト設定で,過剰購入と過剰販売を完全に回避できない可能性があります.

  4. 悪いニュースや良いニュースなど 突然の出来事の影響は考慮されていません.

対応する解法:

  1. MAサイクルをスーパートレンド指標に合わせて調整する.

  2. ADX サイクルを短縮して突然の出来事に対する敏感性を高めるようにしてください.

  3. RSIのパラメータを最適化して 最適値を見つけます

  4. ニュースフィルターモジュールを追加して,主要なニュースリリースを回避します.

最適化

戦略は,次の側面でも最適化できます.

  1. マシン学習モデルを追加して 傾向を判断し 取引決定をより賢くします

  2. ADXの代わりに 感情指標を導入して 傾向の強さを判断してみてください

  3. ストップ損失をよりダイナミックで正確にするための 適応型ストップ損失モジュールを増やす.

  4. 総合戦略を最適化するために ディープラーニング技術でより多くの機能を抽出します

  5. 戦略の拡張性を高めるために Pythonのような高度な言語を使用します

概要

この戦略は,全体的に非常に実用的です. 基本的には,トレンドの走行方向を追跡し,トレンドが十分に強いときに参加することです. ストップ・ロストとテイク・プロフィートの設定は,損失を回避しながら利益を最大限に抑えるためにも非常に有効です. もちろん,最適化するにはまだ多くの余地があります. 機械学習とディープ・ラーニング技術を追加することで,戦略はより効果的で拡張可能になります.


/*backtest
start: 2023-01-15 00:00:00
end: 2024-01-21 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=5
strategy("Bendre ADX STrend", overlay = true)

///////////////////////////
// SuperTrend + Pivot Point
//////////////////////////

src =  input(close, title="EMA Source")
PPprd = input(defval = 2, title="Pivot Point Period")
AtrFactor=input(defval = 2, title = "ATR Factor")
AtrPd=input(defval = 21, title = "ATR Period")

StartDate = input(timestamp("1 Dec 2023"), title="Start Date")
EndDate = input(timestamp("12 Jan 2024"), title="End Date")
window()  => true

var float ph = na
var float pl = na
ph := ta.pivothigh(PPprd, PPprd)
pl :=ta.pivotlow(PPprd, PPprd)

float center = na
center := center[1]
// float lastpp = ph ? ph : pl ? pl : 0.0
float lastpp = na(ph) ? na(pl) ? na : pl : ph

if lastpp > 0
    if na(center)
        center := lastpp
    else
        center := (center * 2 + lastpp) / 3

Up = center - (AtrFactor * ta.atr(AtrPd))
Dn = center + (AtrFactor * ta.atr(AtrPd))

var float TUp = na
var float TDown = na
Trend = 0
TUp := close[1] > TUp[1] ? math.max(Up, TUp[1]) : Up
TDown := close[1] < TDown[1] ? math.min(Dn, TDown[1]) : Dn
Trend := close > TDown[1] ? 1: close < TUp[1]? -1: nz(Trend[1], 1)
Trailingsl = Trend == 1 ? TUp : TDown

// Lines
linecolor = Trend == 1 and nz(Trend[1]) == 1 ? color.lime : Trend == -1 and nz(Trend[1]) == -1 ? color.red : na
plot(Trailingsl, color = linecolor ,  linewidth = 2, title = "PP SuperTrend")

bsignalSSPP = close > Trailingsl
ssignalSSPP = close < Trailingsl


///////
// ADX
//////

lenADX = 14
th = 14
TrueRange = math.max(math.max(high-low, math.abs(high-nz(close[1]))), math.abs(low-nz(close[1])))
DirectionalMovementPlus = high-nz(high[1]) > nz(low[1])-low ? math.max(high-nz(high[1]), 0): 0
DirectionalMovementMinus = nz(low[1])-low > high-nz(high[1]) ? math.max(nz(low[1])-low, 0): 0
SmoothedTrueRange = 0.0
SmoothedTrueRange := nz(SmoothedTrueRange[1]) - (nz(SmoothedTrueRange[1])/lenADX) + TrueRange
SmoothedDirectionalMovementPlus = 0.0
SmoothedDirectionalMovementPlus := nz(SmoothedDirectionalMovementPlus[1]) - (nz(SmoothedDirectionalMovementPlus[1])/lenADX) + DirectionalMovementPlus
SmoothedDirectionalMovementMinus = 0.0
SmoothedDirectionalMovementMinus := nz(SmoothedDirectionalMovementMinus[1]) - (nz(SmoothedDirectionalMovementMinus[1])/lenADX) + DirectionalMovementMinus
DIPlus = SmoothedDirectionalMovementPlus / SmoothedTrueRange * 100
DIMinus = SmoothedDirectionalMovementMinus / SmoothedTrueRange * 100
DX = math.abs(DIPlus-DIMinus) / (DIPlus+DIMinus)*100
ADX = ta.sma(DX, lenADX)


//////
// MA
/////

lenMA = 21
srcMA = input(close, title="Source")
// offsetMA = input(title="Offset", type=input.integer, defval=0, minval=-500, maxval=500)
offsetMA = input(0, title="Offset")
outMA = ta.sma(srcMA, lenMA)

//
// RSI
//
length = input( 14 )
overSold = input( 30 )
overBought = input( 65 )
price = close
vrsi = ta.rsi(price, length)

//
// DMI - Direction Movement Index
// 
[diplus1, diminus1, adx] = ta.dmi(14, 14)

// Buy - Sell Entries
buy = bsignalSSPP and outMA < close and ADX > th
sell = ssignalSSPP 


if (buy and vrsi > overBought and adx > 19)
    // .order // Tuned version
    strategy.entry("Buy", strategy.long, when = window())
    // strategy.close("Sell", "close Sell")

if (sell) and (strategy.position_size > 0)
    // strategy.entry("Sell", strategy.short)
    strategy.close("Buy", "Close Buy")

if(sell and vrsi < overSold and adx > 25)
    strategy.entry("Sell", strategy.short, when = window())

if ( ta.crossover( diminus1, diplus1) or ((buy) and (strategy.position_size > 0)) )
    strategy.close("Sell", "close Sell")

// if(sell) and (diminus1 > diplus1) and adx > 23 and adx > adx[1] and (vrsi < overSold)
//     strategy.entry("Sell", strategy.short, when = window())

// if (strategy.position_size > 0 and ta.crossunder(diminus1, adx)) or (strategy.position_size > 0  and (buy))
//     strategy.close("Sell", "close Sell")





もっと