
이중 EMA 동선 추적 전략 (Dual Exponential Moving Average Trend Following Strategy) 은 동선 교차를 기반으로 한 트렌드 추적 전략이다. 이 전략은 빠른 EMA와 느린 EMA를 계산하고, 그들의 교차상황에 따라 현재 트렌드 방향을 판단한다. 빠른 선에서 느린 선을 통과했을 때, 낙점으로 판단하고, 빠른 선에서 느린 선을 통과했을 때, 낙점으로 판단한다. 판단된 트렌드 방향에 따라 이 전략은 낙점 또는 낙점 작업을 할 수 있다.
이 전략의 핵심 논리는 두 개의 다른 주기의 EMA 평균선을 계산하는 데 있습니다. 하나는 공백선으로, 하나는 다중선으로. 구체적으로, 전략은 talib 지표를 통해 8 주기의 빠른 EMA 평균선을 계산합니다.
구체적인 거래 동작을 실행할 때, 이 전략은 더 많은 것을 할 수 있고, 공백을 할 수 있습니다. 또한 빠른 느린 라인이 교차하는 경우, 동시에 양방향 거래를 할 수 있습니다. 또한, 전략은 중지 손실과 중지 가격을 설정합니다. 입장을 열고 나서, 가격 운행 방향이 좋지 않으면 손실이 중단되며, 가격 운행이 예상 목표에 도달하면 중지 종료됩니다.
이중 EMA 평행선 추적 전략의 가장 큰 장점은 평행선 교차의 강력한 추세 판단 능력을 사용하는 것입니다. EMA 평행선은 평행선 교차를 통해 가격 변화의 추세와 전환 시기를 식별하는 일반적인 추세 판단 도구로 사용되며, 단선 시장 소음으로 혼란스럽지 않고 주요 추세 방향을 파악 할 수 있습니다.
또한, 전략의 유연한 거래 방향 설정은 일방적인 시세에 적응할 수 있고, 가격의 흔들림 영역에서의 쌍방향 기회를 잡을 수 있어 전략의 실용성을 증가시킨다. 동시에 스톱 로스 스톱을 설정하여 위험을 효과적으로 제어하고, 수익의 일부를 잠금할 수 있다.
이중 EMA 평행선 추적 전략의 가장 큰 위험은, 충격적인 상황에서의 여러 번의 작은 크기의 교차가 교차 신호의 빈번한 트리거와 가짜 신호를 초래한다는 것이다. 이것은 전략의 빈번한 포지션 개설과 손실을 초래할 것이다. 이 경우, EMA 주기를 적절히 확대하여 교차의 빈도와 가짜 신호의 발생 가능성을 줄일 수 있다.
다른 한편으로, 너무 작은 스톱 레인지 설정은 전략이 타격될 확률을 증가시킨다. 이 경우 스톱 레인지를 적절히 확장할 수 있지만, 또한 헤비트레이드되는 위험을 가중할 필요가 있다.
이 전략은 다음의 몇 가지 측면에서 더 개선될 수 있습니다.
동적으로 조정 EMA 평균선 주기를. 시장의 변동률과 최적의 변수 재검토 결과에 따라 EMA 주기의 동적으로 변경할 수 있으며 고정 주기의 과잉 적합 문제를 피할 수 있습니다.
필터링 조건을 추가하여 가짜 신호를 필터링한다. 예를 들어 거래량과 결합하여 소규모의 흔들림으로 발생하는 가짜 교차를 필터링한다. 또한 MACD, KDJ 등과 같은 다른 지표와 결합하여 불확실한 시간에 신호를 발생하지 않도록 할 수 있다.
손해 중지 중지 전략을 최적화하여 ATR과 같은 지표와 결합하여 손해 중지 중지의 동적 추적을 구현할 수 있습니다. 너무 작은 손해 중지 및 너무 이른 중지 문제를 피하십시오.
다양한 포지션 보유 시간을 테스트한다. 포지션 보유 기간이 너무 길어서 갑작스러운 사건에 영향을 받기 쉽다. 포지션 보유 기간이 너무 짧으면 거래 비용과 슬라이드 포인트 비용이 더 높다. 포지션 보유 일 수를 최적화하여 전략의 수익성을 높일 수 있다.
쌍 EMA 평행 추적 전략은 전체적으로 견고하고 실용적인 트렌드 추적 전략이다. 그것은 EMA 평행 교차 판단 가격 트렌드를 사용하여 시세 방향을 효과적으로 파악할 수 있다. 동시에 Settings의 유연한 거래 방향 설정은 전략의 적응력을 향상시킵니다. 그리고 Stop Loss Stop Loss 설정은 위험을 제어합니다. 추가로 최적화하고 개선하면 이 전략은 거래량을 측정하는 강력한 도구가 될 수 있습니다.
/*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)