Strategi pembalikan purata bergerak berganda

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

img

Ringkasan

Strategi pembalikan purata bergerak berganda adalah strategi perdagangan pembalikan purata jangka pendek yang tipikal. Strategi ini menghasilkan isyarat perdagangan oleh dua purata bergerak dengan tetapan parameter yang berbeza. Ia bertujuan untuk memperoleh keuntungan apabila pembalikan trend berlaku.

Logika Strategi

Strategi ini menggunakan dua purata bergerak untuk menjana isyarat perdagangan. MA pertama maopening digunakan untuk menentukan arah trend. MA kedua maclosing digunakan untuk menjana isyarat perdagangan.

Apabila maopening naik, ia menunjukkan pasaran semasa berada dalam trend menaik. Apabila maopening turun, ia menunjukkan pasaran semasa berada dalam trend menurun. maclosing dikalikan dengan pekali yang lebih besar daripada 1 untuk menjadikannya lebih sensitif untuk menjana isyarat pembalikan awal.

Secara khusus, apabila maopening naik dan maclosing melintasi di bawah maopening, ia menunjukkan pembalikan trend. Strategi akan membuka kedudukan pendek. Apabila maopening turun dan maclosing melintasi di atas maopening, ia menunjukkan pembalikan trend. Strategi akan membuka kedudukan panjang.

Parameter strategi termasuk jenis MA, panjang, sumber data dan lain-lain. Prestasi perdagangan boleh dioptimumkan dengan menyesuaikan parameter ini.

Analisis Kelebihan

Kelebihan utama Strategi Pembalikan MA Berganda adalah:

  1. Sedikit drawdown, sesuai untuk perdagangan jangka pendek. purata bergerak pantas boleh dengan cepat menangkap pembalikan jangka pendek dengan drawdown yang lebih kecil.

  2. Sederhana untuk dilaksanakan dan mudah difahami. persilangan dua MA menghasilkan isyarat perdagangan yang jelas.

  3. Sangat boleh dikonfigurasi dengan pelbagai parameter yang boleh diselaraskan.

  4. Mudah untuk automatik dengan aliran logik yang jelas. Logik yang mudah dan perdagangan frekuensi tinggi menjadikannya sangat sesuai untuk perdagangan automatik.

  5. Risiko yang boleh dikawal dengan mekanisme stop loss.

Analisis Risiko

Terdapat juga beberapa risiko strategi:

  1. Peninggalan isyarat persilangan MA. MA sendiri ketinggalan harga. Persalinan mungkin berlaku selepas trend telah berbalik untuk beberapa waktu.

  2. Risiko perdagangan whipsaw. Trend yang terbalik boleh dengan cepat berbalik lagi, menyebabkan kerugian berturut-turut.

  3. Walaupun stop loss mengehadkan kerugian tunggal, stop loss berturut-turut masih boleh membawa kepada pengeluaran besar.

  4. Risiko overfitting: pengoptimuman parameter yang berlebihan boleh membawa kepada overfitting dan prestasi yang buruk dalam perdagangan langsung.

Penyelesaian termasuk:

  1. Mengoptimumkan parameter untuk mencari MAs yang lebih cepat.

  2. Tambah penapis, seperti indikator jumlah dan turun naik, untuk mengelakkan perdagangan whipsaw.

  3. Sesuaikan kedudukan stop loss untuk mengurangkan kebarangkalian stop loss berturut-turut.

  4. Ujian ketahanan set parameter untuk menilai risiko pemasangan berlebihan.

Arahan Penambahbaikan

Strategi ini boleh dioptimumkan lagi dalam aspek berikut:

  1. Uji pelbagai jenis MA untuk mencari yang lebih sensitif, seperti KAMA, ZLEMA dll.

  2. Mengoptimumkan panjang MA untuk mencari kombinasi optimum. Biasanya tempoh yang lebih pendek mempunyai prestasi yang lebih baik.

  3. Uji sumber data yang berbeza, seperti harga dekat, harga median, harga biasa dan lain-lain.

  4. Tambah penapis trend untuk mengelakkan isyarat pembalikan yang tidak sesuai, seperti Saluran Donchian.

  5. Tambah penunjuk lain untuk pengesahan, seperti MACD, OBV dll.

  6. Meningkatkan mekanisme pengurusan risiko, seperti memindahkan stop loss, kerugian maksimum akaun dan lain-lain.

  7. Pengoptimuman portfolio untuk mencari peruntukan aset yang optimum.

  8. Ujian ketahanan parameter untuk menilai risiko pemasangan berlebihan.

Kesimpulan

Dual MA Reversion adalah strategi perdagangan jangka pendek yang mudah dan praktikal. Ia sesuai untuk menangkap pembalikan jangka pendek dengan perdagangan kuantitatif. Walau bagaimanapun, terdapat risiko seperti perdagangan lag dan whipsaw. Strategi ini boleh dipertingkatkan dengan mengoptimumkan parameter, menambah penapis, meningkatkan kawalan risiko dan lain-lain untuk mengembangkan strategi yang stabil dan cekap dengan prestasi perdagangan sebenar 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 lanjut