MACD双方向最適化取引戦略


作成日: 2024-01-22 11:10:10 最終変更日: 2024-01-22 11:10:10
コピー: 0 クリック数: 323
1
フォロー
1166
フォロワー

MACD双方向最適化取引戦略

2 戦略概要

この戦略は,MACD指標と均線の交差原理を用いて取引信号を構築する.その優点は,MACDのパラメータを,それぞれ多額の方向と短額の方向に最適化でき,その結果,パラメータを,異なる市場情勢の方向に最適配置できるようにすることにある.

3つ目 戦略の原則

  1. プラスと空白の2つの方向のMACD指標をそれぞれ計算する. プラスには1つのパラメータ群,空白には別のパラメータ群を採用し,自由に構成することができる.
  2. MACD線とSignal線の交差を判断し,取引シグナルを生成する。多行時看交差,空調時看落交差。
  3. 偽信号を避けるため,Signal線が交差して信号を誘発するかどうかを設定できます.
  4. ポジションをオーバーまたは空白にすると,逆の交差時に平仓を待つ.

4 戦略的優位性

  1. 双方向パラメータ最適化:多行と空行のパラメータを自由に最適化して,それぞれ行情方向に最適配置できるようにする.
  2. 設定可能な信号平滑:Signalパラメータは,偽信号をフィルターする信号線の平滑度を制御できます.
  3. 設定可能な信号フィルター:偽信号の誤導を防ぐために,Signalラインの交差を触発するかどうかを設定できます.
  4. 微調整可能なポジションコントロール:単独で多空または空白を起動したり,同時に多空をすることもできます.

5 戦略的リスク

  1. MACDの遅滞問題:MACDは遅滞しているため,急速な反転を逃す可能性があります.
  2. 多空切替リスク: 市場が急速に変化する時に,ポジション切替が頻度が高い可能性があります.
  3. パラメータリスク: パラメータを正しく配置しない場合,状況特性を捉えられない可能性があります.
  4. 損失防止:単一損失を制御するために合理的な損失を設定する.

リスクの管理方法:

  1. 状況の全体像を判断する他の指標と組み合わせて, 追いかけるのを避けましょう.
  2. 信号の遅延と滑らかなパラメータを設定して誤信号を減らす.
  3. 繰り返しテストする最適化パラメータは,異なる周期の走行リズムにマッチするように.
  4. 単一損失を制御するストップ・ストップ・メカニズムを設定する.

6 改善の方向性

この戦略は,以下の点で最適化できます.

  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)