Estrategia dinámica de stop-profit y stop-loss basada en el doble trailing stop de ATR


Fecha de creación: 2024-03-22 13:52:59 Última modificación: 2024-03-22 13:52:59
Copiar: 1 Número de Visitas: 616
1
Seguir
1617
Seguidores

Estrategia dinámica de stop-profit y stop-loss basada en el doble trailing stop de ATR

Descripción general

La estrategia utiliza dos indicadores ATR (Average True Range) de diferentes períodos para construir una línea de parada de seguimiento de doble dinámica y generar una señal de operación cuando el precio supera la línea de parada. Al mismo tiempo, utiliza la longitud de la entidad de la línea de meta para establecer un precio de parada dinámico para lograr una parada dinámica. La estrategia también combina el indicador EMA para ayudar a juzgar la tendencia.

Principio de estrategia

  1. Calcule los valores de los indicadores ATR de dos períodos diferentes (el 10 y el 20 por defecto) y luego multiplique por sus respectivos coeficientes de sensibilidad (el 1 y el 2 por defecto) para obtener dos anchos de parada.
  2. Se produce una señal de más o menos cabeza, dependiendo de la posición del precio por encima o por debajo de las dos líneas de parada y de la situación de la ruptura.
  3. El precio de parada se calcula de forma dinámica en base a 1.65 veces la longitud de la entidad de la línea de parada actual.
  4. Una vez abierta la posición, si el precio alcanza el precio de parada, la posición cerrada se cierra.
  5. Utiliza indicadores como EMA para evaluar las tendencias actuales y proporcionar referencia para la entrada.

La estrategia aprovecha las características del indicador ATR para construir un doble stop dinámico, que se adapta mejor a las diferentes fluctuaciones del mercado, y al mismo tiempo puede responder rápidamente a los cambios en el mercado. La configuración de la parada dinámica permite a la estrategia obtener más ganancias en situaciones de tendencia. En general, la estrategia funciona mejor en mercados de tendencia, pero puede compensar las pérdidas en mercados convulsos.

Análisis de las ventajas

  1. Las líneas de stop-loss dinámicas pueden adaptarse a diferentes tipos de fluctuaciones del mercado y tienen una mayor flexibilidad.
  2. El precio de parada se calcula en función de la dinámica de la longitud de la entidad de la línea de parada actual, lo que permite obtener más ganancias en situaciones de tendencia.
  3. El uso de indicadores como EMA para auxiliar en la determinación de tendencias, como referencia para la entrada, aumenta la fiabilidad de la estrategia.
  4. La lógica del código es clara, legible y fácil de entender y optimizar.

Análisis de riesgos

  1. En un mercado convulso, las transacciones frecuentes pueden generar costos de comisiones más altos que afectan a los beneficios.
  2. La configuración de los parámetros de la línea de parada y el multiplicador de parada debe optimizarse según las características de los diferentes mercados y productos, y los parámetros incorrectos pueden causar un mal desempeño de la estrategia.
  3. La estrategia depende principalmente de que el precio rompa la línea de parada dinámica para generar señales, y puede generar señales erróneas para algunos casos de falsas rupturas de grandes fluctuaciones.

Dirección de optimización

  1. Para los mercados convulsivos, se puede considerar la introducción de más indicadores o condiciones para filtrar las señales de negociación, como RSI, MACD, etc.
  2. Para diferentes productos y mercados, se puede buscar el parámetro de la línea de parada óptima y el multiplicador de la parada mediante el retroceso histórico y la optimización de los parámetros.
  3. Se puede considerar la introducción de un módulo de gestión de posiciones y control de riesgos para ajustar el tamaño de las posiciones en función de la volatilidad del mercado y la dinámica de riesgo de la cuenta.
  4. El objetivo de este proyecto es aumentar la fiabilidad y la precisión de las señales.

Resumir

La estrategia se adapta mejor a los diferentes entornos de mercado a través de un diseño de doble línea de parada dinámica y paradas dinámicas, y se desempeña bien en situaciones de tendencia. Sin embargo, en un mercado inestable, es posible que se enfrente a problemas de negociación frecuente y compensación de ganancias y pérdidas. Por lo tanto, la estrategia es más adecuada para su uso en mercados de tendencia, y al mismo tiempo requiere optimización y ajuste de los parámetros, combinando las características del producto y el entorno del mercado. Además, todavía hay espacio para una optimización adicional, como la introducción de más condiciones de filtración, gestión de posiciones y módulos de control de riesgo, para mejorar la solidez y la rentabilidad de la estrategia. En general, la estrategia es clara, la lógica es fácil de entender y tiene un cierto valor práctico y espacio de optimización, que vale la pena investigar y aplicar más.

Código Fuente de la Estrategia
/*backtest
start: 2024-02-01 00:00:00
end: 2024-02-29 23:59:59
period: 1h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=4
strategy(title="UT Bot Strategy", overlay=true)

// Inputs
a1 = input(1, title="Key Value 1 ('This changes the sensitivity')")
c1 = input(10, title="ATR Period 1")
a2 = input(2, title="Key Value 2 ('This changes the sensitivity')")
c2 = input(20, title="ATR Period 2")
h = input(false, title="Signals from Heikin Ashi Candles")

////////////////////////////////////////////////////////////////////////////////
// BACKTESTING RANGE
 
// From Date Inputs
fromDay = input(defval=1, title="From Day", minval=1, maxval=31)
fromMonth = input(defval=1, title="From Month", minval=1, maxval=12)
fromYear = input(defval=2019, title="From Year", minval=1970)
 
// To Date Inputs
toDay = input(defval=1, title="To Day", minval=1, maxval=31)
toMonth = input(defval=1, title="To Month", minval=1, maxval=12)
toYear = input(defval=2100, title="To Year", minval=1970)
 
// Calculate start/end date and time condition
startDate = timestamp(fromYear, fromMonth, fromDay, 00, 00)
finishDate = timestamp(toYear, toMonth, toDay, 00, 00)
time_cond = time >= startDate and time <= finishDate
 
////////////////////////////////////////////////////////////////////////////////

xATR1 = atr(c1)
nLoss1 = a1 * xATR1
xATR2 = atr(c2)
nLoss2 = a2 * xATR2

src = h ? security(heikinashi(syminfo.tickerid), timeframe.period, close, lookahead=false) : close

xATRTrailingStop1 = 0.0
xATRTrailingStop1 := iff(src > nz(xATRTrailingStop1[1], 0) and src[1] > nz(xATRTrailingStop1[1], 0), max(nz(xATRTrailingStop1[1]), src - nLoss1),
   iff(src < nz(xATRTrailingStop1[1], 0) and src[1] < nz(xATRTrailingStop1[1], 0), min(nz(xATRTrailingStop1[1]), src + nLoss1), 
   iff(src > nz(xATRTrailingStop1[1], 0), src - nLoss1, src + nLoss1)))

xATRTrailingStop2 = 0.0
xATRTrailingStop2 := iff(src > nz(xATRTrailingStop2[1], 0) and src[1] > nz(xATRTrailingStop2[1], 0), max(nz(xATRTrailingStop2[1]), src - nLoss2),
   iff(src < nz(xATRTrailingStop2[1], 0) and src[1] < nz(xATRTrailingStop2[1], 0), min(nz(xATRTrailingStop2[1]), src + nLoss2), 
   iff(src > nz(xATRTrailingStop2[1], 0), src - nLoss2, src + nLoss2)))
 
pos = 0   
pos := iff(src[1] < nz(xATRTrailingStop1[1], 0) and src > nz(xATRTrailingStop1[1], 0), 1,
   iff(src[1] > nz(xATRTrailingStop1[1], 0) and src < nz(xATRTrailingStop1[1], 0), -1, nz(pos[1], 0))) 
   
xcolor = pos == -1 ? color.red: pos == 1 ? color.green : color.blue 

ema1 = ema(src, 1)
above1 = crossover(ema1, xATRTrailingStop1)
below1 = crossover(xATRTrailingStop1, ema1)
buy1 = src > xATRTrailingStop1 and above1 
sell1 = src < xATRTrailingStop1 and below1
barbuy1 = src > xATRTrailingStop1 
barsell1 = src < xATRTrailingStop1 

ema2 = ema(src, 1)
above2 = crossover(ema2, xATRTrailingStop2)
below2 = crossover(xATRTrailingStop2, ema2)
buy2 = src > xATRTrailingStop2 and above2 
sell2 = src < xATRTrailingStop2 and below2
barbuy2 = src > xATRTrailingStop2 
barsell2 = src < xATRTrailingStop2 

plotshape(buy1,  title="Buy 1",  text='Buy 1',  style=shape.labelup,   location=location.belowbar, color=color.green, textcolor=color.white, transp=0, size=size.tiny)
plotshape(sell1, title="Sell 1", text='Sell 1', style=shape.labeldown, location=location.abovebar, color=color.red,   textcolor=color.white, transp=0, size=size.tiny)
plotshape(buy2,  title="Buy 2",  text='Buy 2',  style=shape.labelup,   location=location.belowbar, color=color.green, textcolor=color.white, transp=0, size=size.tiny)
plotshape(sell2, title="Sell 2", text='Sell 2', style=shape.labeldown, location=location.abovebar, color=color.red,   textcolor=color.white, transp=0, size=size.tiny)

barcolor(barbuy1  ? color.green : na)
barcolor(barsell1 ? color.red   : na)
barcolor(barbuy2  ? color.green : na)
barcolor(barsell2 ? color.red   : na)

// Calculate SL and TP levels
candle_size = abs(open - close)
tp_level = close + candle_size *65

// Close long positions if TP is hit
strategy.exit("TP Long", "long", limit=tp_level)

// Close short positions if TP is hit
strategy.exit("TP Short", "short", limit=tp_level)

// Enter long position
strategy.entry("long", strategy.long, when=(buy1 or buy2) and time_cond)

// Enter short position
strategy.entry("short", strategy.short, when=(sell1 or sell2) and time_cond)

//adding ema with width
// Calculate EMA and SMA
ema5 = ema(close, 5)
ema200 = ema(close, 200)
ema21 = ema(close, 21)
ema50 = ema(close, 50)
sma50 = sma(close, 50)

// Plot EMA and SMA with width
plot(ema5, color=color.rgb(130, 235, 139), title="EMA 5", linewidth=1)
plot(ema200, color=color.rgb(243, 246, 249), title="EMA 200", linewidth=2)
plot(ema21, color=color.blue, title="21", linewidth=1)
plot(ema50, color=color.rgb(255, 64, 0), title="EMA 50", linewidth=2)
//plot(sma50, color=color.purple, title="SMA 20", linewidth=2)