Sumber daya yang dimuat... Pemuatan...

Ergotic Dual-rail Reverse MACD Strategi Perdagangan Kuantitatif

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

img

Gambaran umum

Strategi ini adalah strategi perdagangan kuantitatif MACD terbalik dual-rail. Strategi ini didasarkan pada indikator teknis yang dijelaskan oleh William Blau dalam bukunya Momentum, Direction and Divergence dan memperluasnya. Strategi ini juga memiliki kemampuan backtesting dan dapat menggabungkan fitur tambahan seperti peringatan, filter, trailing stop loss, dll.

Prinsip-prinsip

Indikator inti dari strategi ini adalah MACD. Ini menghitung rata-rata bergerak cepat EMA® dan rata-rata bergerak lambat EMA ((slowMALen), kemudian menghitung perbedaan mereka xmacd. Ini juga menghitung EMA ((signalLength) dari xmacd untuk mendapatkan xMA_MACD. Sinyal panjang dipicu ketika xmacd melintasi di atas xMA_MACD, dan sinyal pendek dipicu pada silang di bawahnya. Aspek utama dari strategi ini adalah sinyal perdagangan terbalik, yaitu hubungan antara xmacd dan xMA_MACD berlawanan dengan indikator MACD konvensional, yang juga dari mana nama Reverse MACD berasal.

Selain itu, strategi ini menggabungkan filter tren. Ketika sinyal panjang menyala, jika filter tren bullish dikonfigurasi, itu akan memeriksa apakah harga meningkat. Demikian pula, sinyal pendek memeriksa tren harga menurun. Indikator RSI dan MFI juga dapat digunakan untuk menyaring sinyal. Mekanisme stop loss disertakan untuk mencegah kerugian di luar ambang batas.

Analisis Keuntungan

Keuntungan terbesar dari strategi ini adalah kemampuan backtesting yang kuat. Anda dapat memilih instrumen perdagangan yang berbeda, mengatur kerangka waktu backtest, dan mengoptimalkan parameter strategi berdasarkan data instrumen tertentu. Dibandingkan dengan strategi MACD sederhana, ini menggabungkan analisis tren dan overbought / oversold untuk menyaring beberapa sinyal yang sama.

Analisis Risiko

Risiko utama dari strategi ini berasal dari logika perdagangan terbalik. Sementara sinyal terbalik dapat menangkap beberapa peluang yang dilewatkan oleh sinyal tradisional, itu juga berarti kehilangan beberapa titik masuk MACD konvensional, yang memerlukan penilaian yang cermat.

Untuk mengurangi risiko, parameter dapat dioptimalkan - menyesuaikan panjang rata-rata bergerak; menggabungkan tren dan filter indikator menghindari sinyal di pasar yang bergolak; meningkatkan jarak stop loss memastikan kerugian terbatas pada perdagangan individu.

Arahan Optimasi

Strategi ini dapat ditingkatkan dalam beberapa aspek:

  1. Sesuaikan parameter rel cepat dan lambat, mengoptimalkan panjang rata-rata bergerak, backtest untuk menemukan set parameter optimal untuk instrumen tertentu
  2. Tambahkan atau atur filter tren, menilai dari hasil backtest apakah meningkatkan pengembalian
  3. Uji mekanisme stop loss yang berbeda, tetap atau trailing, untuk menentukan kinerja yang lebih baik
  4. Cobalah menggabungkan indikator lain seperti KD, Bollinger Bands untuk mengatur kondisi filter tambahan dan memastikan kualitas sinyal

Ringkasan

Strategi kuantitatif MACD terbalik dual-rail dibangun di atas indikator MACD klasik dengan ekstensi dan perbaikan. Dengan konfigurasi parameter yang fleksibel, pilihan filter yang melimpah, dan fungsi backtesting yang kuat, dapat disesuaikan agar sesuai dengan instrumen perdagangan yang berbeda. Oleh karena itu, ini adalah strategi perdagangan kuantitatif yang menarik dan menjanjikan yang layak dieksplorasi 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 banyak