Strategi pembalikan rata-rata bergerak ganda

Penulis:ChaoZhang, Tanggal: 2023-11-17 16:56:24
Tag:

img

Gambaran umum

Strategi Reversi Rata-rata Bergerak Ganda adalah strategi perdagangan reversi rata-rata jangka pendek yang khas. Strategi ini menghasilkan sinyal perdagangan dengan dua rata-rata bergerak dengan pengaturan parameter yang berbeda.

Logika Strategi

Strategi ini menggunakan dua rata-rata bergerak untuk menghasilkan sinyal perdagangan. MA pertama maopening digunakan untuk menentukan arah tren. MA kedua maclosing digunakan untuk menghasilkan sinyal perdagangan.

Ketika maopening naik, itu menunjukkan pasar saat ini berada dalam tren naik. Ketika maopening turun, itu menunjukkan pasar saat ini berada dalam tren turun. maclosing dikalikan dengan koefisien lebih besar dari 1 untuk membuatnya lebih sensitif untuk menghasilkan sinyal pembalikan dini.

Secara khusus, ketika maopening naik dan maclosing melintasi di bawah maopening, itu menunjukkan pembalikan tren. Strategi akan membuka posisi pendek. Ketika maopening turun dan maclosing melintasi di atas maopening, itu menunjukkan pembalikan tren. Strategi akan membuka posisi panjang.

Parameter strategi termasuk jenis MA, panjang, sumber data dll. Kinerja perdagangan dapat dioptimalkan dengan menyesuaikan parameter ini. Ada juga beberapa opsi yang dapat dikonfigurasi seperti aturan masuk, stop loss dll.

Analisis Keuntungan

Keuntungan utama dari Strategi Pembalikan Dual MA adalah:

  1. Sedikit drawdown, cocok untuk perdagangan jangka pendek. Rata-rata bergerak cepat dapat dengan cepat menangkap pembalikan jangka pendek dengan drawdown yang lebih kecil.

  2. Sederhana untuk diterapkan dan mudah dipahami.

  3. Sangat dapat dikonfigurasi dengan beberapa parameter yang dapat disesuaikan.

  4. Mudah untuk mengotomatisasi dengan aliran logika yang jelas. logika sederhana dan perdagangan frekuensi tinggi membuatnya sangat cocok untuk perdagangan otomatis.

  5. Risiko terkontrol dengan mekanisme stop loss. Stop loss bergerak atau nilai stop loss dapat membatasi kerugian perdagangan tunggal.

Analisis Risiko

Ada juga beberapa risiko dari strategi:

  1. Penundaan sinyal crossover MA. MA sendiri tertinggal di belakang harga. Crossover dapat terjadi setelah tren berbalik untuk beberapa waktu.

  2. Risiko perdagangan whipsaw. Tren terbalik dapat dengan cepat berbalik lagi, menyebabkan kerugian berturut-turut.

  3. Meskipun stop loss membatasi kerugian tunggal, stop loss berturut-turut masih dapat menyebabkan drawdown besar.

  4. Risiko overfitting: Optimasi parameter yang berlebihan dapat menyebabkan overfitting dan kinerja yang buruk dalam perdagangan langsung.

Solusinya meliputi:

  1. Optimalkan parameter untuk menemukan MAs yang lebih cepat.

  2. Tambahkan filter, seperti indikator volume dan volatilitas, untuk menghindari perdagangan whipsaw.

  3. Sesuaikan posisi stop loss untuk menurunkan probabilitas stop loss berturut-turut.

  4. Uji ketahanan set parameter untuk mengevaluasi risiko pemasangan berlebihan.

Arah Peningkatan

Strategi ini dapat dioptimalkan lebih lanjut dalam aspek berikut:

  1. Uji berbagai jenis MAs untuk menemukan yang lebih sensitif, seperti KAMA, ZLEMA dll.

  2. Optimalkan panjang MA untuk menemukan kombinasi optimal. Biasanya periode yang lebih pendek memiliki kinerja yang lebih baik.

  3. Uji sumber data yang berbeda, seperti harga dekat, harga median, harga tipikal dll.

  4. Tambahkan filter tren untuk menghindari sinyal pembalikan yang tidak sesuai, seperti Saluran Donchian.

  5. Tambahkan indikator lain untuk konfirmasi, seperti MACD, OBV dll.

  6. Meningkatkan mekanisme manajemen risiko, seperti memindahkan stop loss, kerugian maksimum akun dll.

  7. Optimasi portofolio untuk menemukan alokasi aset yang optimal.

  8. Uji ketahanan parameter untuk mengevaluasi risiko overfitting.

Kesimpulan

Dual MA Reversion adalah strategi perdagangan jangka pendek yang sederhana dan praktis. Ini cocok untuk menangkap pembalikan jangka pendek dengan perdagangan kuantitatif. Namun, risiko seperti perdagangan lag dan whipsaw ada. Strategi dapat ditingkatkan dengan mengoptimalkan parameter, menambahkan filter, meningkatkan kontrol risiko dll untuk mengembangkan strategi yang stabil dan efisien dengan kinerja perdagangan yang baik.


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

//@version=5
strategy(title = "hamster-bot MRS 2", overlay = true, default_qty_type = strategy.percent_of_equity, initial_capital = 100, default_qty_value = 100, pyramiding = 9, commission_value = 0.045, backtest_fill_limits_assumption = 1)
info_options = "Options"

on_close = input(false, title = "Entry on close", inline=info_options, group=info_options)
OFFS = input.int(0, minval = 0, maxval = 1, title = "| Offset View", inline=info_options, group=info_options)
trade_offset = input.int(0, minval = 0, maxval = 1, title = "Trade", inline=info_options, group=info_options)
use_kalman_filter = input.bool(false, title="Use Kalman filter", group=info_options)

//MA Opening
info_opening = "MA Opening"
maopeningtyp = input.string("SMA", title="Type", options=["SMA", "EMA", "TEMA", "DEMA", "ZLEMA", "WMA", "Hma", "Thma", "Ehma", "H", "L", "DMA"], title = "", inline=info_opening, group=info_opening)
maopeningsrc = input.source(ohlc4, title = "", inline=info_opening, group=info_opening)
maopeninglen = input.int(3, minval = 1, maxval = 200, title = "", inline=info_opening, group=info_opening)

//MA Closing
info_closing = "MA Closing"
maclosingtyp = input.string("SMA", title="Type", options=["SMA", "EMA", "TEMA", "DEMA", "ZLEMA", "WMA", "Hma", "Thma", "Ehma", "H", "L", "DMA"], title = "", inline=info_closing, group=info_closing)
maclosingsrc = input.source(ohlc4, title = "", inline=info_closing, group=info_closing)
maclosinglen = input.int(3, minval = 1, maxval = 200, title = "", inline=info_closing, group=info_closing)
maclosingmul = input.float(1, step = 0.005, title = "mul", inline=info_closing, group=info_closing)

long1on    = input(true, title = "", inline = "long1")
long1shift = input.float(0.96, step = 0.005, title = "Long", inline = "long1")
long1lot   = input.int(10, minval = 0, maxval = 10000, step = 10, title = "Lot 1", inline = "long1")
short1on    = input(true, title = "", inline = "short1")
short1shift = input.float(1.04, step = 0.005, title = "short", inline = "short1")
short1lot   = input.int(10, minval = 0, maxval = 10000, step = 10, title = "Lot 1", inline = "short1")
startTime = input(timestamp("01 Jan 2010 00:00 +0000"), "Start date", inline = "period")
finalTime = input(timestamp("31 Dec 2030 23:59 +0000"), "Final date", inline = "period")

HMA(_src, _length) =>  ta.wma(2 * ta.wma(_src, _length / 2) - ta.wma(_src, _length), math.round(math.sqrt(_length)))
EHMA(_src, _length) =>  ta.ema(2 * ta.ema(_src, _length / 2) - ta.ema(_src, _length), math.round(math.sqrt(_length)))
THMA(_src, _length) =>  ta.wma(ta.wma(_src,_length / 3) * 3 - ta.wma(_src, _length / 2) - ta.wma(_src, _length), _length)
tema(sec, length)=>
    tema1= ta.ema(sec, length)
    tema2= ta.ema(tema1, length)
    tema3= ta.ema(tema2, length)
    tema_r = 3*tema1-3*tema2+tema3
donchian(len) => math.avg(ta.lowest(len), ta.highest(len))
ATR_func(_src, _len)=>
    atrLow = low - ta.atr(_len)
    trailAtrLow = atrLow
    trailAtrLow := na(trailAtrLow[1]) ? trailAtrLow : atrLow >= trailAtrLow[1] ? atrLow : trailAtrLow[1]
    supportHit = _src <= trailAtrLow
    trailAtrLow := supportHit ? atrLow : trailAtrLow
    trailAtrLow
f_dema(src, len)=>
    EMA1 = ta.ema(src, len)
    EMA2 = ta.ema(EMA1, len)
    DEMA = (2*EMA1)-EMA2
f_zlema(src, period) =>
    lag = math.round((period - 1) / 2)
    ema_data = src + (src - src[lag])
    zl= ta.ema(ema_data, period)
f_kalman_filter(src) =>
    float value1= na
    float value2 = na
    value1 := 0.2 * (src - src[1]) + 0.8 * nz(value1[1])
    value2 := 0.1 * (ta.tr) + 0.8 * nz(value2[1])
    lambda = math.abs(value1 / value2)
    alpha = (-math.pow(lambda, 2) + math.sqrt(math.pow(lambda, 4) + 16 * math.pow(lambda, 2)))/8
    value3 = float(na)
    value3 := alpha * src + (1 - alpha) * nz(value3[1])
//SWITCH
ma_func(modeSwitch, src, len, use_k_f=true) =>
      modeSwitch == "SMA"   ? use_kalman_filter and use_k_f ? f_kalman_filter(ta.sma(src, len))  : ta.sma(src, len) :
      modeSwitch == "RMA"   ? use_kalman_filter and use_k_f ? f_kalman_filter(ta.rma(src, len))  : ta.rma(src, len) :
      modeSwitch == "EMA"   ? use_kalman_filter and use_k_f ? f_kalman_filter(ta.ema(src, len))  : ta.ema(src, len) :
      modeSwitch == "TEMA"  ? use_kalman_filter and use_k_f ? f_kalman_filter(tema(src, len))    : tema(src, len):
      modeSwitch == "DEMA"  ? use_kalman_filter and use_k_f ? f_kalman_filter(f_dema(src, len))  : f_dema(src, len):
      modeSwitch == "ZLEMA" ? use_kalman_filter and use_k_f ? f_kalman_filter(f_zlema(src, len)) : f_zlema(src, len):
      modeSwitch == "WMA"   ? use_kalman_filter and use_k_f ? f_kalman_filter(ta.wma(src, len))  : ta.wma(src, len):
      modeSwitch == "VWMA"  ? use_kalman_filter and use_k_f ? f_kalman_filter(ta.vwma(src, len)) : ta.vwma(src, len):
      modeSwitch == "Hma"   ? use_kalman_filter and use_k_f ? f_kalman_filter(HMA(src, len))     : HMA(src, len):
      modeSwitch == "Ehma"  ? use_kalman_filter and use_k_f ? f_kalman_filter(EHMA(src, len))    : EHMA(src, len):
      modeSwitch == "Thma"  ? use_kalman_filter and use_k_f ? f_kalman_filter(THMA(src, len/2))  : THMA(src, len/2):
      modeSwitch == "ATR"   ? use_kalman_filter and use_k_f ? f_kalman_filter(ATR_func(src, len)): ATR_func(src, len) :
      modeSwitch == "L"   ? use_kalman_filter and use_k_f ? f_kalman_filter(ta.lowest(len)): ta.lowest(len) :
      modeSwitch == "H"   ? use_kalman_filter and use_k_f ? f_kalman_filter(ta.highest(len)): ta.highest(len) :
      modeSwitch == "DMA"   ? donchian(len) : na

//Var
sum = 0.0
maopening = 0.0
maclosing = 0.0
os = maopeningsrc
cs = maclosingsrc
pos = strategy.position_size
p = 0.0
p := pos == 0 ? (strategy.equity / 100) / close : p[1]
truetime = true
loss = 0.0
maxloss = 0.0
equity = 0.0

//MA Opening
maopening := ma_func(maopeningtyp, maopeningsrc, maopeninglen)

//MA Closing
maclosing := ma_func(maclosingtyp, maclosingsrc, maclosinglen) * maclosingmul

long1 = long1on == false ? 0 : long1shift == 0 ? 0 : long1lot == 0 ? 0 : maopening == 0 ? 0 : maopening * long1shift
short1 = short1on == false ? 0 : short1shift == 0 ? 0 : short1lot == 0 ? 0 : maopening == 0 ? 0 : maopening * short1shift
//Colors
maopeningcol = maopening == 0 ? na : color.blue
maclosingcol = maclosing == 0 ? na : color.fuchsia
long1col = long1 == 0 ? na : color.green
short1col = short1 == 0 ? na : color.red
//Lines
plot(maopening, offset = OFFS, color = maopeningcol)
plot(maclosing, offset = OFFS, color = maclosingcol)
long1line = long1 == 0 ? close : long1
short1line = short1 == 0 ? close : short1
plot(long1line, offset = OFFS, color = long1col)
plot(short1line, offset = OFFS, color = short1col)

//Lots
lotlong1 = p * long1lot
lotshort1 = p * short1lot

//Entry
if maopening > 0 and maclosing > 0 and truetime
    //Long
    sum := 0
    strategy.entry("L", strategy.long, lotlong1, limit = on_close ? na : long1, when = long1 > 0 and pos <= sum and (on_close ? close <= long1[trade_offset] : true))
    sum := lotlong1

    //Short
    sum := 0
    pos := -1 * pos
    strategy.entry("S", strategy.short, lotshort1, limit = on_close ? na : short1, when = short1 > 0 and pos <= sum and (on_close ? close >= short1[trade_offset] : true))
    sum := lotshort1

strategy.exit("Exit", na, limit = maclosing)
if time > finalTime
    strategy.close_all()

Lebih banyak