Stratégie de suivi de tendance RSI avec stop suiveur


Date de création: 2023-12-08 11:41:31 Dernière modification: 2023-12-08 11:41:31
Copier: 3 Nombre de clics: 722
1
Suivre
1621
Abonnés

Stratégie de suivi de tendance RSI avec stop suiveur

Aperçu

Cette stratégie consiste à utiliser le RSI pour identifier les tendances et, en combinaison avec les moyennes mobiles, pour confirmer les tendances et définir un stop-loss. Faire plus lorsque le RSI est supérieur à 68 et la moyenne mobile avant de franchir la moyenne mobile actuelle; Faire moins lorsque le RSI est inférieur à 28 et la moyenne mobile avant de franchir la moyenne mobile actuelle.

Principe de stratégie

La stratégie utilise principalement l’indicateur RSI pour déterminer le phénomène de surachat et de survente pour identifier la tendance. Lorsque le RSI est supérieur à 70, c’est une zone de surachat et une zone de survente est une zone de survente. La confirmation de la tendance est effectuée par une croix d’or et une croix de mort associées à une moyenne mobile.

Signaux multiples: le RSI est supérieur à 68 et la moyenne mobile actuelle est sur la moyenne mobile avant de traverser, faire plus. Signal de tête vide: le RSI est inférieur à 28 et se trouve sous la moyenne mobile actuelle avant de traverser la moyenne mobile et de faire une pause.

Les paramètres de stop-loss définissent un ratio de stop-loss différent pour chaque point, allant de plus souple à plus strict, à savoir:

Stop multi-tête: 1,4% de stop à la moitié de la position à la hauteur, 0,8% de stop à la hauteur de stop à la pleine position. Stop multiple: 2% du prix d’entrée.

Stop à tête vide: 0,4% au plus bas pour arrêter la moitié de la position, 0,8% au plus bas pour arrêter la totalité de la position.
Stop à la tête vide: 2% du prix d’entrée.

En revanche, lorsque la tendance est inversée, par exemple, lorsque le RSI est supérieur à 30, le cours est complètement à plat; lorsque le RSI est supérieur à 60, le cours est complètement à plat.

Avantages stratégiques

  1. L’indicateur RSI peut être utilisé pour juger de l’excédent d’achat et de vente, et éviter de suivre les hauts et les bas.
  2. Les moyennes mobiles filtrent les tendances et réduisent les opérations non-mainstream.
  3. La mise en place d’une limite progressive pour maximiser les bénéfices.
  4. Un point d’arrêt plus élevé est défini pour donner une marge appropriée à la tendance.
  5. La stratégie de liquidation inverse combinée à l’indicateur de détournement de tendance et la réaction rapide aux événements soudains.

Risque stratégique

  1. Problème de réglage des paramètres RSI, entraînant une mauvaise reconnaissance.
  2. Problème de configuration des paramètres de la moyenne mobile, qui a entraîné une mauvaise filtration.
  3. Le risque d’une extension des pertes.
  4. Les points d’arrêt sont trop serrés pour maximiser les bénéfices.
  5. La stratégie de liquidation inversée est une erreur de jugement qui entraîne des pertes inutiles.

Les paramètres doivent être testés et optimisés à plusieurs reprises pour répondre aux risques ci-dessus. Le paramètre de stop loss doit être réglé de manière appropriée, avec une certaine marge de manœuvre, et les paramètres doivent être ajustés en fonction de la volatilité du marché. La stratégie de liquidation doit être prudente pour éviter les pertes dues à une mauvaise évaluation des indicateurs.

Direction d’optimisation

Les mesures d’optimisation peuvent être améliorées dans les domaines suivants:

  1. Ajout d’autres indicateurs de filtrage pour améliorer l’exactitude du signal. Par exemple, ajout de filtres de volume de transactions.
  2. Ajuster la stratégie de stop loss, suivre les prix les plus élevés et les prix les plus bas, réaliser des stop loss mobiles.
  3. La modification de l’arrêt partiel pour le suivi de l’arrêt, pour maximiser les bénéfices.
  4. Ajout d’une combinaison de paramètres tels que la commutation des sources de données et l’utilisation de cycles différents pour différentes variétés.
  5. Augmentation du coût de détention des positions vides à terme, ajustement dynamique des arrêts de perte.

Résumer

Cette stratégie est globalement une stratégie de suivi de tendance plus mature et plus fiable. L’utilisation du RSI pour déterminer la direction de la transaction. L’utilisation d’une moyenne mobile pour la confirmation des vagues.

Code source de la stratégie
// © 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)