MACD 전략 - 쌍방향 출구 거래

저자:차오장, 날짜: 2023-12-12 12:44:50
태그:

img

전반적인 설명

이 전략은 이동 평균 컨버전스 디버전스 (MACD) 인디케이터를 사용하여 긴 신호와 짧은 신호를 생성하고 수익을 얻기 위해 동적으로 출구점을 설정하여 좋은 트렌드 조건에서 역전 거래를합니다.

전략 원칙

이 전략의 핵심은 긴 신호에 대한 MACD 황금 십자가와 짧은 신호에 대한 죽음의 십자가를 기반으로합니다. 구체적으로, MACD 라인이 아래에서 신호 라인의 위에 넘어가면, 황금 십자가가 긴 신호로 생성됩니다. MACD 라인이 위에서 신호 라인의 아래에 넘어가면, 죽음의 십자가가 짧은 신호로 생성됩니다.

골든 크로스 신호에서, 닫기 가격이 EMA보다 높으면 장거리; 죽음의 크로스 신호에서, 닫기 가격이 EMA보다 낮으면 단축합니다. 이것은 상승 추세에 따라 반전 거래를 보장합니다.

포지션을 입력한 후, 전략은 출구를 동적으로 제어하기 위해 스톱 로스를 사용하고 수익을 취합니다. 구체적으로, 긴 포지션의 스톱 로스는 엔트리 가격 * (1 - 최대 드래운) 에 설정됩니다. 수익을 취하는 것은 엔트리 가격 * (1 + TARGET_STOP_RATIO * 최대 드래운) 에 설정됩니다. 짧은 포지션의 경우 반대로. 여기서 최대 드래운은 스윙 로우에서 클로즈까지의 가격 하락의 비율로 동적으로 계산됩니다. TARGET_STOP_RATIO는 기본으로 2로 설정되어 있으며, 이는 위험/이익 비율이 2입니다.

이 동적 스톱 전략의 장점은 시장 변동성에 따라 스톱 손실과 위험 / 보상 비율을 조정 할 수 있다는 것입니다. 높은 변동성 동안 긴 스톱 손실로 빠르게 종료하고 낮은 변동성 환경에서 느린 스톱으로 이익을 추적합니다.

장점

  1. MACD는 반전 기회를 식별하는 효과적인 지표입니다.

  2. EMA 필터는 상승 추세 시장에서만 긴 거래가 이루어지는 것을 보장합니다.

  3. 동적 출구 제어 시스템은 수익을 극대화하고 동시에 위험을 효과적으로 관리합니다.

  4. 빠른 현존 속도는 필요한 모니터링 시간을 줄여서 바쁜 투자자에게 적합합니다.

위험 과 해결책

  1. MACD는 옆 시장에서 자주 변동하여 가짜 신호를 생성합니다. 이는 역동 트렌드 거래를 피하기 위해 EMA 필터를 추가하여 해결됩니다.

  2. 극심한 변동성은 DYNAMIC STOP가 너무 느슨하게 될 수 있습니다. 극심한 시장 움직임에 직면했을 때 고정된 위험/이익 비율을 고려하십시오.

  3. 한 거래 당 제한된 이익 마진은 빈번한 거래를 요구합니다. 투자자는 특정 심리적 인내력과 시간 헌신이 필요합니다. 너무 바쁘면 더 높은 시간 프레임으로 전환 할 수 있습니다.

최적화 방향

  1. 신호 품질을 최적화하기 위해 기호 특성에 기반한 MACD 매개 변수를 정렬합니다.

  2. 다양한 이동 평균을 트렌드 필터로 테스트하여 최적의 것을 찾습니다.

  3. 출구 전략을 최적화하기 위해 TARGET_STOP_RATIO 계산과 최대 유출 정의를 테스트합니다.

  4. 신호 품질을 향상시키기 위해 부피, 변동성 등과 같은 다른 요소를 추가하십시오.

  5. 더 많은 기능을 추출하고 더 똑똑한 출구를 위해 적응 가능한 다중 요소 모델을 구축하기 위해 기계 학습 모델을 탐색합니다.

결론

이 전략은 전반적으로 강력한 실용적 가치를 가지고 있다. MACD를 핵심 거래 신호로 사용하면 트렌드 필터와 동적 출구 제어의 부가 모듈이 MACD 성능을 크게 향상시킬 수 있다. 출구 제어는 전략 최적화에 필수적이며 이 전략은 이 분야에서 크게 혁신한다. 추가 연구와 응용에 가치가 있다.


/*backtest
start: 2022-12-05 00:00:00
end: 2023-12-11 00:00:00
period: 1d
basePeriod: 1h
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/
// © maxencetajet

//@version=5
strategy("MACD Strategy", overlay=true, initial_capital=1000, slippage=25)

src = input(title="Source", defval=close)
target_stop_ratio = input.float(title='Risk/Reward', defval=2, minval=0.5, maxval=100)
risk = input.float(2, title="Risk per Trade %")

riskt = risk / 100 + 1

useDateFilter = input.bool(true, title="Filter Date Range of Backtest",
     group="Backtest Time Period")
backtestStartDate = input(timestamp("5 June 2022"), 
     title="Start Date", group="Backtest Time Period",
     tooltip="This start date is in the time zone of the exchange " + 
     "where the chart's instrument trades. It doesn't use the time " + 
     "zone of the chart or of your computer.")
backtestEndDate = input(timestamp("5 July 2022"),
     title="End Date", group="Backtest Time Period",
     tooltip="This end date is in the time zone of the exchange " + 
     "where the chart's instrument trades. It doesn't use the time " + 
     "zone of the chart or of your computer.")

inTradeWindow =  true
emaV = input.int(200, title="Length", group="EMA")
swingHighV = input.int(7, title="Swing High", group="number of past candles")
swingLowV = input.int(7, title="Swing Low", group="number of past candles")

ema = ta.ema(src, emaV)

fast_length = input(title="Fast Length", defval=12, group="MACD")
slow_length = input(title="Slow Length", defval=26, group="MACD")
signal_length = input.int(title="Signal Smoothing",  minval = 1, maxval = 50, defval = 9, group="MACD")
sma_source = input.string(title="Oscillator MA Type",  defval="EMA", options=["SMA", "EMA"], group="MACD")
sma_signal = input.string(title="Signal Line MA Type", defval="EMA", options=["SMA", "EMA"], group="MACD")

fast_ma = sma_source == "SMA" ? ta.sma(src, fast_length) : ta.ema(src, fast_length)
slow_ma = sma_source == "SMA" ? ta.sma(src, slow_length) : ta.ema(src, slow_length)
macd = fast_ma - slow_ma
signal = sma_signal == "SMA" ? ta.sma(macd, signal_length) : ta.ema(macd, signal_length)
hist = macd - signal

longcondition = close > ema and ta.crossover(macd, signal) and macd < 0
shortcondition = close < ema and ta.crossunder(macd, signal) and macd > 0

float risk_long = na
float risk_short = na
float stopLoss = na
float takeProfit = na
float entry_price = na

risk_long := risk_long[1]
risk_short := risk_short[1]

swingHigh = ta.highest(high, swingHighV)
swingLow = ta.lowest(low, swingLowV)

lotB = (strategy.equity*riskt-strategy.equity)/(close - swingLow)
lotS = (strategy.equity*riskt-strategy.equity)/(swingHigh - close)

if strategy.position_size == 0 and longcondition and inTradeWindow
    risk_long := (close - swingLow) / close
    strategy.entry("long", strategy.long, qty=lotB)
    
if strategy.position_size == 0 and shortcondition and inTradeWindow
    risk_short := (swingHigh - close) / close  
    strategy.entry("short", strategy.short, qty=lotS)

if strategy.position_size > 0

    stopLoss := strategy.position_avg_price * (1 - risk_long)
    takeProfit := strategy.position_avg_price * (1 + target_stop_ratio * risk_long)
    entry_price := strategy.position_avg_price
    strategy.exit("long exit", "long", stop = stopLoss, limit = takeProfit)
    
if strategy.position_size < 0

    stopLoss := strategy.position_avg_price * (1 + risk_short)
    takeProfit := strategy.position_avg_price * (1 - target_stop_ratio * risk_short)
    entry_price := strategy.position_avg_price
    strategy.exit("short exit", "short", stop = stopLoss, limit = takeProfit)
    
plot(ema, color=color.white, linewidth=2, title="EMA")
p_ep = plot(entry_price, color=color.new(color.white, 0), linewidth=2, style=plot.style_linebr, title='entry price')
p_sl = plot(stopLoss, color=color.new(color.red, 0), linewidth=2, style=plot.style_linebr, title='stopLoss')
p_tp = plot(takeProfit, color=color.new(color.green, 0), linewidth=2, style=plot.style_linebr, title='takeProfit')
fill(p_sl, p_ep, color.new(color.red, transp=85))
fill(p_tp, p_ep, color.new(color.green, transp=85))



더 많은