Analisis Strategi RSI dan Band OTT

Penulis:ChaoZhang, Tarikh: 2023-10-09 16:21:20
Tag:

Ringkasan

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.

Logika Strategi

  1. Strategi ini menggunakan penunjuk RSI dan OTT untuk menentukan trend dan titik kemasukan.

  2. 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.

  3. 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.

  4. Selepas menentukan trend dan mengesahkan titik kemasukan, strategi ini akan membuka kedudukan panjang atau pendek apabila harga memecahkan jalur OTT.

  5. 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.

  6. Strategi ini juga membenarkan perdagangan hanya panjang, pendek sahaja atau kedua-dua arah.

Kelebihan

  1. Menggabungkan jalur RSI dan OTT dapat mencari titik masuk kebarangkalian yang tinggi di bawah penilaian trend yang tepat.

  2. Band OTT menggunakan penunjuk momentum dan sangat sensitif terhadap turun naik harga, yang dapat mengesan titik perubahan lebih awal.

  3. Fungsi mengambil keuntungan dan menghentikan kerugian membantu mengunci keuntungan dan menghadkan kerugian sebelum mereka berkembang, yang memberi manfaat kepada kawalan risiko.

  4. Struktur kod adalah jelas dengan komen yang mencukupi, mudah difahami dan diubah suai.

  5. Parameter strategi boleh disesuaikan dengan fleksibel melalui antara muka untuk menyesuaikan diri dengan persekitaran pasaran yang berbeza.

Risiko

  1. RSI mempunyai pengeluaran yang tertinggal dan mungkin terlepas titik pembalikan trend, yang membawa kepada kerugian yang tidak perlu.

  2. Band OTT juga boleh menghasilkan isyarat palsu. Lebih baik mengesahkan dengan corak candlestick.

  3. Tidak betul mengambil keuntungan dan berhenti kerugian tetapan akan menjejaskan prestasi strategi. Parameter perlu diselaraskan untuk produk yang berbeza.

  4. Strategi ini hanya diuji semula pada satu produk sahaja. Parameter harus dioptimumkan secara berasingan untuk produk yang berbeza dalam perdagangan langsung.

  5. Jendela masa backtest adalah pendek dan mungkin tidak sepenuhnya mengesahkan keberkesanan strategi.

Arahan pengoptimuman

  1. Pertimbangkan untuk menambah penunjuk lain untuk penapisan, seperti MACD, KD dan lain-lain untuk mengurangkan entri palsu.

  2. Julat keuntungan dan stop loss boleh diselaraskan secara dinamik berdasarkan turun naik.

  3. Pengoptimuman parameter penyelidikan untuk produk yang berbeza untuk menetapkan kriteria pemilihan parameter.

  4. Cuba kaedah pembelajaran mesin untuk mengoptimumkan parameter strategi secara dinamik.

  5. Tambah pengesahan jumlah untuk mengelakkan pecah palsu. Penunjuk jumlah juga boleh digunakan untuk menentukan trend.

  6. Pertimbangkan untuk menggunakan penembusan MA sebagai stop loss dan bukannya stop loss peratusan yang mudah.

Ringkasan

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")




Lebih lanjut