ADXダイナミックインジケーターと組み合わせた移動平均クロスオーバーの開始と終了の定量取引戦略

MA ADX SMMA EMA DEMA TEMA WMA VWMA HullMA LSMA ALMA SSMA TMA ATR
作成日: 2025-02-18 13:35:54 最終変更日: 2025-02-18 13:35:54
コピー: 1 クリック数: 445
1
フォロー
1617
フォロワー

ADXダイナミックインジケーターと組み合わせた移動平均クロスオーバーの開始と終了の定量取引戦略

概要

これは,開場価格と閉場価格の移動平均線交差に基づいて,平均トレンド指標 ((ADX) をフィルターとして組み合わせた量化取引戦略である.この戦略は,SMMA,EMA,DEMAなどを含む複数の移動平均線タイプを採用し,平均線交差点を識別することによって市場トレンドの変化を捉え,同時に,トレンドの強さを確認するためにADX指標を使用し,取引の信頼性を向上させる.

戦略原則

策略の核心論理は,開盘価格と閉盘価格の移動平均を計算することによって,閉盘価格平均線が開盤価格平均線を向上して,ADX値が設定値より大きいとき,多信号を生成し,閉盘価格平均線が開盤価格平均線をダウンして,ADX値が設定値より大きいとき,空信号を生成することである. 策略は,単一の移動平均線 ((SMA),指標移動平均線 ((EMA),ダブル指標移動平均線 ((EMAD) などを含む,移動平均計算の複数の方法をサポートし,異なる市場特性に応じて最も適した平均線タイプを選択することができます.

戦略的優位性

  1. 柔軟性:複数の移動平均線型をサポートし,異なる市場状況に応じて最適な平均線計算方法を選択できます
  2. トレンド確認:ADX指標のフィルタリングにより,波動市場における偽信号を効果的に軽減する
  3. リスク管理が完ぺき: ストップ・ロスとストップ・ストップ機能を含むため,取引ごとにリスクを効果的に制御できます.
  4. 高度なカスタマイズ性:戦略を最適化するために,平均線周期,ADX値,取引方向などを含む複数のパラメータインターフェースを提供します.
  5. 複数のタイムサイクルをサポート:異なるタイムサイクルで動作し,異なる取引スタイルに対応

戦略リスク

  1. 平均線遅れ:移動平均線は本質的に遅れの指標であり,急速な波動のある市場で遅れの信号を生じることがあります.
  2. 偽突破リスク:市場が揺れ動くと均線偽突破が発生する可能性があるが,ADXフィルターがあるにもかかわらず注意が必要である
  3. パラメータの感受性: パラメータの設定に戦略効果が敏感であり,異なる市場環境で適切な調整が必要である
  4. 市場の適応性: 傾向が顕著な市場では良好なパフォーマンスを発揮しますが,揺れ動いている市場では頻繁に取引される可能性があります.
  5. 計算の複雑性:複数の均線型の計算はシステム負荷を増加させ,運用効率に注意する必要がある

戦略最適化の方向性

  1. ボリューム指標の導入:ボリュームの変化を組み合わせることでトレンドの有効性を確認できます
  2. ADXパラメータの最適化:異なる市場周期の動向に応じてADX値の調整
  3. トレンド確認指標の追加: 信号の信頼性を高めるために,他のトレンド指標の追加を検討することができます.
  4. ストップメカニズムの改善:トラッキングストップまたは波動率自主ストップの導入
  5. 取引時間を最適化:市場の変動や流動性の要因を考慮して,最適な取引時間を選択する

要約する

これは,クラシックな均線交差戦略とADX指標を組み合わせた定量化取引システムである.複数の均線型のサポートとADXのトレンド確認により,市場動向をよりよく把握でき,同時に,完善なリスク制御機構を備えている.戦略のカスタマイズ性が強く,異なる市場環境に応じて最適化調整が可能です.いくつかの固有のリスクがあるものの,合理的なパラメータ設定と継続的な最適化により,この戦略は良い実用価値を持っています.

ストラテジーソースコード
/*backtest
start: 2024-02-18 00:00:00
end: 2025-02-16 08:00:00
period: 3d
basePeriod: 3d
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

// This Pine Script™ code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © algostudio

//@version=6
strategy("Open Close Cross Strategy R5.1", shorttitle="OCC Strategy R5.1", overlay=true,
     pyramiding=0, default_qty_type=strategy.percent_of_equity, default_qty_value=10, calc_on_every_tick=false)

// === INPUTS ===
useRes      = input.bool(true, title="Use Alternate Resolution?")
intRes      = input.int(3, title="Multiplier for Alternate Resolution", minval=1)
stratRes    = timeframe.ismonthly ? str.tostring(timeframe.multiplier * intRes) + "M" :
              timeframe.isweekly ? str.tostring(timeframe.multiplier * intRes) + "W" :
              timeframe.isdaily ? str.tostring(timeframe.multiplier * intRes) + "D" :
              timeframe.isintraday ? str.tostring(timeframe.multiplier * intRes) : "60"

basisType   = input.string("SMMA", title="MA Type:", options=["SMA", "EMA", "DEMA", "TEMA", "WMA", "VWMA", "SMMA", "HullMA", "LSMA", "ALMA", "SSMA", "TMA"])
basisLen    = input.int(8, title="MA Period", minval=1)
offsetSigma = input.int(6, title="Offset for LSMA / Sigma for ALMA", minval=0)
offsetALMA  = input.float(0.85, title="Offset for ALMA", minval=0, step=0.01)
scolor      = input.bool(false, title="Show Colored Bars to Indicate Trend?")
delayOffset = input.int(0, title="Delay Open/Close MA (Forces Non-Repainting)", minval=0, step=1)
tradeType   = input.string("BOTH", title="What trades should be taken:", options=["LONG", "SHORT", "BOTH", "NONE"])

// === BASE FUNCTIONS ===
variant(type, src, len, offSig, offALMA) =>
    if type == "EMA"
        ta.ema(src, len)
    else if type == "DEMA"
        ta.ema(ta.ema(src, len), len) * 2 - ta.ema(ta.ema(ta.ema(src, len), len), len)
    else if type == "TEMA"
        3 * (ta.ema(src, len) - ta.ema(ta.ema(src, len), len)) + ta.ema(ta.ema(ta.ema(src, len), len), len)
    else if type == "WMA"
        ta.wma(src, len)
    else if type == "VWMA"
        ta.vwma(src, len)
    else if type == "SMMA"
        ta.sma(src, len)
    else if type == "HullMA"
        ta.wma(2 * ta.wma(src, len / 2) - ta.wma(src, len), math.round(math.sqrt(len)))
    else if type == "LSMA"
        ta.linreg(src, len, offSig)
    else if type == "ALMA"
        ta.alma(src, len, offALMA, offSig)
    else if type == "TMA"
        ta.sma(ta.sma(src, len), len)
    else
        ta.sma(src, len)

// Security wrapper
reso(exp, use, res) => use ? request.security(syminfo.tickerid, res, exp, lookahead=barmerge.lookahead_on) : exp

// === SERIES SETUP ===
closeSeries = variant(basisType, close[delayOffset], basisLen, offsetSigma, offsetALMA)
openSeries  = variant(basisType, open[delayOffset], basisLen, offsetSigma, offsetALMA)

// Alternate resolution series
closeSeriesAlt = reso(closeSeries, useRes, stratRes)
openSeriesAlt  = reso(openSeries, useRes, stratRes)

// Trend Colors
trendColour = closeSeriesAlt > openSeriesAlt ? color.green : color.red
bcolour     = closeSeries > openSeriesAlt ? color.lime : color.red
barcolor(scolor ? bcolour : na, title="Bar Colours")

closeP = plot(closeSeriesAlt, title="Close Series", color=trendColour, linewidth=2, style=plot.style_line)
openP  = plot(openSeriesAlt, title="Open Series", color=trendColour, linewidth=2, style=plot.style_line)
fill(closeP, openP, color=trendColour)
// === ADX FILTER ===
// ADX Calculation
// Input parameters
adxLength = input.int(14, title="ADX Length", minval=1)
adxfilter = input.int(13, title="ADX filter", minval=1)
// Calculate +DM and -DM (Directional Movement)
plusDM = math.max(high - high[1], 0)
minusDM = math.max(low[1] - low, 0)

// Remove cases where both are positive
plusDM := plusDM > minusDM ? plusDM : 0
minusDM := minusDM > plusDM ? minusDM : 0

// Smooth the directional movement using RMA
smoothedPlusDM = ta.rma(plusDM, adxLength)
smoothedMinusDM = ta.rma(minusDM, adxLength)

// Calculate True Range and smooth it
tr = ta.atr(adxLength)
smoothedTR = ta.rma(tr, adxLength)

// Compute +DI and -DI
plusDI = (smoothedPlusDM / smoothedTR) * 100
minusDI = (smoothedMinusDM / smoothedTR) * 100

// Compute DX (Directional Index)
dx = math.abs(plusDI - minusDI) / (plusDI + minusDI) * 100

// Compute ADX by smoothing DX
adx = ta.rma(dx, adxLength)




// === UPDATED TRADE CONDITIONS ===
xlong     = ta.crossover(closeSeriesAlt, openSeriesAlt) and adx > adxfilter
xshort    = ta.crossunder(closeSeriesAlt, openSeriesAlt) and adx > adxfilter
longCond  = xlong
shortCond = xshort


// === STRATEGY ===
slPoints  = input.float(0, title="Initial Stop Loss Points", minval=0)
tpPoints  = input.float(0, title="Initial Target Profit Points", minval=0)
ebar      = input.int(10000, title="Number of Bars for Back Testing", minval=0)

tdays     = (timenow - time) / 60000.0

tdays     := timeframe.ismonthly ? tdays / 1440.0 / 5.0 / 4.3 / timeframe.multiplier :
             timeframe.isweekly ? tdays / 1440.0 / 5.0 / timeframe.multiplier :
             timeframe.isdaily ? tdays / 1440.0 / timeframe.multiplier :
             tdays / timeframe.multiplier

TP = tpPoints > 0 ? tpPoints : na
SL = slPoints > 0 ? slPoints : na

if (ebar == 0 or tdays <= ebar)
    if longCond and tradeType != "SHORT"
        strategy.entry("long", strategy.long)
    if shortCond and tradeType != "LONG"
        strategy.entry("short", strategy.short)
    if shortCond and tradeType == "LONG"
        strategy.close("long")
    if longCond and tradeType == "SHORT"
        strategy.close("short")
    strategy.exit("XL", from_entry="long", profit=TP, loss=SL)
    strategy.exit("XS", from_entry="short", profit=TP, loss=SL)

// === END ===