MACD戦略 - 二方向の出口取引

作者: リン・ハーンチャオチャン開催日:2023年12月12日12時45分50秒
タグ:

img

概要

この戦略は,移動平均収束差異 (MACD) 指標を使用して,長期と短期の信号を生成し,利益を得るために動的に出口点を設定することで,良いトレンド条件下で逆転取引を行います.

戦略の原則

この戦略の核心は,長信号のMACDゴールデンクロスと短信号のデスクロスに基づいています.特に,MACD線が下から信号線の上を横切ると,長信号としてゴールデンクロスが生成されます.MACD線が上から信号線下を横切ると,デスクロスはショート信号として生成されます.

ゴールドクロスシグナルでは,閉じる価格がEMAより高くなった場合,ロングシグナルで,死点クロスシグナルでは,閉じる価格がEMAより低くなった場合,ショートシグナルで,上向きのトレンドの下での逆転取引を保証します.

ポジションを入力した後に,ストップロスを利用し,出口をダイナミックに制御するために利益を得ます.特に,ロングポジションのストップロスはエントリー価格 * (1 - 最大引き下げ) に設定され,利益を得ることはエントリー価格 * (1 + TARGET_STOP_RATIO * 最大引き下げ) に設定されます.ショートポジションの場合は逆です.ここで,最大引き下げは,スイングローから閉じるまでの価格減少の割合として動的に計算されます. TARGET_STOP_RATIOはデフォルトで2,つまりリスク/リターン比は2です.

このダイナミックストップ戦略の利点は,市場の変動に基づいてストップ損失とリスク/リターン比を調整できる点である.高波動時の緊密なストップ損失で迅速に終了し,低波動環境では緩いストップで利益を追跡する.

利点

  1. MACDは逆転の機会を特定するための効果的な指標です.

  2. EMAフィルターは,上向きの市場でのみロング取引を保証します.

  3. ダイナミックな出口制御システムは リスクを効果的に管理しながら 利益を最大化します

  4. 急速な速さにより 監視時間が短縮され 忙しい投資家に適しています

リスク と 解決策

  1. MACDは横向市場では頻繁に振動し,偽の信号を生成する.これは反トレンド取引を避けるためにEMAフィルターを追加することで解決する.

  2. 極端な変動がDYNAMIC STOPを過度に緩やかにする可能性があります. 極端な市場動向に直面するときに固定リスク/リターン比を考えてください.

  3. 取引ごとに限られた利益率は頻繁な取引を必要とします.投資家は一定の心理的な耐力と時間コミットメントを必要とします.忙しい場合はより高い時間枠に切り替えることができます.

オプティマイゼーションの方向性

  1. シグナル品質を最適化するために,シンボルの特徴に基づいて MACD パラメータを調整します.

  2. トレンドフィルターとして異なる移動平均値をテストして最適値を見つけます

  3. TARGET_STOP_RATIOの計算と最大引き上げの定義をテストして,退出戦略を最適化します.

  4. 信号の質を改善するために 音量や波動性などの他の要因を追加します

  5. 機械学習モデルを探求し より多くの機能を抽出し よりスマートな出口のための適応型多要素モデルを構築します

結論

この戦略は全体的に強力な実用的な価値を持っています.MACDがコア取引信号であるため,トレンドフィルターとダイナミック出口制御の追加モジュールはMACDのパフォーマンスを大幅に改善することができます.出口制御は戦略最適化にとって不可欠であり,この戦略はこの分野で大幅に革新しています.さらなる研究と適用に価値がある.


/*backtest
start: 2022-12-05 00:00:00
end: 2023-12-11 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © maxencetajet

//@version=5
strategy("MACD Strategy", overlay=true, initial_capital=1000, slippage=25)

src = input(title="Source", defval=close)
target_stop_ratio = input.float(title='Risk/Reward', defval=2, minval=0.5, maxval=100)
risk = input.float(2, title="Risk per Trade %")

riskt = risk / 100 + 1

useDateFilter = input.bool(true, title="Filter Date Range of Backtest",
     group="Backtest Time Period")
backtestStartDate = input(timestamp("5 June 2022"), 
     title="Start Date", group="Backtest Time Period",
     tooltip="This start date is in the time zone of the exchange " + 
     "where the chart's instrument trades. It doesn't use the time " + 
     "zone of the chart or of your computer.")
backtestEndDate = input(timestamp("5 July 2022"),
     title="End Date", group="Backtest Time Period",
     tooltip="This end date is in the time zone of the exchange " + 
     "where the chart's instrument trades. It doesn't use the time " + 
     "zone of the chart or of your computer.")

inTradeWindow =  true
emaV = input.int(200, title="Length", group="EMA")
swingHighV = input.int(7, title="Swing High", group="number of past candles")
swingLowV = input.int(7, title="Swing Low", group="number of past candles")

ema = ta.ema(src, emaV)

fast_length = input(title="Fast Length", defval=12, group="MACD")
slow_length = input(title="Slow Length", defval=26, group="MACD")
signal_length = input.int(title="Signal Smoothing",  minval = 1, maxval = 50, defval = 9, group="MACD")
sma_source = input.string(title="Oscillator MA Type",  defval="EMA", options=["SMA", "EMA"], group="MACD")
sma_signal = input.string(title="Signal Line MA Type", defval="EMA", options=["SMA", "EMA"], group="MACD")

fast_ma = sma_source == "SMA" ? ta.sma(src, fast_length) : ta.ema(src, fast_length)
slow_ma = sma_source == "SMA" ? ta.sma(src, slow_length) : ta.ema(src, slow_length)
macd = fast_ma - slow_ma
signal = sma_signal == "SMA" ? ta.sma(macd, signal_length) : ta.ema(macd, signal_length)
hist = macd - signal

longcondition = close > ema and ta.crossover(macd, signal) and macd < 0
shortcondition = close < ema and ta.crossunder(macd, signal) and macd > 0

float risk_long = na
float risk_short = na
float stopLoss = na
float takeProfit = na
float entry_price = na

risk_long := risk_long[1]
risk_short := risk_short[1]

swingHigh = ta.highest(high, swingHighV)
swingLow = ta.lowest(low, swingLowV)

lotB = (strategy.equity*riskt-strategy.equity)/(close - swingLow)
lotS = (strategy.equity*riskt-strategy.equity)/(swingHigh - close)

if strategy.position_size == 0 and longcondition and inTradeWindow
    risk_long := (close - swingLow) / close
    strategy.entry("long", strategy.long, qty=lotB)
    
if strategy.position_size == 0 and shortcondition and inTradeWindow
    risk_short := (swingHigh - close) / close  
    strategy.entry("short", strategy.short, qty=lotS)

if strategy.position_size > 0

    stopLoss := strategy.position_avg_price * (1 - risk_long)
    takeProfit := strategy.position_avg_price * (1 + target_stop_ratio * risk_long)
    entry_price := strategy.position_avg_price
    strategy.exit("long exit", "long", stop = stopLoss, limit = takeProfit)
    
if strategy.position_size < 0

    stopLoss := strategy.position_avg_price * (1 + risk_short)
    takeProfit := strategy.position_avg_price * (1 - target_stop_ratio * risk_short)
    entry_price := strategy.position_avg_price
    strategy.exit("short exit", "short", stop = stopLoss, limit = takeProfit)
    
plot(ema, color=color.white, linewidth=2, title="EMA")
p_ep = plot(entry_price, color=color.new(color.white, 0), linewidth=2, style=plot.style_linebr, title='entry price')
p_sl = plot(stopLoss, color=color.new(color.red, 0), linewidth=2, style=plot.style_linebr, title='stopLoss')
p_tp = plot(takeProfit, color=color.new(color.green, 0), linewidth=2, style=plot.style_linebr, title='takeProfit')
fill(p_sl, p_ep, color.new(color.red, transp=85))
fill(p_tp, p_ep, color.new(color.green, transp=85))



もっと