Strategi Trailing Stop Mengikuti Tren RSI


Tanggal Pembuatan: 2023-12-08 11:41:31 Akhirnya memodifikasi: 2023-12-08 11:41:31
menyalin: 3 Jumlah klik: 722
1
fokus pada
1621
Pengikut

Strategi Trailing Stop Mengikuti Tren RSI

Ringkasan

Strategi ini adalah strategi perdagangan otomatis yang menggunakan indikator RSI untuk mengidentifikasi tren, dan dalam kombinasi dengan rata-rata bergerak untuk konfirmasi tren, untuk mengatur stop loss. Jika RSI lebih besar dari 68 dan bergerak di atas rata-rata bergerak saat ini, lakukan lebih banyak; jika RSI lebih kecil dari 28 dan bergerak di bawah rata-rata bergerak saat ini, lakukan kosong.

Prinsip Strategi

Strategi ini terutama menggunakan indikator RSI untuk menilai overbought dan oversold dan mengidentifikasi tren. Ketika RSI lebih besar dari 70, itu adalah zona overbought, dan jika lebih kecil dari 30, itu adalah zona oversold.

Sinyal multihead: RSI lebih besar dari 68 dan bergerak di atas rata-rata bergerak saat ini sebelum melewati rata-rata bergerak, lakukan lebih. Sinyal kosong: RSI kurang dari 28 dan bergerak di bawah rata-rata bergerak saat ini sebelum melewati rata-rata bergerak, kosong.

Pengaturan stop loss untuk setiap titik memiliki rasio stop loss yang berbeda, mulai dari yang lebih longgar hingga yang lebih ketat, yaitu:

Multihead Stop: 1,4% stop di titik tinggi setengah posisi, 0,8% stop di titik tinggi seluruh posisi kosong. Stop loss: 2% dari harga tiket.

Hulu Stop Stop: 0,4% dari posisi terendah, setengah dari posisi terendah, 0,8% dari posisi terendah, seluruh posisi terendah.
Stop loss: 2% dari harga tiket.

Pada saat yang sama, ketika tren berbalik, misalnya ketika RSI lebih dari 30 maka harga pasar akan benar-benar rata. Ketika RSI lebih dari 60 maka harga pasar akan benar-benar rata.

Keunggulan Strategis

  1. Menggunakan indikator RSI untuk mengevaluasi overbought dan oversold, hindari mengejar high dan low.
  2. Moving Average melakukan pemfilteran tren, mengurangi operasi non-mainstream.
  3. Pengaturan stop loss progresif untuk memaksimalkan keuntungan.
  4. Stop loss yang lebih tinggi diatur untuk memberikan ruang yang tepat untuk tren.
  5. Strategi Reverse Liquidation yang dikombinasikan dengan Trend Shift Indicator, untuk bereaksi cepat terhadap kejadian yang tidak terduga.

Risiko Strategis

  1. Masalah pengaturan parameter RSI, menyebabkan kesalahan pengidentifikasian.
  2. Masalah pengaturan parameter moving average yang menyebabkan efek filter yang buruk.
  3. Stop loss terlalu longgar, risiko kerugian meningkat.
  4. Hal ini dikarenakan titik tolak yang terlalu sempit, sehingga tidak dapat memaksimalkan keuntungan.
  5. Keputusan yang salah dalam strategi likuidasi terbalik menyebabkan kerugian yang tidak perlu.

Untuk menghadapi risiko di atas, parameter harus banyak kali diuji dan dioptimalkan. Pengaturan stop loss harus tepat, melonggarkan interval tertentu, dan menyesuaikan parameter sesuai dengan volatilitas pasar. Strategi penyelesaian harus berhati-hati, untuk menghindari kerugian akibat kesalahan penilaian indikator.

Arah optimasi

Ada beberapa hal yang bisa dioptimalkan:

  1. Menambahkan lebih banyak indikator filter untuk meningkatkan akurasi sinyal. Misalnya, menambahkan filter volume transaksi.
  2. Adaptasi strategi stop loss, pelacakan harga tertinggi dan harga terendah, dan implementasi stop loss mobile.
  3. Ada beberapa stop loss yang disesuaikan untuk memaksimalkan keuntungan.
  4. Menambahkan kombinasi parameter seperti pertukaran sumber data, penggunaan siklus yang berbeda untuk varietas yang berbeda.
  5. Meningkatkan pertimbangan biaya kepemilikan saham kosong berjangka, mengadaptasi stop loss secara dinamis.

Meringkaskan

Strategi ini secara keseluruhan adalah strategi pelacakan tren yang lebih andal. Strategi ini menggunakan RSI untuk menilai overbought dan oversold untuk menentukan arah perdagangan. Penggunaan rata-rata bergerak untuk mengkonfirmasi gelombang.

Kode Sumber Strategi
// © 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)