리소스 로딩... 로딩...

ATR 변동성 필터와 함께 DEMA와 EMA 크로스오버에 기반한 모멘텀 전략

저자:차오장, 날짜: 2024-01-08 14:14:57
태그:

img

I. 전략 개요

이 전략은 ATR 변동성 필터와 함께 DEMA와 EMA 크로스오버에 기반한 모멘텀 전략 (Momentum Strategy Based on DEMA and EMA Crossover with ATR Volatility Filter) 이라고 불린다. 이 전략은 ATR 변동성 지수와 결합한 DEMA와 EMA 크로스오버를 감지하여 단기 거래 신호를 생성한다. DEMA가 EMA 아래로 넘어가고 ATR가 상승할 때, 보안을 단축한다. DEMA가 EMA 위에 다시 넘어가면, 포지션을 닫는다.

II. 전략 논리

  1. DEMA 지표를 계산합니다. DEMA는 단기 시장 소음을 필터링하고 신호 정확도를 향상시킬 수있는 이중 EMA를 사용하여 이중 기하급수적인 이동 평균입니다.

  2. EMA 지표를 계산하세요. EMA는 가격 변화에 더 빠르게 반응하는 기하급수적인 이동 평균입니다.

  3. ATR 변동성 지수를 계산합니다. ATR은 시장 변동성과 위험 수준을 측정합니다. ATR의 상승은 변동성이 증가하고 단기 인하의 확률이 높습니다.

  4. DEMA가 EMA를 넘고 ATR가 임계치를 넘으면 단기 하락 추세가 시작되고 시장 위험이 증가합니다. 전략은 보안을 단축합니다.

  5. DEMA가 EMA를 다시 넘으면 가격 지원과 상승을 나타냅니다. 전략은 짧은 지위를 닫습니다.

III. 장점

  1. 이중 EMA와 EMA의 조합은 신호 정확성을 효과적으로 향상시킬 수 있습니다.

  2. ATR 변동성 필터는 저위험의 윙사 거래를 제거합니다.

  3. 단기 보유 기간은 단기 추진력 추적에 적합하며 장기적인 헤지핑을 피합니다.

  4. 단순하고 명확한 논리, 이해하기 쉽고 실행하기 쉽습니다.

IV. 위험

  1. 부적절한 ATR 매개 변수는 거래 기회를 놓칠 수 있습니다.

  2. 긴 신호와 짧은 신호를 동시에 감시해야 합니다.

  3. 단기 시장 변동에 영향을 받습니다.

솔루션: 백테스팅을 통해 매개 변수 최적화. 한 쪽에 집중하기 위해 논리를 단순화. 적절하게 중지 손실 수준을 느리게.

V. 최적화 방향

  1. 가장 좋은 조합을 찾기 위해 DEMA와 EMA의 매개 변수를 최적화합니다.

  2. 최적의 변동성 벤치마크를 결정하기 위해 ATR 뷰백 기간을 최적화합니다.

  3. 신호의 정확성을 높이기 위해 BOLL 대역과 같은 다른 지표를 추가합니다.

  4. 더 일관된 수익을 확보하기 위해 스톱 로스 및 수익 규칙을 도입합니다.

VI 결론

이 전략은 DEMA, EMA 크로스오버 및 ATR 변동성 지수를 사용하여 간단하면서도 효과적인 단기 거래 시스템을 구축합니다. 깨끗한 논리 및 작동 용이성은 고주파 운동 거래에 적합합니다. 추가 매개 변수 및 논리 최적화는 잠재적으로 더 안정적인 오버 퍼포먼스를 얻을 수 있습니다.


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

// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © Qorbanjf

//@version=4
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © Qorbanjf

//@version=4
strategy("Qorban: DEMA/EMA & VOL Short ONLY", shorttitle="DEMA/EMA & VOL SHORT", overlay=true)

// DEMA
length = input(10, minval=1, title="DEMA LENGTH")
src = input(close, title="Source")
e1 = ema(src, length)
e2 = ema(e1, length)
dema1 = 2 * e1 - e2
plot(dema1, "DEMA", color=color.yellow)

//EMA
len = input(25, minval=1, title="EMA Length")
srb = input(close, title="Source")
offset = input(title="Offset", type=input.integer, defval=0, minval=-500, maxval=500)
ema1 = ema(srb, len)
plot(ema1, title="EMA", color=color.blue, offset=offset)

// get ATR VALUE
atr = atr(14)

//ATRP (Average True Price in precentage)

// Inputs
atrTimeFrame = input("D", title="ATR Timeframe", type=input.resolution)
atrLookback = input(defval=14,title="ATR Lookback Period",type=input.integer)
useMA = input(title = "Show Moving Average?", type = input.bool, defval = true)
maType = input(defval="EMA", options=["EMA", "SMA"], title = "Moving Average Type")
maLength = input(defval = 20, title = "Moving Average Period", minval = 1)
slType = input(title="Stop Loss ATR / %", type=input.float, defval=5.0, step=0.1)
slMulti = input(title="SL Multiplier", type=input.float, defval=1.0, step=0.1)
minimumProfitPercent = input(title="Minimum profit %", type=input.float, defval=20.00)

// ATR Logic
// atrValue = atr(atrLookback)
// atrp = (atrValue/close)*100
// plot(atrp, color=color.white, linewidth=2, transp = 30)

atrValue = security(syminfo.tickerid, atrTimeFrame, atr(atrLookback))
atrp = (atrValue/close)*100

// Moving Average Logic
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 = security(syminfo.tickerid, atrTimeFrame, ma(maType, atrp, maLength))


// Determine percentage of open profit
var entry = 0.0
distanceProfit = low - entry
distanceProfitPercent = distanceProfit / entry

//Determin if we have a long entry signal OR a sell position signal
profitSignal = minimumProfitPercent == 0.0 or distanceProfitPercent >= minimumProfitPercent
shortSignal = crossunder(dema1, ema1) and atrp > maFilter and strategy.position_size == 0 and not na(atr)
exitSignal = profitSignal and strategy.position_size !=0 and  crossover(dema1, ema1)


// === INPUT BACKTEST RANGE ===
//FromMonth = input(defval = 1, title = "From Month", minval = 1, maxval = 12)
//FromDay   = input(defval = 1, title = "From Day", minval = 1, maxval = 31)
//FromYear  = input(defval = 2017, title = "From Year", minval = 2000)
//ToMonth   = input(defval = 1, title = "To Month", minval = 1, maxval = 12)
//ToDay     = input(defval = 1, title = "To Day", minval = 1, maxval = 31)
//ToYear    = input(defval = 9999, title = "To Year", minval = 2017)

//Invert trade direction & flipping 
//tradInvert = input(defval = false, title = "invert trade direction")
//MOM_MR = input(defval=1, title = "MOM = 1 / MR = -1", minval=-1, maxval=1)
//plots=input(false, title="Show plots?")

// Get stop loss (in pips AND percentage distance)
shortStop = highest(high, 4) - (atr * slMulti)
shortStopPercent = close - (close * slMulti)

// Save long stop & target prices (used for drawing data to the chart & deetermining profit)
var shortStopSaved = 0.0
var shortTargetSaved = 0.0
enterShort = false
if shortSignal
    shortStopSaved := slType ? shortStop : shortStopPercent
    enterShort:= true
    entry := close


// long conditions 
//enterLong = crossover(dema1, ema1) and atrp < maFilter
//exitSignal => crossunder(dema1, ema1)

//Enter trades when conditions are met
strategy.entry("short", strategy.short, when=enterShort, comment="SHORT")

//place exit orders (only executed after trades are active)
strategy.exit(id="Short exit",
 from_entry="short",
 limit=exitSignal ? close : na,
 stop=shortStopSaved,
 when=strategy.position_size > 0,
 comment="end short")
 

//short strategy
//goShort() => crossunder(dema1, ema1) and atrp > maFilter
//KillShort() => crossover(dema1, ema1) 
//strategy.entry("SHORT", strategy.short, when = goShort())
//strategy.close("COVER", when = KillShort())


더 많은