이 전략은 이동 평균 컨버전스 디버전스 (MACD) 인디케이터를 사용하여 긴 신호와 짧은 신호를 생성하고 수익을 얻기 위해 동적으로 출구점을 설정하여 좋은 트렌드 조건에서 역전 거래를합니다.
이 전략의 핵심은 긴 신호에 대한 MACD 황금 십자가와 짧은 신호에 대한 죽음의 십자가를 기반으로합니다. 구체적으로, MACD 라인이 아래에서 신호 라인의 위에 넘어가면, 황금 십자가가 긴 신호로 생성됩니다. MACD 라인이 위에서 신호 라인의 아래에 넘어가면, 죽음의 십자가가 짧은 신호로 생성됩니다.
골든 크로스 신호에서, 닫기 가격이 EMA보다 높으면 장거리; 죽음의 크로스 신호에서, 닫기 가격이 EMA보다 낮으면 단축합니다. 이것은 상승 추세에 따라 반전 거래를 보장합니다.
포지션을 입력한 후, 전략은 출구를 동적으로 제어하기 위해 스톱 로스를 사용하고 수익을 취합니다. 구체적으로, 긴 포지션의 스톱 로스는 엔트리 가격 * (1 - 최대 드래운) 에 설정됩니다. 수익을 취하는 것은 엔트리 가격 * (1 + TARGET_STOP_RATIO * 최대 드래운) 에 설정됩니다. 짧은 포지션의 경우 반대로. 여기서 최대 드래운은 스윙 로우에서 클로즈까지의 가격 하락의 비율로 동적으로 계산됩니다. TARGET_STOP_RATIO는 기본으로 2로 설정되어 있으며, 이는 위험/이익 비율이 2입니다.
이 동적 스톱 전략의 장점은 시장 변동성에 따라 스톱 손실과 위험 / 보상 비율을 조정 할 수 있다는 것입니다. 높은 변동성 동안 긴 스톱 손실로 빠르게 종료하고 낮은 변동성 환경에서 느린 스톱으로 이익을 추적합니다.
MACD는 반전 기회를 식별하는 효과적인 지표입니다.
EMA 필터는 상승 추세 시장에서만 긴 거래가 이루어지는 것을 보장합니다.
동적 출구 제어 시스템은 수익을 극대화하고 동시에 위험을 효과적으로 관리합니다.
빠른 현존 속도는 필요한 모니터링 시간을 줄여서 바쁜 투자자에게 적합합니다.
MACD는 옆 시장에서 자주 변동하여 가짜 신호를 생성합니다. 이는 역동 트렌드 거래를 피하기 위해 EMA 필터를 추가하여 해결됩니다.
극심한 변동성은 DYNAMIC STOP가 너무 느슨하게 될 수 있습니다. 극심한 시장 움직임에 직면했을 때 고정된 위험/이익 비율을 고려하십시오.
한 거래 당 제한된 이익 마진은 빈번한 거래를 요구합니다. 투자자는 특정 심리적 인내력과 시간 헌신이 필요합니다. 너무 바쁘면 더 높은 시간 프레임으로 전환 할 수 있습니다.
신호 품질을 최적화하기 위해 기호 특성에 기반한 MACD 매개 변수를 정렬합니다.
다양한 이동 평균을 트렌드 필터로 테스트하여 최적의 것을 찾습니다.
출구 전략을 최적화하기 위해 TARGET_STOP_RATIO 계산과 최대 유출 정의를 테스트합니다.
신호 품질을 향상시키기 위해 부피, 변동성 등과 같은 다른 요소를 추가하십시오.
더 많은 기능을 추출하고 더 똑똑한 출구를 위해 적응 가능한 다중 요소 모델을 구축하기 위해 기계 학습 모델을 탐색합니다.
이 전략은 전반적으로 강력한 실용적 가치를 가지고 있다. 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))