Strategi dagangan kuantitatif K-line berayun


Tarikh penciptaan: 2023-09-26 20:05:55 Akhirnya diubah suai: 2023-09-26 20:05:55
Salin: 0 Bilangan klik: 724
1
fokus pada
1617
Pengikut

Gambaran keseluruhan

Strategi ini adalah strategi momentum berasaskan indikator, menggunakan penunjuk penunjuk oscillators seperti RSI, Stoch, MACD untuk membina isyarat perdagangan strategi. Gagasan utama strategi ini adalah menggunakan penunjuk untuk mengenal pasti arah trend ketika harga bergolak, dan masuk berdasarkan isyarat indikator.

Prinsip Strategi

Strategi ini mula-mula memanggil fungsi f_getOscilatorValues untuk mendapatkan nilai-nilai indikator oscillators yang berbeza, termasuk RSI, Stoch, MACD dan sebagainya. Kemudian, dengan fungsi f_getSupertrend untuk mengira nilai-nilai indikator overtrend yang tertunda, untuk mengesan stop loss.

Selepas mengira penunjuk, strategi akan memanggil fungsi f_getBuySellStops, yang akan mengira titik masuk dan titik berhenti berdasarkan nilai penunjuk. Secara khusus, ia akan mengira penunjuk ATR, dan mengambil ATR kali ganda dengan pekali berhenti sebagai titik masuk dan ATR kali ganda dengan pekali berhenti sebagai titik berhenti.

Selepas itu, strategi akan menilai arah entiti garis K, jika garis K naik, digambar dengan warna hijau, dan garis K turun digambar dengan warna merah. Selepas menggambar garis K dan penunjuk, strategi akan menentukan sama ada ia memenuhi syarat masuk. Syarat masuk adalah apabila penunjuk menunjukkan overbuy, harga melakukan lebih banyak apabila ia melangkau; apabila penunjuk menunjukkan oversold, harga melangkau apabila ia melangkau kosong.

Selepas masuk, stop loss akan dilacak, dan stop loss yang dilacak adalah atas atau bawah landasan, mana yang lebih dekat. Apabila stop loss telah dicetuskan, ia akan meratakan. Apabila harga mencapai stop loss, ia akan berhenti.

Analisis kelebihan strategi

Strategi ini mempunyai kelebihan berikut:

  1. Penggunaan penunjuk pengayun untuk mengenal pasti arah trend, dapat menangkap peluang pembalikan garis pendek pasaran tepat pada masanya.

  2. Menggunakan strategi penangguhan kerugian yang lebih lama, anda boleh menghentikan kerugian sebelum kerugian berkembang, dan mengehadkan kerugian tunggal.

  3. Berdasarkan pengukuran risiko yang dikira oleh ATR, kedudukan boleh disesuaikan secara dinamik.

  4. Penapisan digabungkan dengan garis purata berkala yang tinggi untuk mengelakkan terikat.

  5. Strategi penangguhan sebahagian untuk mengekalkan keuntungan dan mengunci sebahagian daripada keuntungan.

  6. Strategi yang mudah difahami dan mudah diimplementasikan, sesuai untuk pemula dalam perdagangan kuantitatif.

Analisis risiko strategi

Strategi ini mempunyai beberapa risiko:

  1. Penunjuk oscillators mempunyai masalah ketinggalan, yang boleh menyebabkan isyarat masuk terlambat, isyarat keluar lebih awal. Ia boleh dioptimumkan dengan menyesuaikan parameter penunjuk, atau menambahkan penilaian tambahan penunjuk trend following.

  2. Titik hentian yang hampir, mungkin akan dirobohkan oleh hentian hentian. Anda boleh meluaskan julat hentian anda dengan betul, atau menggunakan strategi hentian dinamik seperti Hentian Chandelier.

  3. Selepas penutupan sebahagiannya, kedudukan yang tersisa mungkin akan ditutup. Anda boleh mengurangkan peratusan penutupan sebahagiannya, meninggalkan ruang.

  4. Risiko penyesuaian data pengesanan. Perlu diperiksa berulang kali di pasaran yang berbeza untuk mengelakkan penyesuaian berlebihan.

  5. Garis purata kitaran tinggi juga mungkin tidak berfungsi sebagai syarat penapis. Kaedah seperti klasifikasi trend harus digunakan untuk membantu menentukan pergerakan kitaran besar.

Arah pengoptimuman strategi

Strategi ini boleh dioptimumkan dalam beberapa aspek:

  1. Uji kombinasi parameter untuk pelbagai indikator osilator, pilih kombinasi yang dapat memberikan isyarat kualiti yang lebih baik, seperti indikator Sttoch untuk garis K cepat.

  2. Cuba ubah penangguhan sebahagian menjadi penangguhan bergerak, dan setkan kedudukan penangguhan mengikut ATR atau purata bergerak.

  3. Algoritma pembelajaran mesin ditambah untuk menilai trend kitaran besar, menggantikan penapisan garisan purata kitaran tinggi, meningkatkan ketepatan penilaian.

  4. Menambah penunjuk tenaga sebagai syarat penapisan kemasukan untuk mengelakkan pertukaran balik yang tidak perlu.

  5. Integrasi dan pengoptimuman berat untuk memilih kombinasi yang paling sesuai untuk varieti semasa.

  6. Menambah modul kawalan angin pembelajaran mesin, pengoptimuman dinamik untuk kedudukan berhenti, kedudukan berhenti, dan kedudukan.

  7. Menambah isyarat dagangan dengan penarikan triangle atau penarikan berjangka, memanfaatkan perbezaan harga antara niaga hadapan dan tunai.

ringkaskan

Strategi keseluruhan adalah strategi yang sangat sesuai untuk belajar pemula perdagangan kuantitatif, idea yang jelas, titik-titik penting berdasarkan analisis penunjuk dan kawalan risiko. Tetapi masih perlu untuk mengoptimumkan parameter dan mengelakkan risiko untuk mendapatkan pulangan yang stabil. Di samping itu, anda boleh meningkatkan strategi dari aspek trend penilaian, pengoptimuman stop loss, pembelajaran bersepadu, dan sebagainya.

Kod sumber strategi
/*backtest
start: 2023-08-26 00:00:00
end: 2023-09-25 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/
// © HeWhoMustNotBeNamed

//@version=4
strategy("Oscilator candles - strategy", overlay=false, initial_capital = 1000, default_qty_type = strategy.percent_of_equity, default_qty_value = 100, commission_type = strategy.commission.percent, pyramiding = 1, commission_value = 0.01, calc_on_order_fills = true)

oscilatorType = input(title="Oscliator Type", defval="stoch", options=["rsi", "stoch", "cog", "macd", "tsi", "cci", "cmo", "mfi"])
length = input(3)
shortlength = input(3)
longlength = input(9)

showSupertrend = input(true)
AtrMAType = input(title="Moving Average Type", defval="rma", options=["ema", "sma", "hma", "rma", "vwma", "wma"])
AtrLength = input(30, step=10)
stopMultiplier  = input(4)
targetMultiplier  = input(3)
wicks = input(true)
considerWicksForDelayByStep = input(false)
colorByPreviousClose = input(true)

useHTFPivot = input(false)
resolution = input("12M", type=input.resolution)
HTFMultiplier = input(4, title="Higher Timeframe multiplier (Used when resolution is set to Same as Symbol)", minval=2, step=1)
PivotLength = input(2, step=1)

tradeDirection = input(title="Trade Direction", defval=strategy.direction.long, options=[strategy.direction.all, strategy.direction.long, strategy.direction.short])
i_startTime = input(defval = timestamp("01 Jan 2010 00:00 +0000"), title = "Backtest Start Time", type = input.time)
i_endTime = input(defval = timestamp("01 Jan 2099 00:00 +0000"), title = "Backtest End Time", type = input.time)
inDateRange = true

f_getOscilatorValues(oscilatorType, length, shortlength, longlength)=>
    oOpen = rsi(open, length)
    oClose = rsi(close, length)
    oHigh = rsi(high, length)
    oLow = rsi(low, length)
    if(oscilatorType == "tsi")
        oOpen := tsi(open, shortlength, longlength)
        oClose := tsi(close, shortlength, longlength)
        oHigh := tsi(high, shortlength, longlength)
        oLow := tsi(low, shortlength, longlength)
    if(oscilatorType == "stoch")
        oOpen := stoch(open, longlength, shortlength, length)
        oClose := stoch(close, longlength, shortlength, length)
        oHigh := stoch(high, longlength, shortlength, length)
        oLow := stoch(low, longlength, shortlength, length)
    if(oscilatorType == "cci")
        oOpen := cci(open, length)
        oClose := cci(close, length)
        oHigh := cci(high, length)
        oLow := cci(low, length)
    if(oscilatorType == "cog")
        oOpen := cog(open, length)
        oClose := cog(close, length)
        oHigh := cog(high, length)
        oLow := cog(low, length)
    if(oscilatorType == "cmo")
        oOpen := cmo(open, length)
        oClose := cmo(close, length)
        oHigh := cmo(high, length)
        oLow := cmo(low, length)
    if(oscilatorType == "mfi")
        oOpen := mfi(open, length)
        oClose := mfi(close, length)
        oHigh := mfi(high, length)
        oLow := mfi(low, length)
    if(oscilatorType == "macd")
        [macdLineOpen, signalLineOpen, histLineOpen] = macd(open, shortlength, longlength, length)
        [macdLineClose, signalLineClose, histLineClose] = macd(close, shortlength, longlength, length)
        [macdLineHigh, signalLineHigh, histLineHigh] = macd(high, shortlength, longlength, length)
        [macdLineLow, signalLineLow, histLineLow] = macd(low, shortlength, longlength, length)
        oOpen := macdLineOpen
        oClose := macdLineClose
        oHigh := macdLineHigh
        oLow := macdLineLow
    [oOpen, oClose, oHigh, oLow]

f_getMovingAverage(source, MAType, length)=>
    ma = sma(source, length)
    if(MAType == "ema")
        ma := ema(source,length)
    if(MAType == "hma")
        ma := hma(source,length)
    if(MAType == "rma")
        ma := rma(source,length)
    if(MAType == "vwma")
        ma := vwma(source,length)
    if(MAType == "wma")
        ma := wma(source,length)
    ma

f_getSupertrend(oOpen, oClose, oHigh, oLow, AtrMAType, AtrLength, stopMultiplier, wicks)=>
    truerange = max(oHigh, oClose[1]) - min(oLow, oClose[1])
    
    averagetruerange = f_getMovingAverage(truerange, AtrMAType, AtrLength)
    atr = averagetruerange * stopMultiplier

    longStop = oClose - atr
    longStopPrev = nz(longStop[1], longStop)
    longStop := (wicks ? oLow[1] : oClose[1]) > longStopPrev ? max(longStop, longStopPrev) : longStop
    
    shortStop = oClose + atr
    shortStopPrev = nz(shortStop[1], shortStop)
    shortStop := (wicks ? oHigh[1] : oClose[1]) < shortStopPrev ? min(shortStop, shortStopPrev) : shortStop
    
    dir = 1
    dir := nz(dir[1], dir)
    dir := dir == -1 and (wicks ? oHigh : oClose) > shortStopPrev ? 1 : dir == 1 and (wicks ? oLow : oClose) < longStopPrev ? -1 : dir
    
    trailingStop = dir == 1? longStop : shortStop
    
    [dir, trailingStop]


f_getBuySellStops(oOpen, oClose, oHigh, oLow, AtrMAType, AtrLength, considerWicks, considerWicksForDelayByStep, stopMultiplier, targetMultiplier)=>
    barState = 0
    source = oClose
    
    truerange = max(oHigh, oClose[1]) - min(oLow, oClose[1])
    
    atr = f_getMovingAverage(truerange, AtrMAType, AtrLength)

    buyStop = source - atr * stopMultiplier
    sellStop = source + atr * stopMultiplier
    buyStopDerived = buyStop
    sellStopDerived = sellStop
    highTarget = considerWicks ? oHigh : source
    lowTarget = considerWicks ? oLow : source
    
    highTargetDelayByStep = considerWicksForDelayByStep ? oHigh : source
    lowTargetDelayByStep = considerWicksForDelayByStep ? oLow : source
    
    barState := highTarget > sellStopDerived[1] ? 1 : lowTarget < buyStopDerived[1] ? -1 : nz(barState[1],0)
    
    buyMultiplier = (barState == 1)? stopMultiplier : targetMultiplier
    sellMultiplier = (barState == -1)? stopMultiplier : targetMultiplier
    buyStop := source - atr * buyMultiplier
    sellStop := source + atr * sellMultiplier
    buyStop := barState == 1? max(buyStop, buyStop[1]) : barState == -1? min(buyStop, buyStop[1]) : buyStop
    sellStop := barState == 1? max(sellStop, sellStop[1]) : barState == -1? min(sellStop, sellStop[1]) : sellStop
    
    buyStopDerived := buyStop
    sellStopDerived := sellStop
    
    buyStopDerived := highTargetDelayByStep < sellStopDerived[1] and lowTargetDelayByStep > buyStopDerived[1] ? buyStopDerived[1] : buyStopDerived
    sellStopDerived := highTargetDelayByStep < sellStopDerived[1] and lowTargetDelayByStep > buyStopDerived[1] ? sellStopDerived[1] : sellStopDerived

    [buyStopDerived, sellStopDerived, barState]


f_secureSecurity(_symbol, _res, _src) => security(_symbol, _res, _src[1], lookahead = barmerge.lookahead_on, gaps=barmerge.gaps_off)

f_multiple_resolution(HTFMultiplier) => 
    target_Res_In_Min = timeframe.multiplier * HTFMultiplier * (
      timeframe.isseconds   ? 1. / 60. :
      timeframe.isminutes   ? 1. :
      timeframe.isdaily     ? 1440. :
      timeframe.isweekly    ? 7. * 24. * 60. :
      timeframe.ismonthly   ? 30.417 * 24. * 60. : na)

    target_Res_In_Min     <= 0.0417       ? "1S"  :
      target_Res_In_Min   <= 0.167        ? "5S"  :
      target_Res_In_Min   <= 0.376        ? "15S" :
      target_Res_In_Min   <= 0.751        ? "30S" :
      target_Res_In_Min   <= 1440         ? tostring(round(target_Res_In_Min)) :
      tostring(round(min(target_Res_In_Min / 1440, 365))) + "D"
    
f_getPivotHighLow(oOpen, oClose, oHigh, oLow, HTFMultiplier, resolution, PivotLength)=>
    derivedResolution = resolution == ""? f_multiple_resolution(HTFMultiplier) : resolution
    HTFHigh = f_secureSecurity(syminfo.tickerid, derivedResolution, oHigh)
    HTFLow = f_secureSecurity(syminfo.tickerid, derivedResolution, oLow)
    CLOSEprev = f_secureSecurity(syminfo.tickerid, derivedResolution, oClose)
    pivothi = pivothigh(HTFHigh, PivotLength, PivotLength)
    pivotlo = pivotlow(HTFLow, PivotLength, PivotLength)
    pivothi := na(pivothi)? nz(pivothi[1]) : pivothi
    pivotlo := na(pivotlo)? nz(pivotlo[1]) : pivotlo
    [pivothi, pivotlo]
    
[oOpen, oClose, oHigh, oLow] = f_getOscilatorValues(oscilatorType, length, shortlength, longlength)
[dir, trailingStop] = f_getSupertrend(oOpen, oClose, oHigh, oLow, AtrMAType, AtrLength, stopMultiplier, wicks)

candleColor = colorByPreviousClose ?
                 (oClose[1] < oClose ? color.green : oClose[1] > oClose ? color.red : color.silver) : 
                 (oOpen < oClose ? color.green : oOpen > oClose ? color.red : color.silver)
plotcandle(oOpen, oHigh, oLow, oClose, 'Oscilator Candles', color = candleColor)

[buyStopDerived, sellStopDerived, barState] = f_getBuySellStops(oOpen, oClose, oHigh, oLow, AtrMAType, AtrLength, wicks, considerWicksForDelayByStep, stopMultiplier, targetMultiplier)

trailingStopDerived = barState == 1? buyStopDerived : sellStopDerived

plot(showSupertrend?trailingStopDerived:na, title="TrailingStop", style=plot.style_linebr, linewidth=1, color= barState == 1 ? color.green : color.red)

[pivotHigh, pivotLow] = f_getPivotHighLow(open, close, high, low, HTFMultiplier, resolution, PivotLength)

buyCondition = (barState == 1) and (close > pivotHigh or not useHTFPivot)
exitBuyConditin = (barState == -1)
sellCondition = (barState == -1) and (close < pivotLow or not useHTFPivot)
exitSellCondition = (barState == 1)

// strategy.risk.allow_entry_in(tradeDirection)
strategy.entry("Buy", strategy.long, when=buyCondition and inDateRange, oca_name="oca")
strategy.entry("Sell", strategy.short, when=sellCondition and inDateRange, oca_name="oca")
strategy.close("Buy", when = exitBuyConditin)
strategy.close( "Sell", when = exitSellCondition)