RSI Trend Mengikuti Strategi dengan Stop Loss Trailing

Penulis:ChaoZhang, Tarikh: 2023-12-08 11:41:31
Tag:

img

Ringkasan

Strategi ini adalah strategi perdagangan automatik yang mengenal pasti trend menggunakan penunjuk RSI dan mengesahkan trend dengan purata bergerak, dengan tetapan stop loss dan mengambil keuntungan. Ia pergi lama apabila RSI melebihi 68 dan purata bergerak semasa melintasi di atas purata bergerak sebelumnya, dan pergi pendek apabila RSI jatuh di bawah 28 dan purata bergerak semasa melintasi di bawah purata bergerak sebelumnya.

Logika Strategi

Strategi ini terutamanya menggunakan penunjuk RSI untuk mengenal pasti keadaan overbought dan oversold untuk menentukan trend. Nilai di atas 70 untuk RSI menunjukkan keadaan overbought dan nilai di bawah 30 menunjukkan keadaan oversold. Trend ini disahkan menggunakan isyarat salib emas dan salib kematian dari purata bergerak. Isyarat perdagangan khusus adalah:

Isyarat panjang: RSI melebihi 68 dan purata bergerak semasa melintasi purata bergerak sebelumnya, pergi panjang.
Isyarat pendek: RSI turun di bawah 28 dan purata bergerak semasa melintasi di bawah purata bergerak sebelumnya, pergi pendek.

Tetapan stop loss dan mengambil keuntungan disusun, dari yang lebih longgar kepada yang lebih ketat:

Ambil keuntungan panjang: Ambil keuntungan 50% kedudukan pada 1.4% di atas tinggi, ambil keuntungan 100% pada 0.8% di atas tinggi.
Stop loss panjang: Tetapkan stop loss pada 2% di bawah harga masuk.

Ambil keuntungan pendek: Ambil keuntungan 50% kedudukan pada 0.4% di bawah paras rendah, ambil keuntungan 100% pada 0.8% di bawah paras rendah. Stop loss pendek: Tetapkan stop loss pada 2% di atas harga masuk.

Juga, apabila trend berbalik, seperti RSI memecahkan di bawah 30 apabila panjang, menutup keseluruhan kedudukan panjang di pasaran; apabila RSI memecahkan di atas 60 apabila pendek, menutup keseluruhan kedudukan pendek di pasaran.

Kelebihan

  1. Gunakan RSI untuk menentukan overbought / oversold untuk mengelakkan membeli tinggi dan menjual rendah.
  2. Penapis dengan purata bergerak untuk mengurangkan perdagangan terhadap trend utama.
  3. Staggered mengambil sasaran keuntungan untuk memaksimumkan keuntungan.
  4. Stop loss yang lebih luas membolehkan beberapa retracement.
  5. Penutupan kedudukan berdasarkan pembalikan trend bertindak balas dengan cepat terhadap peristiwa tiba-tiba.

Risiko

  1. Penyesuaian parameter RSI yang buruk membawa kepada isyarat yang tidak tepat.
  2. Penyesuaian parameter purata bergerak yang buruk membawa kepada penapisan yang lemah.
  3. Stop loss terlalu luas yang membawa kepada kerugian besar.
  4. Mengambil keuntungan terlalu ketat meninggalkan keuntungan di atas meja.
  5. Isyarat pembalikan yang tidak tepat menutup kedudukan yang tidak perlu.

Untuk menangani risiko di atas, penyesuaian parameter yang meluas harus dilakukan. Hentikan kerugian dan ambil keuntungan juga harus ditetapkan dengan sewajarnya berdasarkan turun naik pasaran. Isyarat pembalikan harus digunakan dengan berhati-hati untuk mengelakkan kerugian yang tidak perlu.

Peluang Peningkatan

Strategi ini boleh ditingkatkan lagi:

  1. Tambah lebih banyak penapis seperti kelantangan untuk meningkatkan ketepatan isyarat.
  2. Melaksanakan stop loss untuk mengunci keuntungan.
  3. Menggunakan penarikan mengambil keuntungan untuk beberapa keluar untuk memaksimumkan keuntungan.
  4. Tambah pertukaran instrumen untuk menggunakan parameter optimum.
  5. Menggabungkan kos membawa untuk niaga hadapan untuk menyesuaikan berhenti secara dinamik.

Kesimpulan

Secara keseluruhan, ini adalah strategi trend yang matang dan boleh dipercayai. Ia mengenal pasti trend dengan baik menggunakan RSI dan penapis lanjut dengan purata bergerak. Ia juga melaksanakan tetapan stop loss yang masuk akal dan mengambil keuntungan yang tercetak. Ia boleh melakukan dengan sangat baik di pasaran trend jika disesuaikan dengan betul. Pengoptimuman lanjut boleh membawa kepada prestasi yang lebih baik.


// © CRabbit
//@version=5

// Starting with $100 and using 10% of the account per trade
strategy("RSI Template", shorttitle="RSI", overlay=false, initial_capital=100, default_qty_value=10, default_qty_type=strategy.percent_of_equity)

// RSI Indicator
ma(source, length, type) =>
    switch type
        "SMA" => ta.sma(source, length)
        "Bollinger Bands" => ta.sma(source, length)
        "EMA" => ta.ema(source, length)
        "SMMA (RMA)" => ta.rma(source, length)
        "WMA" => ta.wma(source, length)
        "VWMA" => ta.vwma(source, length)

rsiLengthInput = input.int(4, minval=1, title="RSI Length", group="RSI Settings")
rsiSourceInput = input.source(close, "Source", group="RSI Settings")
maTypeInput = input.string("SMA", title="MA Type", options=["SMA", "Bollinger Bands", "EMA", "SMMA (RMA)", "WMA", "VWMA"], group="MA Settings")
maLengthInput = input.int(23, title="MA Length", group="MA Settings")
bbMultInput = input.float(2.0, minval=0.001, maxval=50, title="BB StdDev", group="MA Settings")

up = ta.rma(math.max(ta.change(rsiSourceInput), 0), rsiLengthInput)
down = ta.rma(-math.min(ta.change(rsiSourceInput), 0), rsiLengthInput)
rsi = down == 0 ? 100 : up == 0 ? 0 : 100 - (100 / (1 + up / down))
rsiMA = ma(rsi, maLengthInput, maTypeInput)
isBB = maTypeInput == "Bollinger Bands"

plot(rsi, "RSI", color=#7E57C2)
plot(rsiMA, "RSI-based MA", color=color.green)
rsiUpperBand = hline(70, "RSI Upper Band", color=#787B86)
hline(50, "RSI Middle Band", color=color.new(#787B86, 50))
rsiLowerBand = hline(30, "RSI Lower Band", color=#787B86)
fill(rsiUpperBand, rsiLowerBand, color=color.rgb(126, 87, 194, 90), title="RSI Background Fill")


// Configure backtest start date with inputs
startDate = input.int(title="Start Date", defval=1, minval=1, maxval=31)
startMonth = input.int(title="Start Month", defval=6, minval=1, maxval=12)
startYear = input.int(title="Start Year", defval=2022, minval=1800, maxval=2100)

// See if this bar's time happened on/after start date
afterStartDate = (time >= timestamp(syminfo.timezone,
     startYear, startMonth, startDate, 0, 0))


// Long and Short buy strategy
// Submit a market open/ close Long order, but only on/after start date
if (afterStartDate)
    if rsi > 68 and (rsiMA > rsiMA[1])
        strategy.entry("Long Order", strategy.long, comment="ENTER-LONG")
    if rsi < 30
        strategy.close("Long Order", alert_message="L-CL")

strategy.exit("L-TP1", from_entry="Long Order", limit=high * 1.004, qty_percent=50, alert_message="L-TP1" + str.tostring(high * 1.004))
strategy.exit("L-TP2", from_entry="Long Order", limit=high * 1.008, qty_percent=100, alert_message="L-TP2" + str.tostring(high * 1.008))
strategy.exit("Exit Long", from_entry="Long Order", stop=low * 0.98, alert_message="L-SL" + str.tostring(low * 0.98))        


// Submit a market Open/ Close Short order, but only on/after start date
if (afterStartDate)
    if rsi < 28 and (rsiMA < rsiMA[1])
        strategy.entry("Short Order", strategy.short, comment="ENTER-SHORT")
    if rsi > 60
        strategy.close("Short Order", alert_message="S-CL")    

strategy.exit("S-TP1", from_entry="Short Order", limit=low * 0.996, qty_percent=50, alert_message="S-TP1" + str.tostring(low * 0.996))
strategy.exit("S-TP2", from_entry="Short Order", limit=low * 0.992, qty_percent=100, alert_message="S-TP2" + str.tostring(low * 0.992))
strategy.exit("Exit Short", from_entry="Short Order", stop=high * 1.02, alert_message="S-SL" + str.tostring(high * 1.02))

// MONTHLY TABLE //

prec      = input(2, title = "Return Precision")

new_month = month(time) != month(time[1])
new_year  = year(time)  != year(time[1])

eq = strategy.equity

bar_pnl = eq / eq[1] - 1

cur_month_pnl = 0.0
cur_year_pnl  = 0.0

// Current Monthly P&L
cur_month_pnl := new_month ? 0.0 : 
                 (1 + cur_month_pnl[1]) * (1 + bar_pnl) - 1 

// Current Yearly P&L
cur_year_pnl := new_year ? 0.0 : 
                 (1 + cur_year_pnl[1]) * (1 + bar_pnl) - 1  

// Arrays to store Yearly and Monthly P&Ls
var month_pnl  = array.new_float(0)
var month_time = array.new_int(0)

var year_pnl  = array.new_float(0)
var year_time = array.new_int(0)

if (not na(cur_month_pnl[1]) and (new_month or barstate.islast))
    array.push(month_pnl , cur_month_pnl[1])
    array.push(month_time, time[1])

if (not na(cur_year_pnl[1]) and (new_year or barstate.islast))
    array.push(year_pnl , cur_year_pnl[1])
    array.push(year_time, time[1])

// Monthly P&L Table    
var monthly_table = table(na)

if (barstate.islast)
    monthly_table := table.new(position.bottom_right, columns = 14, rows = array.size(year_pnl) + 1, border_width = 1)

    table.cell(monthly_table, 0,  0, "",     bgcolor = #cccccc)
    table.cell(monthly_table, 1,  0, "Jan",  bgcolor = #cccccc)
    table.cell(monthly_table, 2,  0, "Feb",  bgcolor = #cccccc)
    table.cell(monthly_table, 3,  0, "Mar",  bgcolor = #cccccc)
    table.cell(monthly_table, 4,  0, "Apr",  bgcolor = #cccccc)
    table.cell(monthly_table, 5,  0, "May",  bgcolor = #cccccc)
    table.cell(monthly_table, 6,  0, "Jun",  bgcolor = #cccccc)
    table.cell(monthly_table, 7,  0, "Jul",  bgcolor = #cccccc)
    table.cell(monthly_table, 8,  0, "Aug",  bgcolor = #cccccc)
    table.cell(monthly_table, 9,  0, "Sep",  bgcolor = #cccccc)
    table.cell(monthly_table, 10, 0, "Oct",  bgcolor = #cccccc)
    table.cell(monthly_table, 11, 0, "Nov",  bgcolor = #cccccc)
    table.cell(monthly_table, 12, 0, "Dec",  bgcolor = #cccccc)
    table.cell(monthly_table, 13, 0, "Year", bgcolor = #999999)


    for yi = 0 to array.size(year_pnl) - 1
        table.cell(monthly_table, 0,  yi + 1, str.tostring(year(array.get(year_time, yi))), bgcolor = #cccccc)
        
        y_color = array.get(year_pnl, yi) > 0 ? color.new(color.green, transp = 50) : color.new(color.red, transp = 50)
        table.cell(monthly_table, 13, yi + 1, str.tostring(math.round(array.get(year_pnl, yi) * 100, prec)), bgcolor = y_color)
        
    for mi = 0 to array.size(month_time) - 1
        m_row   = year(array.get(month_time, mi))  - year(array.get(year_time, 0)) + 1
        m_col   = month(array.get(month_time, mi)) 
        m_color = array.get(month_pnl, mi) > 0 ? color.new(color.green, transp = 70) : color.new(color.red, transp = 70)
        
        table.cell(monthly_table, m_col, m_row, str.tostring(math.round(array.get(month_pnl, mi) * 100, prec)), bgcolor = m_color)      


Lebih lanjut