Strategi crossover rata-rata bergerak untuk perdagangan dua arah

Penulis:ChaoZhang, Tanggal: 2023-12-12 11:26:54
Tag:

img

Gambaran umum

Strategi ini menghitung rata-rata bergerak dari periode yang berbeda dan mengeluarkan sinyal perdagangan ketika rata-rata bergerak periode yang lebih pendek melintasi atau melintasi di bawah rata-rata bergerak periode yang lebih lama.

Prinsip-prinsip

Strategi ini menilai tren pasar dan menghasilkan sinyal perdagangan berdasarkan persilangan antara rata-rata bergerak dari periode yang berbeda. Strategi ini menggunakan tiga garis rata-rata bergerak 8-periode, 13-periode dan 21-periode, di mana garis 8-periode adalah garis periode yang lebih pendek dan garis 21-periode adalah garis periode yang lebih panjang. Sinyal panjang dipicu ketika garis 8-periode melintasi garis 21-periode. Sinyal pendek dipicu ketika garis 8-periode melintasi di bawah garis 21-periode.

Dalam eksekusi perdagangan yang sebenarnya, strategi ini juga mencakup kondisi penyaringan untuk menghindari terjebak di pasar yang berbelit-belit. Ini hanya menempatkan pesanan ketika harga penutupan lebih tinggi (sinyal panjang) atau lebih rendah (sinyal pendek) daripada titik persilangan. Ini dapat secara efektif menyaring beberapa sinyal palsu.

Keuntungan

  1. Menerapkan aturan crossover rata-rata bergerak untuk melacak tren pasar secara efektif
  2. Menambahkan filter perdagangan untuk menghindari beberapa sinyal palsu dan terjebak
  3. Mendukung perdagangan dua arah untuk mendapatkan keuntungan di pasar bull dan bear
  4. Mencatatkan pergantian antara tingkat utama menggunakan rata-rata bergerak antar periode
  5. Logika sederhana dan jelas, mudah dipahami dan dioptimalkan

Risiko

  1. Dapat gagal atau menghasilkan sinyal palsu yang berlebihan di pasar yang sangat volatile
  2. Tidak dapat menilai ketika harga bergerak ke samping, kehilangan peluang
  3. Crossover antar periode memiliki keterlambatan, mungkin tidak tepat waktu menangkap perubahan tren jangka pendek
  4. Tidak mempertimbangkan volatilitas harga, parameter perlu disesuaikan untuk tingkat volatilitas yang berbeda
  5. Tidak ada stop loss atau mengambil keuntungan, risiko kerugian tak terbatas

Solusi untuk Risiko

  1. Menggabungkan indikator lain untuk menilai pasar, menghindari dampak volatilitas
  2. Periode rata-rata bergerak yang lebih rendah untuk sensitivitas yang lebih tinggi
  3. Tambahkan stop loss dan take profit untuk mengendalikan risiko dan drawdown

Arahan Optimasi

  1. Menggabungkan indikator lain seperti MACD dan KDJ untuk meningkatkan efektivitas
  2. Pengaruh pengujian dari pengaturan parameter yang berbeda pada kinerja strategi secara keseluruhan
  3. Menetapkan parameter adaptatif berdasarkan jenis pasar dan tingkat volatilitas
  4. Mengoptimalkan metode perhitungan rata-rata bergerak menggunakan DEMA, ZLEMA dll.
  5. Tambahkan stop loss dan mengambil keuntungan logika
  6. Mengoptimalkan metrik backtesting kuantum untuk menentukan parameter terbaik

Kesimpulan

Strategi ini memiliki logika yang jelas menggunakan crossover rata-rata bergerak sederhana untuk menentukan hubungan antara tren jangka pendek dan jangka panjang dan menangkap peluang rotasi. Ini mendukung perdagangan dua arah dan mudah dipahami dan dioptimalkan.


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

//@version=3
//Converted to strategy by shawnteoh

strategy(title = "MA Emperor insiliconot Strategy" , overlay=true, pyramiding=1, precision=8)
strat_dir_input = input(title="Strategy Direction", defval="long", options=["long", "short", "all"])
strat_dir_value = strat_dir_input == "long" ? strategy.direction.long : strat_dir_input == "short" ? strategy.direction.short : strategy.direction.all
strategy.risk.allow_entry_in(strat_dir_value)

// Testing start dates
testStartYear = input(2020, "Backtest Start Year")
testStartMonth = input(1, "Backtest Start Month")
testStartDay = input(1, "Backtest Start Day")
testPeriodStart = timestamp(testStartYear,testStartMonth,testStartDay,0,0)
//Stop date if you want to use a specific range of dates
testStopYear = input(2030, "Backtest Stop Year")
testStopMonth = input(12, "Backtest Stop Month")
testStopDay = input(30, "Backtest Stop Day")
testPeriodStop = timestamp(testStopYear,testStopMonth,testStopDay,0,0)
// Order size
orderQty = input(1, "Order quantity", type = float)
// Plot indicator
plotInd = input(false, "Plot indicators?", type = bool)

testPeriod() =>
    time >= testPeriodStart and time <= testPeriodStop ? true : false

haClose = close
haOpen  = open
haHigh  = high
haLow   = low 

haClose := (open + high + low + close) / 4
haOpen  := (nz(haOpen[1]) + nz(haClose[1])) / 2
haHigh  := max(high, max(haOpen, haClose))
haLow   := min(low , min(haOpen, haClose))

ssrc = close
ha = false

o = ha ? haOpen : open
c = ha ? haClose : close
h = ha ? haHigh : high
l = ha ? haLow : low

ssrc := ssrc == close ? ha ? haClose : c : ssrc
ssrc := ssrc == open ? ha ? haOpen : o : ssrc
ssrc := ssrc == high ? ha ? haHigh : h : ssrc
ssrc := ssrc == low ? ha ? haLow : l : ssrc
ssrc := ssrc == hl2 ? ha ? (haHigh + haLow) / 2 : hl2 : ssrc
ssrc := ssrc == hlc3 ? ha ? (haHigh + haLow + haClose) / 3 : hlc3 : ssrc
ssrc := ssrc == ohlc4 ? ha ? (haHigh + haLow + haClose+ haOpen) / 4 : ohlc4 : ssrc

type = input(defval = "EMA", title = "Type", options = ["Butterworth_2Pole", "DEMA", "EMA", "Gaussian", "Geometric_Mean", "LowPass", "McGuinley", "SMA", "Sine_WMA", "Smoothed_MA", "Super_Smoother",  "Triangular_MA", "Wilders", "Zero_Lag"])

len1=input(8, title ="MA 1")
len2=input(13, title = "MA 2") 
len3=input(21, title = "MA 3")
len4=input(55, title = "MA 4")
len5=input(89, title = "MA 5")
lenrib=input(120, title = "IB")
lenrib2=input(121, title = "2B")
lenrib3=input(200, title = "21b")
lenrib4=input(221, title = "22b")

onOff1  = input(defval=true, title="Enable 1")
onOff2  = input(defval=true, title="Enable 2")
onOff3  = input(defval=true, title="Enable 3")
onOff4  = input(defval=false, title="Enable 4")
onOff5  = input(defval=false, title="Enable 5")
onOff6  = input(defval=false, title="Enable 6")
onOff7  = input(defval=false, title="Enable 7")
onOff8  = input(defval=false, title="Enable x")
onOff9  = input(defval=false, title="Enable x")


gauss_poles = input(3, "*** Gaussian poles ***",  minval = 1, maxval = 14) 
linew = 2
shapes = false

 
variant_supersmoother(src,len) =>
    Pi = 2 * asin(1)
    a1 = exp(-1.414* Pi / len)
    b1 = 2*a1*cos(1.414* Pi / len)
    c2 = b1
    c3 = (-a1)*a1
    c1 = 1 - c2 - c3
    v9 = 0.0
    v9 := c1*(src + nz(src[1])) / 2 + c2*nz(v9[1]) + c3*nz(v9[2])
    v9
    
variant_smoothed(src,len) =>
    v5 = 0.0
    v5 := na(v5[1]) ? sma(src, len) : (v5[1] * (len - 1) + src) / len
    v5

variant_zerolagema(src, len) =>
    price = src
    l = (len - 1) / 2
    d = (price + (price - price[l]))
    z = ema(d, len)
    z
    
variant_doubleema(src,len) =>
    v2 = ema(src, len)
    v6 = 2 * v2 - ema(v2, len)
    v6

variant_WiMA(src, length) =>
    MA_s= nz(src)
    MA_s:=(src + nz(MA_s[1] * (length-1)))/length
    MA_s
    
fact(num)=>
    a = 1
    nn = num <= 1 ? 1 : num
    for i = 1 to nn
        a := a * i
    a
    
getPoles(f, Poles, alfa)=>
    filt = f
    sign = 1
    results = 0 + n//tv series spoofing
    for r = 1 to max(min(Poles, n),1)
	    mult  = fact(Poles) / (fact(Poles - r) * fact(r))
	    matPo = pow(1 - alfa, r)
        prev  = nz(filt[r-1],0)
        sum   =  sign * mult * matPo * prev
        results := results + sum
        sign  := sign * -1
    results := results - n
    results
    
variant_gauss(Price, Lag, Poles)=>
    Pi = 2 * asin(1)
    beta = (1 - cos(2 * Pi / Lag)) / ( pow (sqrt(2), 2.0 / Poles) - 1)
    alfa = -beta + sqrt(beta * beta +  2 * beta)
    pre = nz(Price, 0) * pow(alfa, Poles) 
    filter = pre
    result = n > 0 ?  getPoles(nz(filter[1]), Poles, alfa) : 0
    filter := pre + result

variant_mg(src, len)=>
    mg = 0.0
    mg := na(mg[1]) ? ema(src, len) : mg[1] + (src - mg[1]) / (len * pow(src/mg[1], 4))
    mg
    
variant_sinewma(src, length) =>
    PI = 2 * asin(1)
    sum = 0.0
    weightSum = 0.0
    for i = 0 to length - 1
        weight = sin(i * PI / (length + 1))
        sum := sum + nz(src[i]) * weight
        weightSum := weightSum + weight
    sinewma = sum / weightSum
    sinewma
    
variant_geoMean(price, per)=>
    gmean = pow(price, 1.0/per)
    gx = for i = 1 to per-1
        gmean := gmean * pow(price[i], 1.0/per)
        gmean
    ggx = n > per? gx : price    
    ggx


variant_butt2pole(pr, p1)=>
    Pi = 2 * asin(1)
    DTR = Pi / 180    
    a1 = exp(-sqrt(2) * Pi / p1)
    b1 = 2 * a1 * cos(DTR * (sqrt(2) * 180 / p1))
    cf1 = (1 - b1 + a1 * a1) / 4
    cf2 = b1
    cf3 = -a1 * a1
    butt_filt = pr
    butt_filt := cf1 * (pr + 2 * nz(pr[1]) + nz(pr[2])) + cf2 * nz(butt_filt[1]) + cf3 * nz(butt_filt[2])

variant_lowPass(src, len)=>
    LP = src
    sr = src
    a = 2.0 / (1.0 + len)
    LP := (a - 0.25 * a * a) * sr + 0.5 * a * a * nz(sr[1]) - (a - 0.75 * a * a) * nz(sr[2]) + 2.0 * (1.0 - a) * nz(LP[1]) - (1.0 - a) * (1.0 - a) * nz(LP[2])
    LP


variant_sma(src, len) =>
    sum = 0.0
    for i = 0 to len - 1
        sum := sum + src[i] / len
    sum

variant_trima(src, length) =>
    len = ceil((length + 1) * 0.5)
    trima =  sum(sma(src, len), len)/len
    trima
 
 
    
variant(type, src, len) =>
      type=="EMA"   ? ema(src, len) : 
      type=="LowPass" ? variant_lowPass(src, len) :  
      type=="Linreg"  ? linreg(src, len, 0) : 
      type=="Gaussian"  ? variant_gauss(src, len, gauss_poles) :
      type=="Sine_WMA"  ? variant_sinewma(src, len) :
      
      type=="Geometric_Mean"  ? variant_geoMean(src, len) :
      
      type=="Butterworth_2Pole" ? variant_butt2pole(src, len) : 
      type=="Smoothed_MA"  ? variant_smoothed(src, len) :
      type=="Triangular_MA"  ? variant_trima(src, len) : 
      type=="McGuinley" ? variant_mg(src, len) : 
      type=="DEMA"  ? variant_doubleema(src, len):  
      type=="Super_Smoother"  ? variant_supersmoother(src, len) : 
      type=="Zero_Lag"  ? variant_zerolagema(src, len) :  
      type=="Wilders"? variant_WiMA(src, len) : variant_sma(src, len)


c1=#44E2D6
c2=#DDD10D
c3=#0AA368
c4=#E0670E
c5=#AB40B2

cRed = #F93A00


ma1 =  variant(type, ssrc, len1)
ma2 =  variant(type, ssrc, len2)
ma3 =  variant(type, ssrc, len3)
ma4 =  variant(type, ssrc, len4)
ma5 =  variant(type, ssrc, len5)
ma6 =  variant(type, ssrc, lenrib)
ma7 =  variant(type, ssrc, lenrib2)
ma8 =  variant(type, ssrc, lenrib3)
ma9 =  variant(type, ssrc, lenrib4)

col1 = c1
col2 = c2
col3 = c3
col4 = c4
col5 = c5

p1 = plot(onOff1 ? ma1 : na, title = "MA 1",  color = col1,  linewidth = linew, style = linebr)
p2 = plot(onOff2 ? ma2 : na, title = "MA 2",  color = col2,  linewidth = linew, style = linebr)
p3 = plot(onOff3 ? ma3 : na, title = "MA 3",  color = col3,  linewidth = linew, style = linebr)
p4 = plot(onOff4 ? ma4 : na, title = "MA 4",  color = col4,  linewidth = linew, style = linebr)
p5 = plot(onOff5 ? ma5 : na, title = "MA 5",  color = col5,  linewidth = linew, style = linebr)
p6 = plot(onOff6 ? ma6 : na, title = "MA 6",  color = col5,  linewidth = linew, style = linebr)
p7 = plot(onOff7 ? ma7 : na, title = "MA 7",  color = col5,  linewidth = linew, style = linebr)
p8 = plot(onOff8 ? ma8 : na, title = "MA 8",  color = col5,  linewidth = linew, style = linebr)
p9 = plot(onOff9 ? ma9 : na, title = "MA 9",  color = col5,  linewidth = linew, style = linebr)

longCond = crossover(ma2, ma3)
if longCond and testPeriod()
    strategy.entry("buy", strategy.long, qty = orderQty, when = open > ma2[1])

shortCond = crossunder(ma2, ma3)
if shortCond and testPeriod()
    strategy.entry("sell", strategy.short, qty = orderQty, when = open < ma2[1])

plotshape(series=plotInd? longCond : na, title="P", style=shape.triangleup, location=location.belowbar, color=green, text="P", size=size.small)   
plotshape(series=plotInd? shortCond : na, title="N", style=shape.triangledown, location=location.abovebar, color=red, text="N", size=size.small)


Lebih banyak