더블 크로스 트렌드 팔로잉 전략: 지수 이동 평균 및 MACD 협업 거래 시스템

EMA MACD DIF DEA TP SL RR
생성 날짜: 2025-01-17 16:06:16 마지막으로 수정됨: 2025-01-17 16:06:16
복사: 0 클릭수: 374
avatar of ChaoZhang ChaoZhang
1
집중하다
1617
수행원

더블 크로스 트렌드 팔로잉 전략: 지수 이동 평균 및 MACD 협업 거래 시스템

개요

이 전략은 이동 평균과 MACD 이중 기술 지표를 결합한 추세 추적 거래 시스템입니다. 주로 EMA9 이동평균선과 가격의 교차점, 그리고 MACD 지표의 빠른 선(DIF)과 느린 선(DEA)의 교차점을 통해 시장 동향을 포착합니다. 동시에 이 전략은 과거 5개 K-라인을 기반으로 한 적응형 손절매 방식을 채택하고, 3.5배의 위험-수익 비율을 사용하여 수익 목표를 설정하여 완전한 거래 시스템을 형성합니다.

전략 원칙

전략의 핵심 논리는 긴 방향과 짧은 방향의 두 가지 방향으로 나뉩니다.

  1. 롱 조건: 종가가 EMA9를 바닥에서 꼭대기까지 돌파하고, MACD의 DIF선이 DEA선을 바닥에서 꼭대기까지 교차할 때, 시스템은 롱 신호를 보냅니다.
  2. 공매도 조건: 종가가 위에서 아래로 EMA9 아래로 떨어지고, MACD의 DIF선이 위에서 아래로 DEA선을 교차할 때, 시스템은 공매도 신호를 보냅니다.
  3. 위험 관리:
    • 롱 오더의 손절매는 이전 5K 라인의 최저점 아래에 설정됩니다.
    • 단기 주문에 대한 손절매는 이전 5개 K-라인의 최고점 위에 설정됩니다.
    • 이익 목표는 손절매 거리의 3.5배입니다.

전략적 이점

  1. 이중 확인 메커니즘: 이동평균선과 MACD의 협력을 통해 잘못된 신호를 효과적으로 걸러내고 거래의 정확성을 향상시킬 수 있습니다.
  2. 적응형 손절매: 최근 가격 변동에 따라 설정된 손절매 수준은 시장 변동성에 따라 보호 포지션을 자동으로 조정할 수 있습니다.
  3. 명확한 위험-수익 비율: 3.5배의 고정된 위험-수익 설정은 장기적으로 안정적인 수익을 달성하는 데 도움이 됩니다.
  4. 전략적 논리는 명확합니다. 진입 및 종료 조건이 명확하고, 이해하고 실행하기 쉽습니다.
  5. 강력한 적응성: 매개변수는 다양한 시장 상황에 따라 조정될 수 있습니다.

전략적 위험

  1. 변동성이 큰 시장의 위험: 횡보장이고 변동성이 큰 시장에서는 거짓 돌파가 자주 발생할 수 있으며, 이로 인해 지속적인 손절매가 발생할 수 있습니다.
  2. 미끄러짐 위험: 빠른 시장에서는 실제 손절매 가격과 수익 가격이 예상과 달라질 수 있습니다.
  3. 매개변수 민감도: EMA와 MACD의 기간 설정은 전략 성과에 큰 영향을 미칩니다.
  4. 추세 의존성: 명확한 추세가 없는 시장 환경에서는 전략의 성과가 좋지 않을 수 있습니다.

전략 최적화 방향

  1. 트렌드 필터 추가: 주요 트렌드 방향으로만 더 긴 기간과 미결제 포지션이 있는 트렌드 지표를 도입할 수 있습니다.
  2. 동적 위험 배수: 시장 변동성에 따라 위험-수익 비율을 자동으로 조정합니다.
  3. 시간 필터: 유동성이 낮은 기간을 피하기 위해 거래 기간 필터를 추가합니다.
  4. 위치 관리 최적화: 위치 비율은 신호 강도에 따라 동적으로 조정될 수 있습니다.
  5. 변동성 지표 소개: 손절매 거리를 동적으로 조정하는 데 사용됩니다.

요약하다

이 전략은 기술 지표의 이중 확인과 엄격한 위험 관리를 통해 완전한 추세 추적 거래 시스템을 구축합니다. 시장 환경에 따라 어느 정도 의존성은 있지만, 해당 전략은 합리적인 매개변수 최적화와 위험 관리를 통해 우수한 적응성과 안정성을 보여줍니다. 이후의 최적화 방향은 주로 추세 식별의 정확성과 위험 관리의 역동성에 초점을 맞춰 전략의 전반적인 성과를 개선합니다.

전략 소스 코드
/*backtest
start: 2024-01-17 00:00:00
end: 2025-01-16 00:00:00
period: 2d
basePeriod: 2d
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT","balance":49999}]
*/

// =======================
// @version=6
strategy(title="MACD + EMA9 3 h",
     shorttitle="MACD+EMA9+StopTP_5candles",
     overlay=true,
     initial_capital=100000,    // Ajuste conforme desejar
     default_qty_type=strategy.percent_of_equity,
     default_qty_value=200)      // Ajuste % de risco ou quantidade

// ----- Entradas (Inputs) -----
emaLen          = input.int(9,     "Período da EMA 9", minval=1)
macdFastLen     = input.int(12,    "Período MACD Rápido", minval=1)
macdSlowLen     = input.int(26,    "Período MACD Lento",  minval=1)
macdSignalLen   = input.int(9,     "Período MACD Signal", minval=1)
riskMultiplier  = input.float(3.5, "Fator de Multiplicação do Risco (TP)")
lookbackCandles = input.int(5,     "Quantidade de candles p/ Stop", minval=1)

// ----- Cálculo da EMA -----
ema9 = ta.ema(close, emaLen)

// ----- Cálculo do MACD -----
[macdLine, signalLine, histLine] = ta.macd(close, macdFastLen, macdSlowLen, macdSignalLen)
// DIF cruza DEA para cima ou para baixo
macdCrossover   = ta.crossover(macdLine, signalLine)   // DIF cruza DEA p/ cima
macdCrossunder  = ta.crossunder(macdLine, signalLine)  // DIF cruza DEA p/ baixo

// ----- Condições de Compra/Venda -----

// Compra quando:
// 1) Preço cruza EMA9 de baixo pra cima
// 2) MACD cruza a linha de sinal para cima
buySignal = ta.crossover(close, ema9) and macdCrossover

// Venda quando:
// 1) Preço cruza EMA9 de cima pra baixo
// 2) MACD cruza a linha de sinal para baixo
sellSignal = ta.crossunder(close, ema9) and macdCrossunder

// ----- Execução das ordens -----

// Identifica o menor e o maior preço dos últimos 'lookbackCandles' candles.
// A função ta.lowest() e ta.highest() consideram, por padrão, a barra atual também.
// Se você quiser EXCLUIR a barra atual, use low[1] / high[1] dentro do ta.lowest() / ta.highest().
lowestLow5  = ta.lowest(low, lookbackCandles)
highestHigh5= ta.highest(high, lookbackCandles)

// >>> Quando há sinal de COMPRA <<<
if (buySignal)
    // Fecha posição vendida, se existir
    strategy.close("Sell")
    // Entra comprado
    strategy.entry("Buy", strategy.long)
    
    // STOP: abaixo do menor preço dos últimos 5 candles
    stopPrice = lowestLow5
    // Risco = (preço de entrada) - (stop)
    // Note que strategy.position_avg_price só fica disponível a partir da barra seguinte.
    // Por isso, o exit costuma funcionar corretamente apenas na barra seguinte.
    // Para fins de teste, podemos usar 'close' como proxy do "entry" (ou aceitar essa limitação).
    // A forma "correta" de usar strategy.position_avg_price seria via calc_on_order_fills = true,
    // mas isso pode exigir algumas configurações adicionais.
    risk = strategy.position_avg_price - stopPrice
    
    // Take Profit = entrada + 2,5 * risco
    takeProfitPrice = strategy.position_avg_price + riskMultiplier * risk

    // Registra a saída (stop e alvo) vinculada à posição "Buy"
    strategy.exit("Exit Buy", "Buy", stop=stopPrice, limit=takeProfitPrice)

// >>> Quando há sinal de VENDA <<<
if (sellSignal)
    // Fecha posição comprada, se existir
    strategy.close("Buy")
    // Entra vendido
    strategy.entry("Sell", strategy.short)
    
    // STOP: acima do maior preço dos últimos 5 candles
    stopPrice = highestHigh5
    // Risco = (stop) - (preço de entrada)
    risk = stopPrice - strategy.position_avg_price
    
    // Take Profit = entrada - 2,5 * risco
    takeProfitPrice = strategy.position_avg_price - riskMultiplier * risk

    // Registra a saída (stop e alvo) vinculada à posição "Sell"
    strategy.exit("Exit Sell", "Sell", stop=stopPrice, limit=takeProfitPrice)

// ----- Plotagens visuais -----
plot(ema9, color=color.orange, linewidth=2, title="EMA 9")

plot(macdLine,       color=color.new(color.blue, 0),   title="MACD")
plot(signalLine,     color=color.new(color.red, 0),    title="Signal")
plot(histLine,       color=color.new(color.purple, 0), style=plot.style_histogram, title="Histogram")

// Só para auxiliar na visualização, vamos plotar a linha do lowestLow5 e highestHigh5
plot(lowestLow5,    color=color.new(color.lime, 70),  style=plot.style_line, title="Lowest 5 bars")
plot(highestHigh5,  color=color.new(color.fuchsia,70),style=plot.style_line, title="Highest 5 bars")