RSI tendance suivant la stratégie avec arrêt de perte de suivi

Auteur:ChaoZhang est là., Date: 2023-12-08 11:41:31 Je suis désolé
Les étiquettes:

img

Résumé

Cette stratégie est une stratégie de trading automatisée qui identifie la tendance à l'aide de l'indicateur RSI et confirme la tendance avec des moyennes mobiles, avec des paramètres de stop loss et take profit.

La logique de la stratégie

La stratégie utilise principalement l'indicateur RSI pour identifier les conditions de surachat et de survente pour déterminer la tendance. Les valeurs supérieures à 70 pour RSI indiquent une condition de surachat et les valeurs inférieures à 30 indiquent une condition de survente. La tendance est confirmée en utilisant les signaux de croix dorée et de croix de mort des moyennes mobiles. Les signaux de trading spécifiques sont:

Signal long: le RSI dépasse 68 et la moyenne mobile actuelle dépasse la moyenne mobile précédente, passez long.
Signal court: le RSI tombe en dessous de 28 et la moyenne mobile actuelle dépasse la moyenne mobile précédente, passez court.

Les paramètres d'arrêt des pertes et de prise de profit sont échelonnés, de plus lâches à plus strictes:

Profit long: Profit 50% de la position à 1,4% au-dessus du maximum, profit 100% à 0,8% au-dessus du maximum.
L'opération de stop loss est effectuée à un niveau inférieur à 2% du prix d'entrée.

Profit à court terme: Profit à 50% de la position à 0,4% sous le minimum, profit à 100% à 0,8% sous le minimum. Le prix d'entrée de l'échange est le prix de vente de l'échange.

En outre, lorsque la tendance s'inverse, comme lorsque le RSI tombe en dessous de 30 en long, fermer toute la position longue sur le marché; lorsque le RSI dépasse 60 en short, fermer toute la position courte sur le marché.

Les avantages

  1. Utilisez le RSI pour déterminer le surachat/survente afin d'éviter d'acheter haut et de vendre bas.
  2. Filtres avec moyennes mobiles pour réduire les transactions contre la tendance principale.
  3. Les stagnerés prennent des objectifs de profit pour maximiser les profits.
  4. Un stop-loss plus large permet une certaine rétraction.
  5. La fermeture de position basée sur l'inversion de tendance réagit rapidement à des événements soudains.

Les risques

  1. Un mauvais réglage des paramètres RSI conduit à des signaux inexacts.
  2. Un mauvais réglage des paramètres de la moyenne mobile entraîne un faible filtrage.
  3. Un stop-loss trop large conduit à de grandes pertes.
  4. Prendre les bénéfices trop serré en laissant les bénéfices sur la table.
  5. Un signal de renversement inexact ferme inutilement les positions.

Pour faire face aux risques ci-dessus, un réglage approfondi des paramètres doit être effectué. Le stop loss et le take profit doivent également être définis de manière appropriée en fonction de la volatilité du marché. Les signaux de renversement doivent être utilisés avec prudence pour éviter des pertes inutiles.

Des possibilités d'amélioration

La stratégie peut être encore améliorée:

  1. Ajouter plus de filtres comme le volume pour améliorer la précision du signal.
  2. Mettez en œuvre un stop-loss pour bloquer les profits.
  3. Utilisez la trailing take profit pour certaines sorties pour maximiser les profits.
  4. Ajoutez le commutateur d'instruments pour utiliser les paramètres optimaux.
  5. Incorporer le coût de transport pour les contrats à terme afin d'ajuster dynamiquement les arrêts.

Conclusion

Dans l'ensemble, il s'agit d'une stratégie de suivi de tendance mature et fiable. Il identifie bien la tendance en utilisant le RSI et en filtrant davantage avec des moyennes mobiles. Il implémente également des paramètres de stop loss raisonnables et de prise de profit échelonnée. Il peut très bien fonctionner sur les marchés tendance s'il est ajusté correctement. Des optimisations supplémentaires peuvent conduire à une meilleure performance.


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


Plus de