Estrategia de seguimiento de la tendencia RSI con trailing stop


Fecha de creación: 2023-12-08 11:41:31 Última modificación: 2023-12-08 11:41:31
Copiar: 3 Número de Visitas: 722
1
Seguir
1621
Seguidores

Estrategia de seguimiento de la tendencia RSI con trailing stop

Descripción general

La estrategia es una estrategia de comercio automático que utiliza el indicador RSI para identificar tendencias y, en combinación con las medias móviles para la confirmación de tendencias, establece un stop loss. Cuando el RSI es mayor a 68 y el movimiento promedio es superior al movimiento promedio actual, se hace más; cuando el RSI es menor a 28 y el movimiento promedio es inferior al movimiento promedio actual, se hace vacío. Al mismo tiempo, establece un stop loss.

Principio de estrategia

La estrategia utiliza principalmente el indicador RSI para determinar la tendencia de identificación de los fenómenos de sobreventa y sobreventa. Cuando el RSI es mayor que 70 es una zona de sobreventa y cuando es menor que 30 es una zona de sobreventa. La combinación de la cruz de oro y la cruz de muerte de las medias móviles para confirmar la tendencia.

Señales múltiples: el RSI es mayor que 68 y el promedio móvil actual se cruza sobre el promedio móvil anterior, haciendo más. Señales de cabeza vacía: RSI menor a 28 y debajo de la media móvil actual antes de cruzar la media móvil, hacer vacío.

La configuración de la parada de pérdidas establece diferentes proporciones de parada de pérdidas para cada punto, desde más relajadas a más estrictas, concretamente:

Multi-Head Stop: 1.4% de alto para la mitad de las posiciones, 0.8% de alto para la totalidad de las posiciones. Detención múltiple: el 2% del precio de entrada.

Cancelación de la cabeza vacía: el 0.4% en el punto bajo cesa la mitad de la posición, el 0.8% en el punto bajo cesa la posición completa.
Detención de la cabeza vacía: el 2% del precio de entrada.

Al mismo tiempo, cuando la tendencia se invierte, por ejemplo, cuando el RSI supera los 30 años, el precio de mercado se libra completamente; cuando el RSI supera los 60 años, el precio de mercado se libra completamente.

Ventajas estratégicas

  1. Utilice el RSI para determinar si hay un exceso de compra o de venta, y evite las caídas y subidas.
  2. Las medias móviles filtran las tendencias y reducen las operaciones no convencionales.
  3. El objetivo es maximizar las ganancias mediante el establecimiento de un límite progresivo.
  4. Se establece un punto de parada más alto para dar el espacio adecuado a la tendencia.
  5. La estrategia de liquidación inversa combinada con el indicador de cambio de tendencia, reacciona rápidamente a las emergencias.

Riesgo estratégico

  1. Problemas con la configuración de los parámetros de RSI, lo que hace que la identificación no sea efectiva.
  2. Problemas con la configuración de los parámetros de las medias móviles, lo que hace que el filtro no funcione bien.
  3. El punto de parada es demasiado flojo y el riesgo de pérdidas se expande.
  4. El punto de equilibrio es demasiado estrecho para maximizar el beneficio.
  5. La estrategia de liquidación inversa es un error de juicio que causa pérdidas innecesarias.

Para los riesgos mencionados, los parámetros deben ser optimizados por varias pruebas. La configuración del stop loss debe ser adecuada, relajarse en un cierto intervalo y ajustar los parámetros según la volatilidad del mercado. La estrategia de liquidación debe ser prudente para evitar pérdidas por error de evaluación del indicador.

Dirección de optimización

Se puede optimizar aún más en los siguientes aspectos:

  1. Añadir más indicadores de filtración para mejorar la precisión de la señal. Por ejemplo, añadir filtros de volumen de transacción.
  2. Ajuste la estrategia de stop loss, el seguimiento de los precios más altos y más bajos, y la implementación de un stop loss móvil.
  3. La parte de la parada que se ajusta a la parada de seguimiento para maximizar los beneficios.
  4. Aumentar la combinación de parámetros como el cambio de fuente de datos y el uso de diferentes períodos en diferentes variedades.
  5. Incrementar el costo de tenencia de las existencias en blanco de futuros y ajustar dinámicamente el stop loss.

Resumir

La estrategia en su conjunto es una estrategia de seguimiento de tendencias más estable y confiable. Utiliza el RSI para determinar la dirección de la operación. Utiliza el promedio móvil para la confirmación de la brecha.

Código Fuente de la Estrategia
// © 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)