ADX 모멘텀 트렌드 전략

저자:차오장, 날짜: 2024-01-16 15:57:17
태그:

img

전반적인 설명

이 전략은 ADX 지표를 사용하여 시장 트렌드를 결정하고 DMI 지표와 결합하여 방향을 결정하고 ADX 기울기를 사용하여 트렌드 강도를 측정하고 ADX 키 레벨을 설정하여 트렌드가 아닌 시장을 필터하고 이동 평균을 사용하여 거래 신호를 필터합니다.

전략 논리

  1. ADX, DI+, DI- 지표를 계산합니다.
  2. ADX 기울기 > 0은 증가 추세를 나타냅니다. 트렌드가 아닌 시장을 필터링하기 위해 키 레벨은 23로 설정됩니다.
  3. DI+가 DI-보다 높으면 상승세가 하락세를 능가하고 구매 신호를 줍니다.
  4. 이동 평균 필터가 활성화되면, 닫는 것이 이동 평균보다 높을 때만 구매 신호를 생성합니다.
  5. ADX 기울기 < 0이 되면 포지션을 닫습니다.

이점 분석

  1. MA 필터는 트렌드가 아닌 시장에서 잡음을 줄여줍니다.
  2. ADX 기울기는 트렌드 강도를 정확하게 결정합니다.
  3. DI는 ADX와 결합하여 강도를 나타냅니다.
  4. 간단한 MA 전략보다 낮은 마취율과 높은 수익률을 기대할 수 있습니다.

위험 분석

  1. ADX 결과는 각기 다른 입력 매개 변수에 따라 크게 달라집니다.
  2. DMI는 방향이 명확하게 결정되기 전에 잘못된 신호를 줄 수 있습니다.
  3. 어떤 지연이 존재하고 전략의 효율성을 감소시킵니다.

최적화 방향

  1. 가장 좋은 결과를 위해 ADX 매개 변수를 최적화합니다.
  2. 한 번의 거래에서 손해를 제한하는 스톱 손실을 추가합니다.
  3. 신호를 필터링하기 위해 다른 지표를 조합해보세요. 예를 들어 RSI, 볼링거 밴드.

요약

이 전략은 트렌드 및 모멘텀을 결정하는 데 ADX의 힘을 완전히 활용하고 방향 분석을 위한 DMI와 결합하여 완전한 트렌드 추적 시스템을 형성합니다. MA 필터는 효과적으로 소음을 감소시킵니다. 추가 매개 변수 조정 및 지표 조합은 견고성과 효율성을 향상시킬 수 있습니다. 요컨대, 트렌드, 모멘텀 및 방향 분석을 통합함으로써이 전략은 강력한 수익을 얻을 수 있습니다.


/*backtest
start: 2024-01-08 00:00:00
end: 2024-01-15 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')

더 많은