이 전략은 거래 신호를 구성하기 위해 MACD 지표와 이동 평균 교차 원리를 사용합니다. 이 전략의 장점은 MACD의 매개 변수를 길고 짧은 방향에 별도로 최적화 할 수 있으므로 매개 변수는 다른 시장 방향에 최적화 될 수 있습니다.
긴 방향과 짧은 방향에 대해 MACD 지표를 별도로 계산합니다. 한 세트의 매개 변수는 긴 방향으로 사용되며 다른 세트의 매개 변수는 짧은 방향으로 사용되며 자유롭게 구성 할 수 있습니다.
MACD 라인과 신호 라인의 크로스오버에 의해 생성된 거래 신호를 판단합니다. 길이를위한 상승 크로스오버와 짧은 하락 크로스오버를 찾으십시오.
신호를 발사하기 위해 신호 라인이 교차해야 하는지를 설정할 수 있습니다.
긴 위치 또는 짧은 위치로 들어가면 역차가 발생하면 위치를 닫습니다.
쌍방향 매개 변수 최적화: 장기 및 단기 매개 변수를 자유롭게 최적화하여 시장 방향에 대해 개별적으로 최적화 할 수 있습니다.
구성 가능한 신호 평형: 신호 매개 변수는 잘못된 신호를 필터링하기 위해 신호 라인의 평형을 제어 할 수 있습니다.
구성 가능한 신호 필터링: 잘못된 신호를 피하기 위해 신호 라인 크로스오버가 작동해야하는지 여부를 구성할 수 있습니다.
세밀하게 조정된 위치 제어: 길거나 짧은 단위만 개별적으로 활성화 할 수 있습니다. 또는 길고 짧은 단위도 동시에 수행 할 수 있습니다.
MACD 지연: MACD 자체는 빠른 반전을 놓칠 수 있는 약간의 지연을 가지고 있습니다.
장기 및 단위 사이로 전환하는 위험: 시장이 빠르게 변할 때 빈번한 위치 전환이 발생할 수 있습니다.
매개 변수 위험: 잘못된 매개 변수 구성은 시장 특성을 포착하지 못할 수 있습니다.
스톱 로스 보호가 부족함: 단일 손실을 통제하기 위해 합리적인 스톱 로스를 설정해야 합니다.
위험 관리 방법:
다른 지표와 결합하여 전체 그림을 판단하고 높은 점과 낮은 점의 추격을 피하십시오.
신호 지연 및 평평화 매개 변수를 설정하여 오류 신호를 줄이십시오.
반복적으로 테스트하고 다양한 사이클에서 시장의 리듬에 맞추어 매개 변수를 최적화합니다.
한 번의 손실을 통제하기 위해 스톱 로스 및 수익 메커니즘을 설정하십시오.
이 전략이 더 이상 최적화 될 수 있는 몇 가지 방법:
빠른 선과 느린 선 길이 매개 변수의 다른 조합을 테스트하여 다른 사이클에서 시장 조건에 최적의 매개 변수를 찾습니다.
다른 신호 라인 매개 변수를 테스트합니다. 부드러운 신호 라인은 더 많은 소음을 필터링할 수 있습니다.
최적의 균형을 찾기 위해 신호 라인 크로스오버 필터를 켜고 끄는 차이점을 테스트합니다.
역 테스트 결과를 바탕으로 최적의 스톱 로스를 설정하고 수익률을 취합니다.
전략 효과를 극대화 할 수 있는지 확인하기 위해 길거나 짧게 시도하십시오.
이 MACD 이중 최적화 거래 전략은 긴 매개 변수와 짧은 매개 변수를 별도로 구성하여 다른 시장 방향에 맞춘 최적화를 실현하고 참여 방향의 자유로운 조정을 허용합니다. 동시에 잘못된 신호를 피하기 위해 신호 필터링 메커니즘이 도입됩니다. 매개 변수 최적화 및 위험 관리 조치를 통해 전략 효과를 더욱 향상시킬 수 있습니다.
/*backtest start: 2023-01-15 00:00:00 end: 2024-01-21 00:00:00 period: 1d basePeriod: 1h exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] */ //@version=5 // This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/ // © Gentleman-Goat & TradingTools.Software/Optimizer strategy(title="MACD Short/Long Strategy for TradingView Input Optimizer", shorttitle="MACD Short/Long TVIO", initial_capital=1000, default_qty_value=100, default_qty_type=strategy.percent_of_equity) // Get Inputs Long allow_long = input.bool(title="Allow Long", defval=true, group="inputs long") fast_length_long = input.int(title="Fast Length Long", defval=13, group="inputs long") slow_length_long = input.int(title="Slow Length Long", defval=19, group="inputs long") src_long = input.source(title="Source Long", defval=close, group="inputs long") signal_length_long = input.int(title="Signal Smoothing Long", minval = 1, maxval = 50, defval = 9, group="inputs long") sma_source_long = input.string(title="Oscillator MA Type Long", defval="EMA", options=["SMA", "EMA"], group="inputs long") sma_signal_long = input.string(title="Signal Line MA Type Long", defval="EMA", options=["SMA", "EMA"], group="inputs long") cross_point_long = input.int(title="Cross Point Long", defval=0, group="inputs long") cross_delay_macd_long = input.int(title="MacD Cross Delay Long", defval=0, group="inputs long") signal_must_cross_long = input.bool(title="Signal Must Also Cross Long", defval=false, group="inputs long") cross_delay_signal_long = input.int(title="Signal Cross Delay Long", defval=0, group="inputs long") //Get Inputs Short allow_short = input.bool(title="Allow Short", defval=true, group="inputs short") fast_length_short = input.int(title="Fast Length Short", defval=11, group="inputs short") slow_length_short = input.int(title="Slow Length Short", defval=20, group="inputs short") src_short = input.source(title="Source Short", defval=close, group="inputs short") signal_length_short = input.int(title="Signal Smoothing Short", minval = 1, maxval = 50, defval = 9, group="inputs short") sma_source_short = input.string(title="Oscillator MA Type Short", defval="EMA", options=["SMA", "EMA"], group="inputs short") sma_signal_short = input.string(title="Signal Line MA Type Short", defval="EMA", options=["SMA", "EMA"], group="inputs short") cross_point_short = input.int(title="Cross Point Short", defval=0, group="inputs short") cross_delay_macd_short = input.int(title="MacD Cross Delay Short", defval=1, group="inputs short") signal_must_cross_short = input.bool(title="Signal Must Also Cross Short", defval=false, group="inputs short") cross_delay_signal_short = input.int(title="Signal Cross Delay Short", defval=0, group="inputs short") use_stop_loss_long = input.bool(defval=false,title="Use Stop Loss Long", group="Stop/Profit Long") stop_loss_long_percentage = input.float(defval=1,title="Stop Loss % Long",minval=0.0,step=0.1, group="Stop/Profit Long") * .01 use_take_profit_long = input.bool(defval=false,title="Use Take Profit Long", group="Stop/Profit Long") take_profit_long_percentage = input.float(defval=1,title="Take Profit % Long",minval=0.0,step=0.1, group="Stop/Profit Long") * .01 use_stop_loss_short = input.bool(defval=true,title="Use Stop Loss Short", group="Stop/Profit Short") stop_loss_short_percentage = input.float(defval=21,title="Stop Loss % Short",minval=0.0,step=0.1, group="Stop/Profit Short") * .01 use_take_profit_short = input.bool(defval=true,title="Use Take Profit Short", group="Stop/Profit Short") take_profit_short_percentage= input.float(defval=20,title="Take Profit % Short",minval=0.0,step=0.1, group="Stop/Profit Short") * .01 //------------------------------------------------------------------------------ // Plot colors Long col_macd_long = input.color(#2962FF, "MACD Line Long", group="Color Settings", inline="MACD") col_signal_long = input.color(#FF6D00, "Signal Line Long", group="Color Settings", inline="Signal") col_grow_above_long = input.color(#26A69A, "Grow Above Long", group="Histogram Color Settings", inline="Above Long") col_fall_above_long = input.color(#B2DFDB, "Fall Above Long", group="Histogram Color Settings", inline="Above Long") col_grow_below_long = input.color(#FFCDD2, "Grow Below Long", group="Histogram Color Settings", inline="Below Long") col_fall_below_long = input.color(#FF5252, "Fall Below Long", group="Histogram Color Settings", inline="Below Long") // Plot colors Short col_macd_short = input.color(#B03DFF, "MACD Line Short", group="Color Settings", inline="MACD") col_signal_short = input.color(#00FFE8, "Signal Line Short", group="Color Settings", inline="Signal") col_grow_above_short = input.color(#D95965, "Grow Above Short", group="Histogram Color Settings", inline="Above Short") col_fall_above_short = input.color(#4D2024, "Fall Above Short", group="Histogram Color Settings", inline="Above Short") col_grow_below_short = input.color(#00322D, "Grow Below Short", group="Histogram Color Settings", inline="Below Short") col_fall_below_short = input.color(#00ADAD, "Fall Below Short", group="Histogram Color Settings", inline="Below Short") // Calculate Long fast_ma_long = sma_source_long == "SMA" ? ta.sma(src_long, fast_length_long) : ta.ema(src_long, fast_length_long) slow_ma_long = sma_source_long == "SMA" ? ta.sma(src_long, slow_length_long) : ta.ema(src_long, slow_length_long) macd_long = fast_ma_long - slow_ma_long signal_long = sma_signal_long == "SMA" ? ta.sma(macd_long, signal_length_long) : ta.ema(macd_long, signal_length_long) hist_long = macd_long - signal_long // Calculate Short fast_ma_short = sma_source_short == "SMA" ? ta.sma(src_short, fast_length_short) : ta.ema(src_short, fast_length_short) slow_ma_short = sma_source_short == "SMA" ? ta.sma(src_short, slow_length_short) : ta.ema(src_short, slow_length_short) macd_short = fast_ma_short - slow_ma_short signal_short = sma_signal_short == "SMA" ? ta.sma(macd_short, signal_length_short) : ta.ema(macd_short, signal_length_short) hist_short = macd_short - signal_short //Plot Long plot(hist_long, title="Histogram Long", style=plot.style_columns, color=(hist_long>=0 ? (hist_long[1] < hist_long ? col_grow_above_long : col_fall_above_long) : (hist_long[1] < hist_long ? col_grow_below_long : col_fall_below_long))) plot(macd_long, title="MACD Long", color=col_macd_long) plot(signal_long, title="Signal Long", color=col_signal_long) //Plot Short plot(hist_short, title="Histogram Short", style=plot.style_columns, color=(hist_short>=0 ? (hist_short[1] < hist_short ? col_grow_above_short : col_fall_above_short) : (hist_short[1] < hist_short ? col_grow_below_short : col_fall_below_short))) plot(macd_short, title="MACD Short", color=col_macd_short) plot(signal_short, title="Signal Short", color=col_signal_short) var detectedLongCrossOver = false var detectedShortCrossUnder = false if(ta.crossunder(macd_short,cross_point_short)) detectedShortCrossUnder := true if(ta.crossover(macd_short,cross_point_short)) detectedShortCrossUnder := false if(ta.crossover(macd_long,cross_point_long)) detectedLongCrossOver := true if(ta.crossunder(macd_long,cross_point_long)) detectedLongCrossOver := false crossover_signal_long = ta.crossover(signal_long,cross_point_long) crossunder_signal_long = ta.crossunder(signal_long,cross_point_long) crossunder_signal_short = ta.crossunder(signal_short,cross_point_short) crossover_signal_short = ta.crossover(signal_short,cross_point_short) crossover_macd_long = ta.crossover(macd_long,cross_point_long) crossunder_macd_long = ta.crossunder(macd_long,cross_point_long) crossunder_macd_short = ta.crossunder(macd_short,cross_point_short) crossover_macd_short = ta.crossover(macd_short,cross_point_short) inEntry = false //Strategy Entries if (strategy.equity > 0) //This is required for the input optimizer to work since it will fail if the strategy fails to succeed by not having enough equity. if (strategy.position_size <= 0 and allow_long==true and inEntry==false) if(signal_must_cross_long==true) longSignalCondition = detectedLongCrossOver==true and crossover_signal_long[cross_delay_signal_long] strategy.entry(id="long", direction=strategy.long, when=longSignalCondition) if(longSignalCondition) inEntry:=true else longMacDCondition = crossover_macd_long[cross_delay_macd_long] strategy.entry(id="long", direction=strategy.long, when=longMacDCondition) if(longMacDCondition) inEntry:=true if (strategy.position_size >= 0 and allow_short==true and inEntry==false) if(signal_must_cross_short==true) shortSignalCondition = detectedShortCrossUnder and crossunder_signal_short[cross_delay_signal_short] strategy.entry(id="short", direction=strategy.short, when=shortSignalCondition) if(shortSignalCondition) inEntry:=true else shortMacDCondition = crossunder_macd_short[cross_delay_macd_short] strategy.entry(id="short", direction=strategy.short, when=shortMacDCondition) if(shortMacDCondition) inEntry:=true if(strategy.position_size > 0 and allow_long==true and allow_short==false) if(signal_must_cross_long==true) strategy.close(id="long", when=detectedLongCrossOver==false and crossunder_signal_long) else strategy.close(id="long", when=crossunder_macd_long) if(strategy.position_size < 0 and allow_short==true and allow_long==false) if(signal_must_cross_short==true) strategy.close(id="short", when=detectedShortCrossUnder==false and crossover_signal_short) else strategy.close(id="short", when=crossover_macd_short) stop_loss_value_long = strategy.position_avg_price*(1 - stop_loss_long_percentage) take_profit_value_long = strategy.position_avg_price*(1 + take_profit_long_percentage) stop_loss_value_short = strategy.position_avg_price*(1 + stop_loss_short_percentage) take_profit_value_short = strategy.position_avg_price*(1 - take_profit_short_percentage) if(strategy.position_size>0) //Long positions only strategy.exit(id="TP/SL Long",from_entry="long", limit=use_take_profit_long ? take_profit_value_long : na, stop=use_stop_loss_long ? stop_loss_value_long : na) if(strategy.position_size<0) //Short positions only strategy.exit(id="TP/SL Short",from_entry="short", limit=use_take_profit_short ? take_profit_value_short : na, stop=use_stop_loss_short ? stop_loss_value_short : na)