RSI-Trend folgt der Trailing-Stop-Strategie


Erstellungsdatum: 2023-12-08 11:41:31 zuletzt geändert: 2023-12-08 11:41:31
Kopie: 3 Klicks: 722
1
konzentrieren Sie sich auf
1621
Anhänger

RSI-Trend folgt der Trailing-Stop-Strategie

Überblick

Die Strategie ist eine automatische Handelsstrategie, bei der der RSI-Indikator Trends identifiziert und in Kombination mit dem Moving Average eine Trendbestätigung durchführt, um einen Stop-Loss-Stillstand zu setzen. Wenn der RSI größer als 68 ist und der Moving Average vor dem Durchbruch des aktuellen Moving Average liegt, machen Sie mehr; wenn der RSI kleiner als 28 ist und der Moving Average vor dem Durchbruch des aktuellen Moving Average liegt, machen Sie nichts.

Strategieprinzip

Die Strategie verwendet hauptsächlich die RSI-Anzeige, um überkaufte und überverkaufte Trends zu erkennen. Wenn der RSI größer als 70 ist, ist es eine Überkaufzone, wenn er kleiner als 30 ist, ist es eine Überverkaufszone.

Mehrköpfige Signale: Der RSI ist größer als 68 und bewegt sich über den aktuellen Moving Average, bevor er den Moving Average durchbricht. Hohes Signal: Der RSI ist kleiner als 28 und unterhalb des aktuellen Moving Averages, bevor der Moving Average durchbrochen wird.

Die Stop-Loss-Stopp-Einstellungen setzen für jeden Punkt eine unterschiedliche Stop-Loss-Ratio ein, von lockerer bis strenger, und zwar:

Mehrköpfige Stop-Off: 1,4% Stop-Off auf die Hälfte der Positionen, 0,8% Stop-Off auf die Hälfte der Positionen. Mehrfache Stop-Loss: 2% des Eintrittspreises.

Hoher Stop: 0,4% an den niedrigsten Punkten halbe Position, 0,8% an den niedrigsten Punkten vollständige Position.
Leerstand: 2% des Einstiegspreises.

Wenn der Trend umgekehrt wird, beispielsweise wenn der RSI bei 30 brechen wird, ist der Marktpreis vollständig ausgeglichen. Wenn der RSI bei 60 brechen wird, ist der Marktpreis vollständig ausgeglichen.

Strategische Vorteile

  1. Der RSI-Indikator wird verwendet, um Überkaufe und Überverkäufe zu ermitteln, um zu verhindern, dass die Höhen und Tiefen verfolgt werden.
  2. Der Moving Average filtert Trends und reduziert die Abweichungen.
  3. Die Einführung von Schritt-zu-Schritt-Sperren maximiert die Gewinne.
  4. Ein höherer Stop-Loss-Punkt ist festgelegt, um dem Trend den richtigen Raum zu geben.
  5. In Kombination mit einer Trendwende-Strategie für die Umkehrung der Liquidation und einer schnellen Reaktion auf unerwartete Ereignisse.

Strategisches Risiko

  1. Probleme mit der Einstellung der RSI-Parameter, was zu einer schlechten Erkennung führte.
  2. Problem mit der Einstellung der Moving Average-Parameter, was zu einer schlechten Filterwirkung führte.
  3. Die Stop-Loss-Punkte sind zu locker und es besteht die Gefahr, dass sich die Verluste ausweiten.
  4. Das ist eine sehr schwierige Aufgabe, die sich nicht lösen lässt.
  5. Die Reverse-Liquidation-Strategie führt zu unnötigen Verlusten.

Die Parameter müssen mehrfach getestet und optimiert werden. Die Stop-Loss-Sperre sollte angemessen eingestellt und in bestimmten Bereichen gelockert werden. Die Parameter müssen je nach Marktschwankungen angepasst werden.

Optimierungsrichtung

Die Optimierung kann in folgenden Bereichen weiter vorangetrieben werden:

  1. Mehr Filterindikatoren, um die Signalgenauigkeit zu verbessern. Zum Beispiel die Erweiterung der Filter für die Transaktionsmenge.
  2. Anpassung der Stop-Loss-Strategie, Verfolgung der Höchst- und Tiefstpreise, Erreichung eines mobilen Stop-Losses.
  3. Die Anpassung des Teils des Stopps an den Tracking-Stop ermöglicht die Maximierung der Gewinne.
  4. Hinzu kommt eine Kombination von Parametern, wie z. B. Datenspeicherung, unterschiedliche Zeitspannen für verschiedene Sorten.
  5. Erhöhung der Kosten für die Inhaber von leeren Futures und dynamische Anpassung der Stop-Loss-Regelung.

Zusammenfassen

Die Strategie als Ganzes ist eine eher erfahrene und zuverlässige Trend-Tracking-Strategie. Der RSI wird verwendet, um Überkauf-Überverkauf zu bestimmen. Der Moving Average wird verwendet, um die Wellen zu bestätigen.

Strategiequellcode
// © 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)