Ergotic Dual-rail Reverse MACD Strategi Dagangan Kuantitatif

Penulis:ChaoZhang, Tarikh: 2023-12-21 11:07:51
Tag:

img

Ringkasan

Strategi ini adalah strategi dagangan kuantitatif MACD terbalik dua rel. Ia berdasarkan kepada penunjuk teknikal yang diterangkan oleh William Blau dalam bukunya Momentum, Direction and Divergence dan memperluaskannya. Strategi ini juga mempunyai keupayaan backtesting dan boleh menggabungkan ciri tambahan seperti amaran, penapis, penangguhan stop loss, dll.

Prinsip-prinsip

Indikator teras strategi ini adalah MACD. Ia mengira purata bergerak pantas EMA® dan purata bergerak perlahan EMA ((slowMALen), kemudian mengira perbezaan mereka xmacd. Ia juga mengira EMA ((signalLength) xmacd untuk mendapatkan xMA_MACD. Isyarat panjang dipicu apabila xmacd melintasi di atas xMA_MACD, dan isyarat pendek dipicu pada silang di bawah. Aspek utama strategi ini adalah isyarat perdagangan terbalik, iaitu hubungan antara xmacd dan xMA_MACD bertentangan dengan petunjuk MACD konvensional, yang juga dari mana nama Reverse MACD berasal.

Di samping itu, strategi ini menggabungkan penapis trend. Apabila isyarat panjang ditembakkan, jika penapis trend menaik dikonfigurasi, ia akan memeriksa sama ada harga meningkat. Begitu juga, isyarat pendek memeriksa trend harga menurun. Indikator RSI dan MFI juga boleh digunakan untuk menapis isyarat. Mekanisme stop loss disertakan untuk mencegah kerugian di luar ambang.

Analisis Kelebihan

Kelebihan terbesar strategi ini adalah keupayaan backtesting yang kuat. Anda boleh memilih instrumen dagangan yang berbeza, menetapkan jangka masa backtest, dan mengoptimumkan parameter strategi berdasarkan data instrumen tertentu. Berbanding dengan strategi MACD yang mudah, ia menggabungkan trend dan analisis overbought / oversold untuk menapis beberapa isyarat yang sama.

Analisis Risiko

Risiko utama strategi ini berasal dari logik perdagangan terbalik. Walaupun isyarat terbalik boleh menangkap beberapa peluang yang dilewatkan oleh isyarat tradisional, ia juga bermakna kehilangan beberapa titik masuk MACD konvensional, yang memerlukan penilaian yang teliti.

Untuk mengurangkan risiko, parameter boleh dioptimumkan - menyesuaikan panjang purata bergerak; menggabungkan trend dan penapis penunjuk mengelakkan isyarat di pasaran yang berbelit-belit; menaikkan jarak stop loss memastikan kerugian terhad pada perdagangan individu.

Arahan pengoptimuman

Strategi ini boleh ditingkatkan dalam beberapa aspek:

  1. Sesuaikan parameter rel pantas dan perlahan, mengoptimumkan panjang purata bergerak, backtest untuk mencari set parameter optimum untuk instrumen tertentu
  2. Tambah atau menyesuaikan penapis trend, menilai daripada hasil backtest sama ada ia meningkatkan pulangan
  3. Uji mekanisme stop loss yang berbeza, tetap atau belakang untuk menentukan prestasi yang lebih baik
  4. Cuba menggabungkan penunjuk lain seperti KD, Bollinger Bands untuk menetapkan syarat penapis tambahan dan memastikan kualiti isyarat

Ringkasan

Strategi kuantitatif MACD terbalik berkerudung dua membina pada penunjuk MACD klasik dengan pelanjutan dan penambahbaikan. Dengan konfigurasi parameter yang fleksibel, pilihan penapis yang banyak, dan fungsi backtesting yang kuat, ia boleh disesuaikan untuk sesuai dengan instrumen dagangan yang berbeza. Oleh itu, ia adalah strategi dagangan kuantitatif yang menarik dan menjanjikan yang layak diteroka lebih lanjut.


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

//@version = 3
////////////////////////////////////////////////////////////
//  Copyright by HPotter v1.0 09/12/2016
// This is one of the techniques described by William Blau in his book
// "Momentum, Direction and Divergence" (1995). If you like to learn more,
// we advise you to read this book. His book focuses on three key aspects
// of trading: momentum, direction and divergence. Blau, who was an electrical
// engineer before becoming a trader, thoroughly examines the relationship 
// between price and momentum in step-by-step examples. From this grounding,
// he then looks at the deficiencies in other oscillators and introduces some
// innovative techniques, including a fresh twist on Stochastics. On directional 
// issues, he analyzes the intricacies of ADX and offers a unique approach to help 
// define trending and non-trending periods.
// Blau`s indicator is like usual MACD, but it plots opposite of meaningof
// stndard MACD indicator. 
//
// You can change long to short in the Input Settings
// Please, use it only for learning or paper trading. Do not for real trading.
//
//
// 2018-09 forked by Khalid Salomão
// - Backtesting
// - Added filters: RSI, MFI, Price trend
// - Trailing Stop Loss
// - Other minor adjustments
//
////////////////////////////////////////////////////////////
strategy(title="Ergotic MACD Backtester [forked from HPotter]", shorttitle="Ergotic MACD Backtester", overlay=true, pyramiding=0, default_qty_type=strategy.cash, default_qty_value=25000, initial_capital=50000, commission_type=strategy.commission.percent, commission_value=0.15, slippage=3)


// === BACKTESTING: INPUT BACKTEST RANGE ===
source = input(close)
strategyType = input(defval="Long Only", options=["Long & Short", "Long Only", "Short Only"])

FromMonth = input(defval = 7, title = "From Month", minval = 1, maxval = 12)
FromDay   = input(defval = 1, title = "From Day", minval = 1, maxval = 31)
FromYear  = input(defval = 2018, title = "From Year", minval = 2017)
ToMonth   = input(defval = 12, title = "To Month", minval = 1, maxval = 12)
ToDay     = input(defval = 1, title = "To Day", minval = 1, maxval = 31)
ToYear    = input(defval = 2030, title = "To Year", minval = 2017)

start     = timestamp(FromYear, FromMonth, FromDay, 00, 00)  
finish    = timestamp(ToYear, ToMonth, ToDay, 23, 59)        
window()  => true // window of time verification

// === STRATEGY ===

r = input(144, minval=1, title="R (32,55,89,100,144,200)") // default 32
slowMALen = input(6, minval=1) // default 32
signalLength = input(6, minval=1)
reverse = input(false, title="Trade reverse (long/short switch)")

//hline(0, color=blue, linestyle=line)

fastMA = ema(source, r)
slowMA = ema(source, slowMALen)
xmacd = fastMA - slowMA
xMA_MACD = ema(xmacd, signalLength)

pos = 0
pos := iff(xmacd < xMA_MACD, 1,
	   iff(xmacd > xMA_MACD, -1, nz(pos[1], 0))) 
possig = 0
possig := iff(reverse and pos == 1, -1,
          iff(reverse and pos == -1, 1, pos))

// === FILTER: price trend ====
trending_price_long = input(true, title="Long only if price has increased" )
trending_price_short = input(false, title="Short only if price has decreased" )
trending_price_length = input( 2, minval=1 )
trending_price_with_ema = input( false )
trending_price_ema = input( 3, minval=1 )
price_trend = trending_price_with_ema ? ema(source, trending_price_ema) : source
priceLongTrend() => (trending_price_long ? rising(price_trend, trending_price_length) : true)
priceShortTrend() => (trending_price_short ? falling(price_trend, trending_price_length) : true)

// === FILTER: RSI ===
rsi_length = input( 14, minval=1 )
rsi_overSold = input( 14, minval=0, title="RSI Sell Cutoff (Sell only if >= #)" )
rsi_overBought = input( 82, minval=0, title="RSI Buy Cutoff (Buy only if <= #)" )

vrsi = rsi(source, rsi_length)
rsiOverbought() => vrsi > rsi_overBought
rsiOversold() => vrsi < rsi_overSold

trending_rsi_long = input(false, title="Long only if RSI has increased" )
trending_rsi_length = input( 2 )
rsiLongTrend() => trending_rsi_long ? rising(vrsi, trending_rsi_length) : true

// === FILTER: MFI ===
mfi_length = input(14, minval=1)
mfi_lower = input(14, minval=0, maxval=50)
mfi_upper = input(82, minval=50, maxval=100)
upper_s = sum(volume * (change(source) <= 0 ? 0 : source), mfi_length)
lower_s = sum(volume * (change(source) >= 0 ? 0 : source), mfi_length)
mf = rsi(upper_s, lower_s)

mfiOverbought() => (mf > mfi_upper)
mfiOversold() => (mf < mfi_lower)

trending_mfi_long = input(false, title="Long only if MFI has increased" )
trending_mfi_length = input( 2 )
mfiLongTrend() => trending_mfi_long ? rising(mf, trending_mfi_length) : true

// === SIGNAL CALCULATION ===
long  = window() and possig == 1 and rsiLongTrend() and mfiLongTrend() and not rsiOverbought() and not mfiOverbought() and priceLongTrend()
short = window() and possig == -1 and not rsiOversold() and not mfiOversold() and priceShortTrend()

// === trailing stop
tslSource=input(hlc3,title="TSL source")
//suseCurrentRes = input(true, title="Use current chart resolution for stop trigger?")
tslResolution = input(title="Use different timeframe for stop trigger? Uncheck box above.", defval="5")
tslTrigger = input(3.0) / 100
tslStop = input(0.6) / 100

currentPrice = request.security(syminfo.tickerid, tslResolution, tslSource, barmerge.gaps_off, barmerge.lookahead_off)

isLongOpen = false
isLongOpen := nz(isLongOpen[1], false)
entryPrice=0.0
entryPrice:= nz(entryPrice[1], 0.0)
trailPrice=0.0
trailPrice:=nz(trailPrice[1], 0.0)

// update TSL high mark
if (isLongOpen )
    if (not trailPrice and currentPrice >= entryPrice * (1 + tslTrigger))
        trailPrice := currentPrice
    else 
        if (trailPrice and currentPrice > trailPrice)
            trailPrice := currentPrice

if (trailPrice and currentPrice <= trailPrice * (1 - tslStop))
    // FIRE TSL SIGNAL
    short:=true // <===
    long := false

// if short clean up
if (short)
    isLongOpen := false
    entryPrice := 0.0
    trailPrice := 0.0

if (long)
    isLongOpen := true
    if (not entryPrice)
        entryPrice := currentPrice

// === BACKTESTING: ENTRIES ===
if long
    if (strategyType == "Short Only")
        strategy.close("Short")
    else
        strategy.entry("Long", strategy.long, comment="Long")

if short
    if (strategyType == "Long Only")
        strategy.close("Long")
    else
        strategy.entry("Short", strategy.short, comment="Short")	  
    
//barcolor(possig == -1 ? red: possig == 1 ? green : blue )
//plot(xmacd, color=green, title="Ergotic MACD")
//plot(xMA_MACD, color=red, title="SigLin")

plotshape(trailPrice ? trailPrice : na, style=shape.circle, location=location.absolute, color=blue, size=size.tiny)

plotshape(long, style=shape.triangleup, location=location.belowbar, color=green, size=size.tiny)
plotshape(short, style=shape.triangledown, location=location.abovebar, color=red, size=size.tiny)

// === Strategy Alert ===
alertcondition(long, title='BUY - Ergotic MACD Long Entry', message='Go Long!')
alertcondition(short, title='SELL - Ergotic MACD Long Entry', message='Go Short!')

// === BACKTESTING: EXIT strategy ===
sl_inp = input(7, title='Stop Loss %', type=float)/100
tp_inp = input(1.8, title='Take Profit %', type=float)/100

stop_level = strategy.position_avg_price * (1 - sl_inp)
take_level = strategy.position_avg_price * (1 + tp_inp)

strategy.exit("Stop Loss/Profit", "Long", stop=stop_level, limit=take_level)

Lebih lanjut