MACD 트렌드 균형 전략

저자:차오장, 날짜: 2023-10-17 16:15:53
태그:

img

전반적인 설명

이것은 MACD 지표를 사용하여 상승과 하락 방향을 식별하는 트렌드 다음 전략입니다. 빠른 이동 평균과 느린 이동 평균의 차이를 계산하여 MACD 메인 라인을 생성합니다. 전략은 MACD 메인 라인과 신호 라인의 황금 십자가를 사용하여 구매 신호를 생성하고 죽음의 십자가를 사용하여 판매 신호를 생성하여 트렌드의 균형 잡힌 추적을 달성합니다.

전략 논리

코드는 먼저 전략의 역사적인 성능을 테스트하기 위해 백테스팅 기간을 설정합니다.

MACD 지표는 그 다음 빠른 이동 평균, 느린 이동 평균, 그리고 MACD 이동 평균의 길이 설정을 포함하여 계산된다. 빠른 선은 더 민감하게 반응하고 느린 선은 더 안정적으로 반응한다. 그들의 차이는 MACD 메인 라인을 형성하고, 그 다음 이동 평균에 의해 매끄럽혀 MACD 신호 라인을 형성한다. 차이는 제로 라인을 넘을 때 상승 신호가 생성된다. 아래를 넘을 때 하향 신호가 생성된다.

상승 및 하락 신호를 기반으로 신호가 생성된 마지막 시간을 기록합니다. 빠른 라인과 느린 라인이 교차 할 때 구매 / 판매 신호를 확인하고 기록하면 포지션을 열 수 있습니다.

포지션에 진입 한 후, 지속적으로 포지션의 가장 높은 가격과 가장 낮은 가격을 추적합니다. 손해를 멈추는 비율을 설정하십시오. 손실이 이 비율에 도달하면 손해를 멈추고 종료하십시오.

장점

  1. MACD 지표는 트렌드를 효과적으로 식별 할 수 있으며 고전적인 기술 지표 중 하나입니다.

  2. 빠른 평균과 느린 이동 평균의 차이는 가격 동력과 방향 변화를 조기에 파악할 수 있습니다.

  3. 이동 평균의 필터링 효과는 일부 잘못된 신호를 필터링하는 데 도움이 됩니다.

  4. 이 전략은 위험을 통제하기 위한 스톱 로스 메커니즘을 포함합니다.

위험성

  1. MACD는 제한된 최적화 공간으로 잘못된 신호를 생성하는 경향이 있습니다.

  2. 부적절한 스톱 로스 배치는 너무 적극적이거나 보수적이어서 제품별로 개별적인 최적화를 요구할 수 있습니다.

  3. 고정된 포지션 크기는 쉽게 과잉 레버링으로 이어질 수 있습니다. 계좌 크기에 따라 포지션 크기를 고려하십시오.

  4. 백트테스트 시간 프레임에 대한 논리는 과잉 적응을 방지하기 위해 검증되어야합니다.

최적화

  1. 다른 제품에 가장 적합한 매개 변수를 찾기 위해 빠르고 느린 이동 평균 조합을 최적화하십시오.

  2. 촛불, 볼링거 밴드, RSI와 같은 다른 지표를 추가하여 신호를 필터합니다.

  3. 마감, 샤프 비율을 기반으로 다른 스톱 손실 수준을 평가합니다.

  4. 스톱 로스, 리미트 오더 같은 스톱 로스 기술을 익히세요.

  5. 자금, 변동성을 기반으로 동적 지점 크기를 테스트합니다.

결론

MACD 트렌드 밸런싱 전략은 고전적인 MACD 지표에 기반을 두고 있다. 가격 동력을 민감하게 파악할 수 있고 매개 변수 최적화를 통해 다양한 제품에 잘 적응할 수 있다. 필터링 신호, 스톱 로스 기술 및 동적 포지션 사이징에 대한 추가 개선은 안정성과 수익성을 계속 향상시킬 수 있다.


/*backtest
start: 2023-09-16 00:00:00
end: 2023-10-16 00:00:00
period: 3h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=2
strategy("MACD BF", overlay=true, initial_capital=10000, default_qty_type=strategy.percent_of_equity, default_qty_value=100, commission_type=strategy.commission.percent, commission_value=0.0)

/////////////// Component Code Start ///////////////
testStartYear = input(2017, "Backtest Start Year") 
testStartMonth = input(1, "Backtest Start Month")
testStartDay = input(1, "Backtest Start Day")
testPeriodStart = timestamp(testStartYear,testStartMonth,testStartDay, 0, 0)

testStopYear = input(2019, "Backtest Stop Year")
testStopMonth = input(12, "Backtest Stop Month")
testStopDay = input(31, "Backtest Stop Day")
testPeriodStop = timestamp(testStopYear,testStopMonth,testStopDay, 0, 0)

// A switch to control background coloring of the test period
testPeriodBackground = input(title="Color Background?", type=bool, defval=true)
testPeriodBackgroundColor = testPeriodBackground and (time >= testPeriodStart) and (time <= testPeriodStop) ? #00FF00 : na
bgcolor(testPeriodBackgroundColor, transp=97)

testPeriod() => true

///////////////  MACD Component - Default settings for one day. /////////////// 
fastLength = input(12) // 72 for 4hr
slowlength = input(26) // 156 for 4 hr
MACDLength = input(12)  // 12 for 4hr

MACD = ema(close, fastLength) - ema(close, slowlength)
aMACD = ema(MACD, MACDLength)
delta = MACD - aMACD

long = crossover(delta, 0) 
short = crossunder(delta, 0) 

last_long = long ? time : nz(last_long[1])
last_short = short ? time : nz(last_short[1])

long_signal = crossover(last_long, last_short)
short_signal = crossover(last_short, last_long)

last_open_long_signal = long_signal ? open : nz(last_open_long_signal[1])
last_open_short_signal = short_signal ? open : nz(last_open_short_signal[1])

last_long_signal = long_signal ? time : nz(last_long_signal[1])
last_short_signal = short_signal ? time : nz(last_short_signal[1])

in_long_signal = last_long_signal > last_short_signal
in_short_signal = last_short_signal > last_long_signal

last_high = not in_long_signal ? na : in_long_signal and (na(last_high[1]) or high > nz(last_high[1])) ? high : nz(last_high[1])
last_low = not in_short_signal ? na : in_short_signal and (na(last_low[1]) or low < nz(last_low[1])) ? low : nz(last_low[1])

sl_inp = input(5.0, title='Stop Loss %', type=float)/100

/////////////// Strategy Component /////////////// 
// Strategy Entry
if testPeriod()
    strategy.entry("Long Entry",  strategy.long, when=long_signal)
    strategy.entry("Short Entry", strategy.short, when=short_signal)

since_longEntry = barssince(last_open_long_signal != last_open_long_signal[1]) // LONG SL
since_shortEntry = barssince(last_open_short_signal != last_open_short_signal[1]) // SHORT SL

slLong = in_long_signal ? strategy.position_avg_price * (1 - sl_inp) : na
slShort = strategy.position_avg_price * (1 + sl_inp)
long_sl = in_long_signal ? slLong : na
short_sl = in_short_signal ? slShort : na

// Strategy SL Exit
if testPeriod()
    strategy.exit("Long SL", "Long Entry", stop=long_sl, when=since_longEntry > 1)
    strategy.exit("Short SL", "Short Entry", stop=short_sl, when=since_shortEntry > 1)

//plot(strategy.equity, title="equity", color=blue, linewidth=2, style=areabr)

더 많은