이중 기하급수적 이동 평균 트렌드 전략

저자:차오장, 날짜: 2024-02-02 17:11:29
태그:

img

전반적인 설명

이중 지수적 이동 평균 트렌드 다음 전략 (Dual Exponential Moving Average Trend Following Strategy) 은 지수적 이동 평균 (EMA) 크로스오버를 기반으로하는 트렌드 다음 전략이다. 빠른 EMA 라인과 느린 EMA 라인을 계산하여 현재의 트렌드 방향을 판단하고 그 크로스오버에 작용한다. 빠른 EMA 라인이 느린 EMA 라인의 위를 넘을 때 상승 신호로 결정된다. 빠른 EMA 라인이 느린 EMA 라인의 아래를 넘을 때 하락 신호로 결정된다. 확인된 트렌드 방향에 따라 이 전략은 그에 따라 길게 갈 수도 있고 짧게 갈 수도 있다.

전략 논리

이 전략의 핵심 논리는 서로 다른 기간의 두 개의 EMA 라인을 계산하는 데 있습니다. 하나는 하락선으로 작용하고 하나는 상승선으로 작용합니다. 구체적으로, 전략은 8 기간 빠른 EMA 라인을 계산하여 타리브 지표를 상승선으로 사용합니다. 그리고 21 기간 느린 EMA 라인을 하락선으로 계산합니다. 그런 다음 빠른 EMA 라인과 느린 EMA 라인의 교차 관계를 판단합니다. 빠른 라인이 느린 라인의 위로 넘을 때, 그것은 길게 갈 수있는 상승 신호를 결정합니다. 빠른 라인이 느린 라인의 아래에 넘을 때, 그것은 짧게 갈 수있는 하락 신호를 결정합니다.

실제 거래 실행의 관점에서, 이 전략은 단, 단 또는 두 방향으로 갈 수 있다. 또한, 빠른 라인과 느린 라인 사이의 교차가 발생하면, 스톱 손실 및 취득 가격들이 전략에 구성된다. 포지션을 열고 나면, 가격이 불리한 방향으로 갈 경우, 스톱 손실은 출구 포지션으로 트리거될 것이다. 가격이 예상 목표 수준에 도달하면, 취득이 실현되고 포지션을 닫을 것이다.

이점 분석

이중 EMA 트렌드 추적 전략의 가장 큰 장점은 이동 평균 크로스오버의 강력한 트렌드 식별 능력에 있다. 트렌드 분석의 일반적인 도구로서, EMA 라인은 크로스오버를 통해 트렌드 변화와 전환점을 식별할 수 있으며, 단기 시장 소음으로 오해되는 것을 피하고 주요 트렌드 방향을 파악할 수 있다.

또한, 거래 방향에 대한 유연한 설정은 전략이 일방적 추세와 양방향 변동에 모두 적응 할 수 있도록하고, 따라서 전략의 적용성을 향상시킵니다. 구성된 스톱 로스 및 수익은 위험을 제어하고 부분 수익을 잠금합니다.

위험 분석

이 전략의 가장 큰 위험은 범위 제한 시장에서 빈번한 작은 크로스오버로 인해 발생하는 잘못된 신호입니다. 이것은 과도한 포지션 오픈과 손실로 이어질 것입니다. 이를 해결하기 위해 EMA 기간을 늘려 크로스오버 시간과 잘못된 신호 가능성을 줄일 수 있습니다.

반면에 너무 긴 스톱 로스 설정은 스톱 아웃 될 가능성을 증가시킵니다. 이 경우 스톱 로스 범위를 확장해야 합니다.

최적화 방향

이 전략은 다음과 같은 측면에서 더 이상 최적화 될 수 있습니다.

  1. 시장 변동성과 백테스트 결과를 기반으로 EMA 기간에 대한 적응 조정, 고정 기간에 과도한 적응을 피합니다.

  2. 잘못된 신호를 필터링하기 위해 필터 조건을 추가합니다. 예를 들어, 중요하지 않은 크로스오버를 필터링하기 위해 거래량과 결합하십시오. 또는 불확실성 신호를 피하기 위해 MACD 및 KDJ와 같은 다른 지표를 결합하십시오.

  3. 스톱 로스 및 영업 전략 최적화, 예를 들어, SL/TP에서 동적 트레일링을 실현하기 위해 ATR을 결합하여 과도한 SL 및 조기 TP를 방지합니다.

  4. 다양한 보유 기간을 테스트합니다. 너무 긴 보유 기간은 사건에 의해 영향을받을 수 있으며, 너무 짧은 기간은 높은 거래 비용과 미끄러짐 비용을 초래합니다. 최적의 보유 날을 찾는 것은 전략 수익성을 향상시킬 수 있습니다.

요약

일반적으로 이중 EMA 트렌드 추적 전략은 견고하고 실용적인 트렌드 거래 시스템입니다. EMA 크로스오버 시스템을 통해 트렌드 방향을 효과적으로 잡습니다. 한편, 거래 방향에 대한 유연한 설정은 적응력을 높이고, 설정된 스톱 로스 및 수익 통제 위험도 있습니다. 추가 최적화 및 향상으로이 전략은 양적 거래에 강력한 도구가 될 수 있습니다.


/*backtest
start: 2024-01-02 00:00:00
end: 2024-02-01 00:00:00
period: 2h
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/
// © TradersPostInc

//@version=5
strategy('TradersPost Example MOMO Strategy', overlay=true, default_qty_value=100, initial_capital=100000, default_qty_type=strategy.percent_of_equity, pyramiding=0)

startTime = input(defval = timestamp('01 Jan 2021 00:00 +0000'), title = 'Start Time', group = 'Date Range')
endTime = input(defval = timestamp('31 Dec 2023 23:59 +0000'), title = 'End Time', group = 'Date Range')
timeCondition = true
timeConditionEnd = timeCondition[1] and not timeCondition

fastEmaLength = input.int(defval = 8, title = 'Fast EMA Length')
slowEmaLength = input.int(defval = 21, title = 'Slow EMA Length')
sides = input.string(defval = 'Both', title = 'Sides', options = ['Long', 'Short', 'Both', 'None'])

fastEma = ta.ema(close, fastEmaLength)
slowEma = ta.ema(close, slowEmaLength)

isUptrend = fastEma >= slowEma
isDowntrend = fastEma <= slowEma
trendChanging = ta.cross(fastEma, slowEma)

ema105 = request.security(syminfo.tickerid, '30', ta.ema(close, 105)[1], barmerge.gaps_off, barmerge.lookahead_on)
ema205 = request.security(syminfo.tickerid, '30', ta.ema(close, 20)[1], barmerge.gaps_off, barmerge.lookahead_on)
plot(ema105, linewidth=4, color=color.new(color.purple, 0), editable=true)
plot(ema205, linewidth=2, color=color.new(color.purple, 0), editable=true)

aa = plot(fastEma, linewidth=3, color=color.new(color.green, 0), editable=true)
bb = plot(slowEma, linewidth=3, color=color.new(color.red, 0), editable=true)
fill(aa, bb, color=isUptrend ? color.green : color.red, transp=90)

tradersPostBuy = trendChanging and isUptrend and timeCondition
tradersPostSell = trendChanging and isDowntrend and timeCondition

pips = syminfo.pointvalue / syminfo.mintick

percentOrPipsInput = input.string('Percent', title='Percent or Pips', options=['Percent', 'Pips'])

stopLossLongInput = input.float(defval=0, step=0.01, title='Stop Loss Long', minval=0)
stopLossShortInput = input.float(defval=0, step=0.01, title='Stop Loss Short', minval=0)

takeProfitLongInput = input.float(defval=0, step=0.01, title='Target Profit Long', minval=0)
takeProfitShortInput = input.float(defval=0, step=0.01, title='Target Profit Short', minval=0)

stopLossPriceLong = ta.valuewhen(tradersPostBuy, close, 0) * (stopLossLongInput / 100) * pips
stopLossPriceShort = ta.valuewhen(tradersPostSell, close, 0) * (stopLossShortInput / 100) * pips

takeProfitPriceLong = ta.valuewhen(tradersPostBuy, close, 0) * (takeProfitLongInput / 100) * pips
takeProfitPriceShort = ta.valuewhen(tradersPostSell, close, 0) * (takeProfitShortInput / 100) * pips

takeProfitALong = takeProfitLongInput > 0 ? takeProfitLongInput : na
takeProfitBLong = takeProfitPriceLong > 0 ? takeProfitPriceLong : na

takeProfitAShort = takeProfitShortInput > 0 ? takeProfitShortInput : na
takeProfitBShort = takeProfitPriceShort > 0 ? takeProfitPriceShort : na

stopLossALong = stopLossLongInput > 0 ? stopLossLongInput : na
stopLossBLong = stopLossPriceLong > 0 ? stopLossPriceLong : na

stopLossAShort = stopLossShortInput > 0 ? stopLossShortInput : na
stopLossBShort = stopLossPriceShort > 0 ? stopLossPriceShort : na

takeProfitLong = percentOrPipsInput == 'Pips' ? takeProfitALong : takeProfitBLong
stopLossLong = percentOrPipsInput == 'Pips' ? stopLossALong : stopLossBLong
takeProfitShort = percentOrPipsInput == 'Pips' ? takeProfitAShort : takeProfitBShort
stopLossShort = percentOrPipsInput == 'Pips' ? stopLossAShort : stopLossBShort

buyAlertMessage = '{"ticker": "' + syminfo.ticker + '", "action": "buy", "price": ' + str.tostring(close) + '}'
sellAlertMessage = '{"ticker": "' + syminfo.ticker + '", "action": "sell", "price": ' + str.tostring(close) + '}'

exitLongAlertMessage = '{"ticker": "' + syminfo.ticker + '", "action": "exit", "price": ' + str.tostring(close) + '}'
exitShortAlertMessage = '{"ticker": "' + syminfo.ticker + '", "action": "exit", "price": ' + str.tostring(close) + '}'

if (sides != "None")
    if tradersPostBuy
        strategy.entry('Long', strategy.long, when = sides != 'Short', alert_message = buyAlertMessage)
        strategy.close('Short', when = sides == "Short" and timeCondition, alert_message = exitShortAlertMessage)

    if tradersPostSell
        strategy.entry('Short', strategy.short, when = sides != 'Long', alert_message = sellAlertMessage)
        strategy.close('Long', when = sides == 'Long', alert_message = exitLongAlertMessage)

exitAlertMessage = '{"ticker": "' + syminfo.ticker + '", "action": "exit"}'

strategy.exit('Exit Long', from_entry = "Long", profit = takeProfitLong, loss = stopLossLong, alert_message = exitAlertMessage)
strategy.exit('Exit Short', from_entry = "Short", profit = takeProfitShort, loss = stopLossShort, alert_message = exitAlertMessage)

strategy.close_all(when = timeConditionEnd)

더 많은