Strategi pembalikan rata-rata bergerak ganda

Penulis:ChaoZhang, Tanggal: 2023-12-25 13:24:14
Tag:

img

Gambaran umum

Strategi pembalikan rata-rata bergerak ganda adalah strategi perdagangan kuantitatif yang memanfaatkan rata-rata bergerak ganda untuk mengidentifikasi tren jangka pendek dan jangka panjang. Strategi ini menggabungkan rata-rata bergerak sederhana (SMA) 10 hari dan SMA 200 hari untuk memanfaatkan penurunan jangka pendek dalam tren kenaikan jangka panjang yang mendasari.

Logika Strategi

Strategi pembalikan rata-rata bergerak ganda didasarkan pada asumsi berikut:

  1. SMA 200 hari mengidentifikasi tren jangka panjang yang berlaku di pasar. Ketika harga berada di atas garis 200 hari, itu menandakan bahwa pasar berada dalam tren kenaikan jangka panjang.

  2. SMA 10 hari menunjukkan penurunan harga jangka pendek. Ketika harga turun di bawah garis 10 hari, itu menunjukkan penurunan sementara telah terjadi.

  3. Dalam tren kenaikan pasar bull yang sedang berlangsung, setiap penurunan jangka pendek dapat dilihat sebagai peluang pembelian untuk secara efisien menangkap rebound naik.

Berdasarkan asumsi di atas, sinyal perdagangan dihasilkan sebagai berikut:

  1. Ketika harga penutupan melintasi SMA 200 hari dan secara bersamaan melintasi SMA 10 hari, ini memicu sinyal beli karena menunjukkan tren jangka panjang tetap positif tetapi penurunan jangka pendek telah terjadi.

  2. Jika harga naik kembali di atas SMA 10 hari saat berada di posisi panjang, tren jangka pendek telah berbalik sehingga posisi akan ditutup segera.

  3. Setiap kali terjadi penurunan besar (melampaui ambang batas yang telah ditentukan sebelumnya), hal ini memberikan kesempatan untuk membeli penurunan sebagai sinyal yang bertentangan.

Dengan desain ini, strategi ini bertujuan untuk secara efisien memanfaatkan snapback naik selama tren naik berkelanjutan sambil mengendalikan risiko menggunakan stop loss.

Keuntungan

Strategi pembalikan rata-rata bergerak ganda memiliki keuntungan utama berikut:

  1. Logika strategi adalah langsung dan mudah dimengerti.
  2. Filter rata-rata bergerak ganda secara efektif mengidentifikasi tren jangka pendek dan jangka panjang.
  3. Ini menawarkan efisiensi waktu yang baik dengan memanfaatkan pembalikan jangka pendek.
  4. Mekanisme stop loss internal mengontrol risiko pada posisi individu secara ketat.
  5. Parameterisasi yang fleksibel membuat strategi ini dapat diterapkan secara luas untuk indeks dan saham.

Risiko

Meskipun secara umum efektif, strategi ini memiliki keterbatasan berikut:

  1. Whipsaws dan sinyal palsu dapat terjadi jika pasar terikat kisaran.
  2. Mengandalkan hanya pada rata-rata bergerak memiliki keterbatasan akurasi sinyal.
  3. Metodologi stop loss tetap tidak fleksibel. Teknik stop loss lainnya dapat diuji.
  4. Parameter yang optimal harus dikalibrasi untuk pasar yang berbeda. pengaturan suboptimal mengurangi keandalan.

Peluang Peningkatan

Perbaikan lebih lanjut untuk strategi ini meliputi:

  1. Mencoba panjang rata-rata bergerak lainnya untuk menemukan kombinasi yang optimal.
  2. Menambahkan indikator pendukung untuk menghasilkan sinyal yang lebih dapat diandalkan misalnya volume, metrik volatilitas.
  3. Menjelajahi teknik stop loss lainnya seperti trailing stop loss, stop loss berbasis waktu.
  4. Membangun kemampuan adaptasi dalam aturan masuk dan parameter stop loss yang memungkinkan penyesuaian dengan perubahan dinamika pasar.
  5. Mengintegrasikan algoritma pembelajaran mesin untuk lebih mengoptimalkan parameter memanfaatkan lebih banyak data historis.

Kesimpulan

Singkatnya, Strategi Pembalikan Rata-rata Bergerak Ganda adalah pendekatan yang sangat praktis. Ini memungkinkan memudar mundur yang menguntungkan selama tren naik berkelanjutan menggunakan analisis rata-rata bergerak yang dipasangkan dengan stop loss. Ini juga menawarkan kemampuan deteksi rezim pasar dan kontrol risiko. Dengan peningkatan terus-menerus, strategi ini menawarkan potensi yang kuat untuk memberikan kinerja yang berbeda.


/*backtest
start: 2023-11-24 00:00:00
end: 2023-12-24 00:00:00
period: 1h
basePeriod: 15m
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/
// © Gold_D_Roger
//note: spreading 1 statement over multiple lines needs 1 apce + 1 tab | multi line function is 1 tab
//Recommended tickers: SPY (D), QQQ (D) and big indexes, AAPL (4H)

//@version=5
strategy("Davin's 10/200MA Pullback on SPY Strategy v2.0",
     overlay=true,
     initial_capital=10000,
     default_qty_type=strategy.percent_of_equity,
     default_qty_value=10, // 10% of equity on each trade
     commission_type=strategy.commission.cash_per_contract, 
     commission_value=0.1) //Insert your broker's rate, IB is 0.005USD or tiered

//Best parameters
// SPY D
// Stop loss 0.15
// commission of 0.005 USD using Interactive brokers
// Exit on lower close 
// Buy more when x% down --> 14%
// DO NOT include stop condition using MA crossover

// Get User Input
i_ma1           = input.int(title="MA Length 1", defval=200, step=10, group="Strategy Parameters", tooltip="Long-term MA 200")
i_ma2           = input.int(title="MA Length 2", defval=10, step=10, group="Strategy Parameters", tooltip="Short-term MA 10")
i_ma3           = input.int(title="MA Length 3", defval=50, step=1, group="Strategy Parameters", tooltip="MA for crossover signals`")
i_stopPercent   = input.float(title="Stop Loss Percent", defval=0.15, step=0.01, group="Strategy Parameters", tooltip="Hard stop loss of 10%")
i_startTime     = input(title="Start filter", defval=timestamp("01 Jan 2013 13:30 +0000"), group="Time filter", tooltip="Start date and time to begin")
i_endTime       = input(title="End filter", defval=timestamp("01 Jan 2099 19:30 +0000"), group="Time filter", tooltip="End date and time to stop")
i_lowerClose    = input.bool(title="Exit on lower close", defval=true, group="Strategy Parameters", tooltip="Wait for lower close after above 10SMA before exiting") // optimise exit strat, boolean type creates tickbox type inputs
i_contrarianBuyTheDip = input.bool(title="Buy whenever more than x% drawdown", defval=true, group="Strategy Parameters", tooltip="Buy the dip! Whenever x% or more drawdown on SPY")
i_contrarianTrigger = input.int(title="Trigger % drop to buy the dip", defval=14, step=1, group="Strategy Parameters", tooltip="% drop to trigger contrarian Buy the Dip!") 
//14% to be best for SPY 1D
//20% best for AMZN 1D
i_stopByCrossover_MA2_3 = input.bool(title="Include stop condition using MA crossover", defval=false, group="Strategy Parameters", tooltip="Sell when crossover of MA2/1 happens")

// Get indicator values
ma1 = ta.sma(close,i_ma1) //param 1
ma2 = ta.sma(close,i_ma2) //param 2
ma3 = ta.sma(close,i_ma3) //param 3
ma_9 = ta.ema(close,9) //param 2
ma_20 = ta.ema(close,20) //param 3

// Check filter(s)
f_dateFilter = true //make sure date entries are within acceptable range

// Highest price of the prev 52 days: https://www.tradingcode.net/tradingview/largest-maximum-value/#:~:text=()%20versus%20ta.-,highest(),max()%20and%20ta.
highest52 = ta.highest(high,52)
overall_change = ((highest52 - close[0]) / highest52) * 100

// Check buy/sell conditions
var float buyPrice = 0 //intialise buyPrice, this will change when we enter a trade ; float = decimal number data type 0.0
buyCondition  = (close > ma1 and close < ma2 and strategy.position_size == 0 and f_dateFilter) or (strategy.position_size == 0 and i_contrarianBuyTheDip==true and overall_change > i_contrarianTrigger and f_dateFilter) // higher than 200sma, lower than short term ma (pullback) + avoid pyramiding positions
sellCondition = close > ma2 and strategy.position_size > 0 and (not i_lowerClose or close < low[1])  //check if we already in trade + close above 10MA; 
// third condition: EITHER i_lowerClose not turned on OR closing price has to be < previous candle's LOW [1]

stopDistance  = strategy.position_size > 0 ? ((buyPrice - close)/close) : na // check if in trade > calc % drop dist from entry, if not na
stopPrice     = strategy.position_size > 0 ? (buyPrice - (buyPrice * i_stopPercent)) : na // calc SL price if in trade, if not, na
stopCondition = (strategy.position_size > 0 and stopDistance > i_stopPercent) or (strategy.position_size > 0 and (i_stopByCrossover_MA2_3==true and ma3 < ma1))


// Enter positions
if buyCondition 
    strategy.entry(id="Long", direction=strategy.long) //long only

    
if buyCondition[1] // if buyCondition is true prev candle
    buyPrice := open // entry price = current bar opening price

// Exit position
if sellCondition or stopCondition 
    strategy.close(id="Long", comment = "Exit" + (stopCondition ? "Stop loss=true" : "")) // if condition? "Value for true" : "value for false"
    buyPrice := na //reset buyPrice

// Plot
plot(buyPrice, color=color.lime, style=plot.style_linebr)
plot(stopPrice, color=color.red, style=plot.style_linebr, offset = -1)
plot(ma1, color=color.blue) //defval=200
plot(ma2, color=color.white) //defval=10
plot(ma3, color=color.yellow) // defval=50






Lebih banyak