RSI Trend Mengikuti Strategi dengan Trailing Stop Loss

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

img

Gambaran umum

Strategi ini adalah strategi perdagangan otomatis yang mengidentifikasi tren menggunakan indikator RSI dan mengkonfirmasi tren dengan rata-rata bergerak, dengan pengaturan stop loss dan take profit.

Logika Strategi

Strategi ini terutama menggunakan indikator RSI untuk mengidentifikasi kondisi overbought dan oversold untuk menentukan tren. Nilai di atas 70 untuk RSI menunjukkan kondisi overbought dan nilai di bawah 30 menunjukkan kondisi oversold. Tren dikonfirmasi menggunakan sinyal salib emas dan salib kematian dari rata-rata bergerak.

Sinyal panjang: RSI naik di atas 68 dan rata-rata bergerak saat ini melintasi di atas rata-rata bergerak sebelumnya, pergi panjang.
Sinyal pendek: RSI turun di bawah 28 dan rata-rata bergerak saat ini melintasi di bawah rata-rata bergerak sebelumnya, pergi pendek.

Pengaturan stop loss dan take profit terhambat, dari yang lebih longgar ke yang lebih ketat:

Long take profit: mengambil keuntungan 50% dari posisi pada 1,4% di atas tinggi, mengambil keuntungan 100% pada 0,8% di atas tinggi.
Stop loss panjang: Tetapkan stop loss pada 2% di bawah harga masuk.

Short take profit: mengambil keuntungan 50% dari posisi pada 0,4% di bawah rendah, mengambil keuntungan 100% pada 0,8% di bawah rendah. Stop loss pendek: Tetapkan stop loss pada 2% di atas harga masuk.

Juga, ketika tren berbalik, seperti RSI melanggar di bawah 30 ketika panjang, menutup seluruh posisi panjang di pasar; ketika RSI melanggar di atas 60 ketika pendek, menutup seluruh posisi pendek di pasar.

Keuntungan

  1. Gunakan RSI untuk menentukan overbought/oversold untuk menghindari membeli tinggi dan menjual rendah.
  2. Filter dengan rata-rata bergerak untuk mengurangi perdagangan terhadap tren utama.
  3. Staggered mengambil target keuntungan untuk memaksimalkan keuntungan.
  4. Stop loss yang lebih luas memungkinkan untuk beberapa retracement.
  5. Penutupan posisi berdasarkan pembalikan tren bereaksi cepat terhadap peristiwa mendadak.

Risiko

  1. Penyesuaian parameter RSI yang buruk menyebabkan sinyal yang tidak akurat.
  2. Penyesuaian parameter rata-rata bergerak yang buruk menyebabkan penyaringan yang lemah.
  3. Stop loss terlalu luas menyebabkan kerugian besar.
  4. Mengambil keuntungan terlalu ketat meninggalkan keuntungan di atas meja.
  5. Sinyal pembalikan yang tidak akurat menutup posisi yang tidak perlu.

Untuk mengatasi risiko di atas, pengaturan parameter yang luas harus dilakukan. Stop loss dan take profit juga harus ditetapkan dengan tepat berdasarkan volatilitas pasar. Sinyal pembalikan harus digunakan dengan hati-hati untuk menghindari kerugian yang tidak perlu.

Peluang Peningkatan

Strategi ini dapat ditingkatkan lagi:

  1. Tambahkan filter seperti volume untuk meningkatkan akurasi sinyal.
  2. Mengimplementasikan stop loss untuk mengunci keuntungan.
  3. Gunakan trailing mengambil keuntungan untuk beberapa keluar untuk memaksimalkan keuntungan.
  4. Tambahkan perpindahan instrumen untuk menggunakan parameter optimal.
  5. Menggabungkan biaya membawa untuk berjangka untuk menyesuaikan berhenti secara dinamis.

Kesimpulan

Secara keseluruhan, ini adalah strategi tren yang matang dan dapat diandalkan. Ini mengidentifikasi tren dengan baik menggunakan RSI dan lebih lanjut menyaring dengan moving average. Ini juga menerapkan stop loss yang masuk akal dan pengaturan profit take staggered. Ini dapat berkinerja sangat baik di pasar tren jika disetel dengan tepat. Optimasi lebih lanjut dapat menyebabkan kinerja 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 banyak