MACD 이중 최적화 거래 전략

저자:차오장, 날짜: 2024-01-22 11:10:10
태그:

img

전략 개요

이 전략은 거래 신호를 구성하기 위해 MACD 지표와 이동 평균 교차 원리를 사용합니다. 이 전략의 장점은 MACD의 매개 변수를 길고 짧은 방향에 별도로 최적화 할 수 있으므로 매개 변수는 다른 시장 방향에 최적화 될 수 있습니다.

III. 전략 원칙

  1. 긴 방향과 짧은 방향에 대해 MACD 지표를 별도로 계산합니다. 한 세트의 매개 변수는 긴 방향으로 사용되며 다른 세트의 매개 변수는 짧은 방향으로 사용되며 자유롭게 구성 할 수 있습니다.

  2. MACD 라인과 신호 라인의 크로스오버에 의해 생성된 거래 신호를 판단합니다. 길이를위한 상승 크로스오버와 짧은 하락 크로스오버를 찾으십시오.

  3. 신호를 발사하기 위해 신호 라인이 교차해야 하는지를 설정할 수 있습니다.

  4. 긴 위치 또는 짧은 위치로 들어가면 역차가 발생하면 위치를 닫습니다.

IV. 전략의 장점

  1. 쌍방향 매개 변수 최적화: 장기 및 단기 매개 변수를 자유롭게 최적화하여 시장 방향에 대해 개별적으로 최적화 할 수 있습니다.

  2. 구성 가능한 신호 평형: 신호 매개 변수는 잘못된 신호를 필터링하기 위해 신호 라인의 평형을 제어 할 수 있습니다.

  3. 구성 가능한 신호 필터링: 잘못된 신호를 피하기 위해 신호 라인 크로스오버가 작동해야하는지 여부를 구성할 수 있습니다.

  4. 세밀하게 조정된 위치 제어: 길거나 짧은 단위만 개별적으로 활성화 할 수 있습니다. 또는 길고 짧은 단위도 동시에 수행 할 수 있습니다.

전략의 위험

  1. MACD 지연: MACD 자체는 빠른 반전을 놓칠 수 있는 약간의 지연을 가지고 있습니다.

  2. 장기 및 단위 사이로 전환하는 위험: 시장이 빠르게 변할 때 빈번한 위치 전환이 발생할 수 있습니다.

  3. 매개 변수 위험: 잘못된 매개 변수 구성은 시장 특성을 포착하지 못할 수 있습니다.

  4. 스톱 로스 보호가 부족함: 단일 손실을 통제하기 위해 합리적인 스톱 로스를 설정해야 합니다.

위험 관리 방법:

  1. 다른 지표와 결합하여 전체 그림을 판단하고 높은 점과 낮은 점의 추격을 피하십시오.

  2. 신호 지연 및 평평화 매개 변수를 설정하여 오류 신호를 줄이십시오.

  3. 반복적으로 테스트하고 다양한 사이클에서 시장의 리듬에 맞추어 매개 변수를 최적화합니다.

  4. 한 번의 손실을 통제하기 위해 스톱 로스 및 수익 메커니즘을 설정하십시오.

VI. 최적화 방향

이 전략이 더 이상 최적화 될 수 있는 몇 가지 방법:

  1. 빠른 선과 느린 선 길이 매개 변수의 다른 조합을 테스트하여 다른 사이클에서 시장 조건에 최적의 매개 변수를 찾습니다.

  2. 다른 신호 라인 매개 변수를 테스트합니다. 부드러운 신호 라인은 더 많은 소음을 필터링할 수 있습니다.

  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)

더 많은