MACDトレンドバランス戦略

作者: リン・ハーンチャオチャン開催日:2023年10月17日 16:15:53
タグ:

img

概要

この戦略は,MACD指標を使用して上昇と下落の方向性を識別するトレンドフォロー戦略である.高速移動平均値とスロー移動平均値の違いを計算することによってMACDメインラインを生成する.この戦略は,MACDメインラインとシグナルラインの黄金十字を使って購入信号を生成し,死亡十字を使って販売信号を生成し,トレンドのバランスの取れた追跡を実現する.

戦略の論理

戦略の履歴性能をテストするための バックテストの時間枠を設定します

MACDインジケーターは,Fast Moving Average,Slow Moving Average,MACD Moving Averageの長さ設定を含む計算されます.Fast Lineはより敏感に反応し,Slow Lineはより安定的に反応します.それらの差はMACDメインラインを形成し,その後MACD信号ラインを形成するために移動平均値で滑らかされます.差がゼロラインを超えると,上昇信号が生成されます.下を通ると,下降信号が生成されます.

上昇信号と下落信号に基づいて,信号が生成された最後の時間を記録します. 速い線と遅い線が交差すると,購入/販売信号を確認し記録し,その時点でポジションを開くことができます.

ポジションに入ると,ポジションの最高値と最低値を継続的に追跡します.ストップ損失パーセントを設定します.損失がこのパーセントに達すると,ストップ損失で退場します.

利点

  1. MACD指標は,動向を効果的に特定することができ,従来の技術指標の1つです.

  2. 急速な移動平均値と遅い移動平均値の差は,価格の動向と方向の変化を早期に把握することができます.

  3. 移動平均値のフィルタリング効果は 誤った信号をフィルタリングするのに役立ちます

  4. 戦略にはリスク管理のためのストップ・ロスのメカニズムが含まれています

リスク

  1. MACDは最適化スペースが限られているため,誤った信号を生成する傾向があります.

  2. 誤ったストップロスの配置は,過剰に積極的または保守的になり,製品全体で個別最適化が必要です.

  3. 固定ポジションのサイズ設定は,過度レバレッジを容易に行う可能性があります.アカウントサイズに基づいてポジションサイズ設定を検討してください.

  4. バックテストのタイムフレームの根拠は過度に適合しないように検証する必要がある.

最適化

  1. 異なる製品に最適なパラメータを見つけるために,高速移動平均と遅い移動平均の組み合わせを最適化します.

  2. フィルター信号にキャンドルスタイク,ボリンジャー帯,RSIなどの指標を追加します

  3. ストップ・ロスのレベルを 引き下げ,シャープ比率に基づいて評価する

  4. ストップ・ロストや制限オーダーなど ストップ・ロストのテクニックを探ります

  5. 動的ポジションのサイズを試す 資本,波動性に基づいて

結論

MACDトレンドバランス戦略は,クラシックなMACD指標に基づいています.価格の勢いを敏感に捉える能力があり,パラメータ最適化によって異なる製品にうまく適応できます.フィルタリング信号,ストップ損失技術,ダイナミックなポジションサイジングのさらなる強化により,安定性と収益性が向上し続けることができます.


/*backtest
start: 2023-09-16 00:00:00
end: 2023-10-16 00:00:00
period: 3h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=2
strategy("MACD BF", overlay=true, initial_capital=10000, default_qty_type=strategy.percent_of_equity, default_qty_value=100, commission_type=strategy.commission.percent, commission_value=0.0)

/////////////// Component Code Start ///////////////
testStartYear = input(2017, "Backtest Start Year") 
testStartMonth = input(1, "Backtest Start Month")
testStartDay = input(1, "Backtest Start Day")
testPeriodStart = timestamp(testStartYear,testStartMonth,testStartDay, 0, 0)

testStopYear = input(2019, "Backtest Stop Year")
testStopMonth = input(12, "Backtest Stop Month")
testStopDay = input(31, "Backtest Stop Day")
testPeriodStop = timestamp(testStopYear,testStopMonth,testStopDay, 0, 0)

// A switch to control background coloring of the test period
testPeriodBackground = input(title="Color Background?", type=bool, defval=true)
testPeriodBackgroundColor = testPeriodBackground and (time >= testPeriodStart) and (time <= testPeriodStop) ? #00FF00 : na
bgcolor(testPeriodBackgroundColor, transp=97)

testPeriod() => true

///////////////  MACD Component - Default settings for one day. /////////////// 
fastLength = input(12) // 72 for 4hr
slowlength = input(26) // 156 for 4 hr
MACDLength = input(12)  // 12 for 4hr

MACD = ema(close, fastLength) - ema(close, slowlength)
aMACD = ema(MACD, MACDLength)
delta = MACD - aMACD

long = crossover(delta, 0) 
short = crossunder(delta, 0) 

last_long = long ? time : nz(last_long[1])
last_short = short ? time : nz(last_short[1])

long_signal = crossover(last_long, last_short)
short_signal = crossover(last_short, last_long)

last_open_long_signal = long_signal ? open : nz(last_open_long_signal[1])
last_open_short_signal = short_signal ? open : nz(last_open_short_signal[1])

last_long_signal = long_signal ? time : nz(last_long_signal[1])
last_short_signal = short_signal ? time : nz(last_short_signal[1])

in_long_signal = last_long_signal > last_short_signal
in_short_signal = last_short_signal > last_long_signal

last_high = not in_long_signal ? na : in_long_signal and (na(last_high[1]) or high > nz(last_high[1])) ? high : nz(last_high[1])
last_low = not in_short_signal ? na : in_short_signal and (na(last_low[1]) or low < nz(last_low[1])) ? low : nz(last_low[1])

sl_inp = input(5.0, title='Stop Loss %', type=float)/100

/////////////// Strategy Component /////////////// 
// Strategy Entry
if testPeriod()
    strategy.entry("Long Entry",  strategy.long, when=long_signal)
    strategy.entry("Short Entry", strategy.short, when=short_signal)

since_longEntry = barssince(last_open_long_signal != last_open_long_signal[1]) // LONG SL
since_shortEntry = barssince(last_open_short_signal != last_open_short_signal[1]) // SHORT SL

slLong = in_long_signal ? strategy.position_avg_price * (1 - sl_inp) : na
slShort = strategy.position_avg_price * (1 + sl_inp)
long_sl = in_long_signal ? slLong : na
short_sl = in_short_signal ? slShort : na

// Strategy SL Exit
if testPeriod()
    strategy.exit("Long SL", "Long Entry", stop=long_sl, when=since_longEntry > 1)
    strategy.exit("Short SL", "Short Entry", stop=short_sl, when=since_shortEntry > 1)

//plot(strategy.equity, title="equity", color=blue, linewidth=2, style=areabr)

もっと