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.
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.
Strategi ini mempunyai kelebihan berikut:
Penggunaan penunjuk pengayun untuk mengenal pasti arah trend, dapat menangkap peluang pembalikan garis pendek pasaran tepat pada masanya.
Menggunakan strategi penangguhan kerugian yang lebih lama, anda boleh menghentikan kerugian sebelum kerugian berkembang, dan mengehadkan kerugian tunggal.
Berdasarkan pengukuran risiko yang dikira oleh ATR, kedudukan boleh disesuaikan secara dinamik.
Penapisan digabungkan dengan garis purata berkala yang tinggi untuk mengelakkan terikat.
Strategi penangguhan sebahagian untuk mengekalkan keuntungan dan mengunci sebahagian daripada keuntungan.
Strategi yang mudah difahami dan mudah diimplementasikan, sesuai untuk pemula dalam perdagangan kuantitatif.
Strategi ini mempunyai beberapa risiko:
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.
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.
Selepas penutupan sebahagiannya, kedudukan yang tersisa mungkin akan ditutup. Anda boleh mengurangkan peratusan penutupan sebahagiannya, meninggalkan ruang.
Risiko penyesuaian data pengesanan. Perlu diperiksa berulang kali di pasaran yang berbeza untuk mengelakkan penyesuaian berlebihan.
Garis purata kitaran tinggi juga mungkin tidak berfungsi sebagai syarat penapis. Kaedah seperti klasifikasi trend harus digunakan untuk membantu menentukan pergerakan kitaran besar.
Strategi ini boleh dioptimumkan dalam beberapa aspek:
Uji kombinasi parameter untuk pelbagai indikator osilator, pilih kombinasi yang dapat memberikan isyarat kualiti yang lebih baik, seperti indikator Sttoch untuk garis K cepat.
Cuba ubah penangguhan sebahagian menjadi penangguhan bergerak, dan setkan kedudukan penangguhan mengikut ATR atau purata bergerak.
Algoritma pembelajaran mesin ditambah untuk menilai trend kitaran besar, menggantikan penapisan garisan purata kitaran tinggi, meningkatkan ketepatan penilaian.
Menambah penunjuk tenaga sebagai syarat penapisan kemasukan untuk mengelakkan pertukaran balik yang tidak perlu.
Integrasi dan pengoptimuman berat untuk memilih kombinasi yang paling sesuai untuk varieti semasa.
Menambah modul kawalan angin pembelajaran mesin, pengoptimuman dinamik untuk kedudukan berhenti, kedudukan berhenti, dan kedudukan.
Menambah isyarat dagangan dengan penarikan triangle atau penarikan berjangka, memanfaatkan perbezaan harga antara niaga hadapan dan tunai.
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.
/*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)