Strategi ini dinamakan RSI_OTT-TP/SL. Ia menggabungkan penunjuk RSI dan jalur OTT untuk menentukan isyarat perdagangan, yang tergolong dalam strategi trend berikut. Strategi ini menilai arah trend pasaran melalui penunjuk RSI dan menggunakan jalur OTT untuk mencari titik masuk tertentu. Ia juga membolehkan pengguna menetapkan nisbah mengambil keuntungan dan menghentikan kerugian untuk mengunci keuntungan atau mengelakkan kerugian secara automatik.
Strategi ini menggunakan penunjuk RSI dan OTT untuk menentukan trend dan titik kemasukan.
RSI digunakan untuk menilai arah trend keseluruhan. RSI boleh menunjukkan sama ada pasaran terlalu banyak dibeli atau terlalu banyak dijual. RSI yang melintasi di atas tahap overbought adalah isyarat beli, sementara melintasi di bawah tahap oversold adalah isyarat jual. Panjang RSI lalai adalah 6, tahap overbought adalah 50 dan tahap oversold juga 50 dalam strategi ini.
Band OTT digunakan untuk menemui titik masuk. Mereka adalah band yang dibentuk berdasarkan penunjuk Kadar Perubahan Volatiliti (VAR). Apabila harga menembusi band bawah ke atas, ia adalah isyarat beli. Apabila harga menembusi band atas ke bawah, ia adalah isyarat jual.
Selepas menentukan trend dan mengesahkan titik kemasukan, strategi ini akan membuka kedudukan panjang atau pendek apabila harga memecahkan jalur OTT.
mengambil keuntungan dan stop loss boleh ditetapkan melalui kotak input untuk pengguna untuk menyesuaikan. strategi akan menutup kedudukan secara automatik apabila mengambil keuntungan atau harga stop loss disentuh.
Strategi ini juga membenarkan perdagangan hanya panjang, pendek sahaja atau kedua-dua arah.
Menggabungkan jalur RSI dan OTT dapat mencari titik masuk kebarangkalian yang tinggi di bawah penilaian trend yang tepat.
Band OTT menggunakan penunjuk momentum dan sangat sensitif terhadap turun naik harga, yang dapat mengesan titik perubahan lebih awal.
Fungsi mengambil keuntungan dan menghentikan kerugian membantu mengunci keuntungan dan menghadkan kerugian sebelum mereka berkembang, yang memberi manfaat kepada kawalan risiko.
Struktur kod adalah jelas dengan komen yang mencukupi, mudah difahami dan diubah suai.
Parameter strategi boleh disesuaikan dengan fleksibel melalui antara muka untuk menyesuaikan diri dengan persekitaran pasaran yang berbeza.
RSI mempunyai pengeluaran yang tertinggal dan mungkin terlepas titik pembalikan trend, yang membawa kepada kerugian yang tidak perlu.
Band OTT juga boleh menghasilkan isyarat palsu. Lebih baik mengesahkan dengan corak candlestick.
Tidak betul mengambil keuntungan dan berhenti kerugian tetapan akan menjejaskan prestasi strategi. Parameter perlu diselaraskan untuk produk yang berbeza.
Strategi ini hanya diuji semula pada satu produk sahaja. Parameter harus dioptimumkan secara berasingan untuk produk yang berbeza dalam perdagangan langsung.
Jendela masa backtest adalah pendek dan mungkin tidak sepenuhnya mengesahkan keberkesanan strategi.
Pertimbangkan untuk menambah penunjuk lain untuk penapisan, seperti MACD, KD dan lain-lain untuk mengurangkan entri palsu.
Julat keuntungan dan stop loss boleh diselaraskan secara dinamik berdasarkan turun naik.
Pengoptimuman parameter penyelidikan untuk produk yang berbeza untuk menetapkan kriteria pemilihan parameter.
Cuba kaedah pembelajaran mesin untuk mengoptimumkan parameter strategi secara dinamik.
Tambah pengesahan jumlah untuk mengelakkan pecah palsu. Penunjuk jumlah juga boleh digunakan untuk menentukan trend.
Pertimbangkan untuk menggunakan penembusan MA sebagai stop loss dan bukannya stop loss peratusan yang mudah.
Ringkasnya, ini adalah strategi trend berikut yang tipikal. Ia mula-mula menilai arah trend melalui RSI, kemudian menggunakan jalur OTT untuk membantu menentukan titik masuk tertentu, dan akhirnya menetapkan mengambil keuntungan dan menghentikan kerugian untuk mengunci keuntungan dan mengawal risiko. Kelebihan strategi ini adalah kombinasi penunjuk yang mudah dan berkesan dan hasil backtest yang baik. Tetapi terdapat juga beberapa risiko seperti lag RSI dan isyarat palsu jalur OTT. Ini memerlukan kita untuk mengoptimumkan parameter dengan teliti dalam perdagangan langsung, dan menambah penunjuk teknikal lain untuk pengesahan untuk meningkatkan kestabilan strategi. Dengan pengoptimuman dan pengesahan berterusan, strategi ini boleh menjadi strategi templat trend berikut yang sangat praktikal.
/*backtest start: 2023-09-08 00:00:00 end: 2023-10-08 00:00:00 period: 2h 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/ // © BigCoinHunter //@version=5 strategy(title="RSI_OTT-TP/SL", overlay=true, pyramiding=0, default_qty_type=strategy.percent_of_equity, default_qty_value=100, initial_capital=1000, currency=currency.USD, commission_value=0.05, commission_type=strategy.commission.percent, process_orders_on_close=true) //----------- get the user inputs -------------- //---------- RSI ------------- price = input(close, title="Source") RSIlength = input.int(defval=6,title="RSI Length") RSIoverSold = input.int(defval=50, title="RSI OverSold", minval=1) RSIoverBought = input.int(defval=50, title="RSI OverBought", minval=1) //------- OTT Bands ---------------- src = close length=input.int(defval=1, title="OTT Period", minval=1) percent=input.float(defval=5, title="OTT Percent", step=0.1, minval=0.001) mav = input.string(title="OTT MA Type", defval="VAR", options=["SMA", "EMA", "WMA", "TMA", "VAR", "WWMA", "ZLEMA", "TSF"]) ottUpperPercent = input.float(title="OTT Upper Line Coeff", defval=0.01, minval = 0.001, step=0.001) ottLowerPercent = input.float(title="OTT Lower Line Coeff", defval=0.01, minval = 0.001, step=0.001) Var_Func(src,length)=> valpha=2/(length+1) vud1=src>src[1] ? src-src[1] : 0 vdd1=src<src[1] ? src[1]-src : 0 vUD=math.sum(vud1,9) vDD=math.sum(vdd1,9) vCMO=nz((vUD-vDD)/(vUD+vDD)) VAR=0.0 VAR:=nz(valpha*math.abs(vCMO)*src)+(1-valpha*math.abs(vCMO))*nz(VAR[1]) VAR=Var_Func(src,length) Wwma_Func(src,length)=> wwalpha = 1/ length WWMA = 0.0 WWMA := wwalpha*src + (1-wwalpha)*nz(WWMA[1]) WWMA=Wwma_Func(src,length) Zlema_Func(src,length)=> zxLag = length/2==math.round(length/2) ? length/2 : (length - 1) / 2 zxEMAData = (src + (src - src[zxLag])) ZLEMA = ta.ema(zxEMAData, length) ZLEMA=Zlema_Func(src,length) Tsf_Func(src,length)=> lrc = ta.linreg(src, length, 0) lrc1 = ta.linreg(src,length,1) lrs = (lrc-lrc1) TSF = ta.linreg(src, length, 0)+lrs TSF=Tsf_Func(src,length) getMA(src, length) => ma = 0.0 if mav == "SMA" ma := ta.sma(src, length) ma if mav == "EMA" ma := ta.ema(src, length) ma if mav == "WMA" ma := ta.wma(src, length) ma if mav == "TMA" ma := ta.sma(ta.sma(src, math.ceil(length / 2)), math.floor(length / 2) + 1) ma if mav == "VAR" ma := VAR ma if mav == "WWMA" ma := WWMA ma if mav == "ZLEMA" ma := ZLEMA ma if mav == "TSF" ma := TSF ma ma MAvg=getMA(src, length) fark=MAvg*percent*0.01 longStop = MAvg - fark longStopPrev = nz(longStop[1], longStop) longStop := MAvg > longStopPrev ? math.max(longStop, longStopPrev) : longStop shortStop = MAvg + fark shortStopPrev = nz(shortStop[1], shortStop) shortStop := MAvg < shortStopPrev ? math.min(shortStop, shortStopPrev) : shortStop dir = 1 dir := nz(dir[1], dir) dir := dir == -1 and MAvg > shortStopPrev ? 1 : dir == 1 and MAvg < longStopPrev ? -1 : dir MT = dir==1 ? longStop: shortStop OTT=MAvg>MT ? MT*(200+percent)/200 : MT*(200-percent)/200 light_green=#08ff12 light_red=#fe0808 OTTupper = nz(OTT[2])*(1+ottUpperPercent) OTTlower = nz(OTT[2])*(1-ottLowerPercent) p1 = plot(OTTupper, color=light_green, linewidth=1, title="OTT UPPER") p2 = plot(nz(OTT[2]), color=color.new(color.yellow,0), linewidth=1, title="OTT MIDDLE") p3 = plot(OTTlower, color=light_red, linewidth=1, title="OTT LOWER") fill(plot1=p1, plot2=p3, title="OTT Background", color=color.new(color.aqua,90), fillgaps=false, editable=true) buyEntry = ta.crossover(src, OTTlower) sellEntry = ta.crossunder(src, OTTupper) //---------- input TP/SL --------------- tp = input.float(title="Take Profit:", defval=0.0, minval=0.0, maxval=100.0, step=0.1) * 0.01 sl = input.float(title="Stop Loss: ", defval=0.0, minval=0.0, maxval=100.0, step=0.1) * 0.01 isEntryLong = input.bool(defval=true, title= 'Long Entry', inline="11") isEntryShort = input.bool(defval=true, title='Short Entry', inline="11") //---------- backtest range setup ------------ fromDay = input.int(defval = 1, title = "From Day", minval = 1, maxval = 31) fromMonth = input.int(defval = 1, title = "From Month", minval = 1, maxval = 12) fromYear = input.int(defval = 2021, title = "From Year", minval = 2010) toDay = input.int(defval = 30, title = "To Day", minval = 1, maxval = 31) toMonth = input.int(defval = 12, title = "To Month", minval = 1, maxval = 12) toYear = input.int(defval = 2022, title = "To Year", minval = 2010) //------------ time interval setup ----------- start = timestamp(fromYear, fromMonth, fromDay, 00, 00) // backtest start window finish = timestamp(toYear, toMonth, toDay, 23, 59) // backtest finish window window() => true // create function "within window of time" //------- define the global variables ------ var bool long = true var bool stoppedOutLong = false var bool stoppedOutShort = false //--------- Colors --------------- //TrendColor = RSIoverBought and (price[1] > BBupper and price < BBupper) and BBbasis < BBbasis[1] ? color.red : RSIoverSold and (price[1] < BBlower and price > BBlower) and BBbasis > BBbasis[1] ? color.green : na //bgcolor(switch2?(color.new(TrendColor,50)):na) //--------- calculate the input/output points ----------- longProfitPrice = strategy.position_avg_price * (1 + tp) // tp -> take profit percentage longStopPrice = strategy.position_avg_price * (1 - sl) // sl -> stop loss percentage shortProfitPrice = strategy.position_avg_price * (1 - tp) shortStopPrice = strategy.position_avg_price * (1 + sl) //---------- RSI + Bollinger Bands Strategy ------------- vrsi = ta.rsi(price, RSIlength) rsiCrossOver = ta.crossover(vrsi, RSIoverSold) rsiCrossUnder = ta.crossunder(vrsi, RSIoverBought) OTTCrossOver = ta.crossover(src, OTTlower) OTTCrossUnder = ta.crossunder(src, OTTupper) if (not na(vrsi)) if rsiCrossOver and OTTCrossOver long := true if rsiCrossUnder and OTTCrossUnder long := false //------- define the global variables ------ buySignall = false sellSignall = false //------------------- determine buy and sell points --------------------- buySignall := window() and long and (not stoppedOutLong) sellSignall := window() and (not long) and (not stoppedOutShort) //---------- execute the strategy ----------------- if(isEntryLong and isEntryShort) if long strategy.entry("LONG", strategy.long, when = buySignall, comment = "ENTER LONG") stoppedOutLong := true stoppedOutShort := false else strategy.entry("SHORT", strategy.short, when = sellSignall, comment = "ENTER SHORT") stoppedOutLong := false stoppedOutShort := true else if(isEntryLong) strategy.entry("LONG", strategy.long, when = buySignall) strategy.close("LONG", when = sellSignall) if long stoppedOutLong := true else stoppedOutLong := false else if(isEntryShort) strategy.entry("SHORT", strategy.short, when = sellSignall) strategy.close("SHORT", when = buySignall) if not long stoppedOutShort := true else stoppedOutShort := false //----------------- take profit and stop loss ----------------- if(tp>0.0 and sl>0.0) if ( strategy.position_size > 0 ) strategy.exit(id="LONG", limit=longProfitPrice, stop=longStopPrice, comment="Long TP/SL Trigger") else if ( strategy.position_size < 0 ) strategy.exit(id="SHORT", limit=shortProfitPrice, stop=shortStopPrice, comment="Short TP/SL Trigger") else if(tp>0.0) if ( strategy.position_size > 0 ) strategy.exit(id="LONG", limit=longProfitPrice, comment="Long TP Trigger") else if ( strategy.position_size < 0 ) strategy.exit(id="SHORT", limit=shortProfitPrice, comment="Short TP Trigger") else if(sl>0.0) if ( strategy.position_size > 0 ) strategy.exit(id="LONG", stop=longStopPrice, comment="Long SL Trigger") else if ( strategy.position_size < 0 ) strategy.exit(id="SHORT", stop=shortStopPrice, comment="Short SL Trigger")