MACD 양방향 최적화 거래 전략


생성 날짜: 2024-01-22 11:10:10 마지막으로 수정됨: 2024-01-22 11:10:10
복사: 0 클릭수: 626
avatar of ChaoZhang ChaoZhang
1
집중하다
1617
수행원

MACD 양방향 최적화 거래 전략

2 전략 개요

이 전략은 MACD 지표와 평행선의 교차 원칙을 사용하여 거래 신호를 구성한다. 이 전략의 장점은 MACD의 매개 변수를 각각 상장 및 상하 방향으로 최적화하여 매개 변수가 다른 상장 방향에 대해 최적화 할 수 있다는 것이다.

세번째, 전략적 원칙

  1. 각각 양방향으로 계산되는 MACD 지표들. 한 집합의 매개 변수를 사용하여 더하고, 다른 집합의 매개 변수를 사용하여 더하고, 다른 집합의 매개 변수를 사용하여 더하고, 자유롭게 구성할 수 있다.
  2. MACD 라인과 Signal 라인이 교차하면 거래 신호가 발생한다. 상향 교차하면 상향 교차, 하향 교차하면 하향 교차한다.
  3. Signal 라인을 설정할 수 있습니다. Signal 라인이 신호를 유발하기 위해 교차해야 하는 경우도 설정할 수 있습니다. 이렇게 하면 가짜 신호를 방지할 수 있습니다.
  4. 상위 또는 하위 포지션에 들어가고, 반전 교차시 평형 포지션을 기다립니다.

네, 전략적 장점

  1. 양방향 변수 최적화: 더 많은 변수와 더 적은 변수를 자유롭게 최적화하여 각각 시장 방향에 따라 최적의 구성을 할 수 있다.
  2. 설정 가능한 신호 평평: Signal 파라미터는 신호 라인의 평평도를 제어하고, 가짜 신호를 필터링한다.
  3. 설정 가능한 신호 필터링: 가짜 신호의 오해를 방지하기 위해 Signal 라인 교차가 필요한지 설정할 수 있다.
  4. 미세 조정 가능한 포지션 제어: 개별적으로 추가 또는 공백을 열 수 있으며 동시에 추가 공백을 할 수도 있습니다.

다섯째, 전략적 위험

  1. MACD 지연 문제: MACD 자체는 지연이 있어 빠른 반전을 놓칠 수 있다.
  2. 다방위 전환 위험: 시장 상황이 급격히 변화할 때, 포지션 전환이 너무 자주 발생할 수 있다.
  3. 매개 변수 위험: 잘못된 매개 변수 구성으로 실황 특성을 잡을 수 없습니다.
  4. 손실 보호: 단독 손실을 제어하기 위해 합리적인 손실을 설정해야합니다.

위험을 관리하는 방법:

  1. 다른 지표들과 함께 큰 틀을 판단하고, 위아래를 쫓는 것을 피하십시오.
  2. 신호 지연 및 부드러운 매개 변수를 설정하여 잘못된 신호를 줄여줍니다.
  3. 반복적으로 테스트하여 최적화 파라미터를 다른 주기에서 동작하는 속도와 일치하도록 한다.
  4. 단독 손실을 제어하기 위해 HST를 설정합니다.

여섯째, 최적화 방향

이 전략은 다음과 같은 측면에서 최적화될 수 있습니다.

  1. 다양한 빠른 선과 느린 선의 길이 파라미터 조합을 테스트하여 다양한 주기적 상황에 최적의 파라미터를 찾습니다.

  2. 다양한 Signal 라인 파라미터를 테스트하고, Smoother 신호 라인은 더 많은 잡음을 필터링할 수 있다.

  3. 시그널 라인을 열고 닫는 크로스 필터의 차이를 테스트하여 최적의 균형을 찾습니다.

  4. 재검토 상황에 따라 최적의 스톱 스탠드 비율을 설정한다.

  5. 이 전략의 효과를 극대화할 수 있는지 확인하기 위해, 그냥 더 많이 하거나 그냥 아무것도 하지 않는 방법을 시도해보세요.

VII. 결론

이 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)