Una estrategia de negociación de ETF basada en ATR y breakout

El autor:¿ Qué pasa?, Fecha: 2023-12-26 16:05:55
Las etiquetas:

img

Resumen general

Esta es una estrategia de trading algorítmica de ETF basada en el Rango Verdadero Promedio (ATR) y la ruptura del precio. Utiliza ATR para calcular los niveles de stop loss y take profit, y abrir posiciones largas o cortas cuando el precio rompe el precio más alto o más bajo de un determinado período.

Estrategia lógica

La estrategia se basa principalmente en los siguientes principios:

  1. Utilice los precios más altos y más bajos de un determinado período (por ejemplo, 20 velas) para determinar la tendencia y la dirección del precio.

  2. Utilice ATR para calcular dinámicamente el nivel de stop loss. La stop loss se coloca a una distancia del valor ATR de un período ATR multiplicado por un coeficiente (por ejemplo 2) del precio de entrada.

  3. Utilice ATR para determinar el nivel de toma de ganancias. La toma de ganancias se coloca a una distancia del valor ATR de un período ATR multiplicado por un coeficiente (por ejemplo, 1) del precio de entrada.

  4. Utilizar el multiplicador ATR para rastrear la pérdida de parada. Cierre posiciones con pérdida de parada cuando el precio rompe el nivel de pérdida de parada de remolque hacia una dirección desfavorable.

La estrategia es simple y confiable, ya que considera tanto la dirección de la tendencia de los precios para detectar los movimientos de los precios a tiempo, y establece el stop loss y el take profit para obtener ganancias y controlar el riesgo.

Análisis de ventajas

Las ventajas de esta estrategia incluyen:

  1. La lógica de la estrategia es simple y clara, fácil de entender e implementar.

  2. El uso de ATR para calcular los niveles de stop loss y take profit adaptativos ayuda a una flexibilidad en el tamaño de las posiciones y el control del riesgo.

  3. Las estrategias de ruptura son buenas para detectar las tendencias de precios, lo que conduce a buenos rendimientos.

  4. El stop loss del remolque puede cerrar posiciones a tiempo, evitando pérdidas excesivas.

  5. Es adecuado para productos con tendencias obvias, como los ETF y las acciones.

Análisis de riesgos

Los riesgos de la estrategia incluyen:

  1. Durante la consolidación de precios pueden producirse más señales falsas y apertura inversa.

  2. El ajuste inadecuado de los parámetros puede llevar a la falta de tendencias de precios o a demasiadas operaciones innecesarias.

  3. Los valores extremos de los parámetros pueden dar lugar a un stop loss y take profit demasiado agresivos o demasiado conservadores, lo que influye en la rentabilidad de la estrategia.

  4. Los riesgos subyacentes de los ETF, como los riesgos de política y de primas, también pueden afectar al rendimiento de la estrategia.

Soluciones correspondientes:

  1. Optimice los parámetros para disminuir las operaciones innecesarias.
  2. Añadir más factores y filtros para confirmar las señales comerciales.
  3. Ajustar los parámetros de manera adaptativa para los diferentes mercados.
  4. Diversificar el tamaño de las posiciones de inversión y control de un solo ETF.

Direcciones de optimización

La estrategia se puede optimizar aún más en los siguientes aspectos:

  1. Añadir indicadores como promedio móvil para filtrar señales falsas.

  2. Desarrollar un módulo de optimización de parámetros adaptativos para ajustar automáticamente los parámetros para diferentes períodos y productos.

  3. Adopte modelos de aprendizaje automático para predecir los próximos precios más altos y más bajos de las velas para determinar las señales de ruptura.

  4. Considere el exceso de volumen de negociación para evitar una falsa ruptura.

  5. Optimizar el tamaño de la posición inicial y los porcentajes de asignación de forma adaptativa para diferentes productos y regímenes de mercado.

Conclusión

La estrategia tiene una lógica clara y simple. Los mecanismos centrales de ruptura y de adaptación de ATR stop loss / take profit pueden controlar eficazmente los riesgos y bloquear las ganancias. Mejorar aún más los factores de ganancia y las capacidades de control de riesgos a través de la optimización de parámetros e integrar más filtros puede convertirlo en una estrategia cuantitativa rentable y optimizable.


/*backtest
start: 2023-12-18 00:00:00
end: 2023-12-21 03:00:00
period: 1m
basePeriod: 1m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © FX_minds

//@version=4
strategy("ETF tradedr", overlay=true, pyramiding=100, default_qty_type=strategy.percent_of_equity, default_qty_value=100)

//------------------------------ get user input
lookback                   = input(title="HH LL lookback", type=input.integer, defval=20)
ATR_periode                = input(title="ATR period", type=input.integer, defval=14)
ATR_SL_multiplier          = input(title="ATR SL multiplier", type=input.float, defval=2)
ATR_TP_multiplier          = input(title="ATR TP multiplier", type=input.float, defval=1)
trailing_SL_ATR_multiplier = input(title="ATR trailing SL multiplier", type=input.float, defval=3.5)
lookback_trailing_SL       = input(title="trailing SL lookback", type=input.integer, defval=4)
max_sequel_trades          = input(title="max sequel trades", type=input.float, defval=1)
trade_long                 = input(title= "trade long ?", type=input.bool, defval=true)
trade_short                = input(title= "trade short ?", type=input.bool, defval=false)

//------------------------------ determine entry conditions
long_condition   = barstate.isconfirmed and crossover(high, highest(high, lookback)[1])
short_condition  = barstate.isconfirmed and crossunder(low, lowest(low, lookback)[1])


//------------------------------ count open long trades
count_open_longs = 0
count_open_longs := nz(count_open_longs[1])

if (long_condition) 
    count_open_longs := count_open_longs +1
    //label.new(bar_index, low, tostring(count_open_longs, "#"), xloc.bar_index, yloc.belowbar, color.green, label.style_none, color.green, size.large)

if (short_condition)
    count_open_longs := 0


//------------------------------ count open short trades
count_open_shorts = 0
count_open_shorts := nz(count_open_shorts[1])

if (short_condition)
    count_open_shorts := count_open_shorts +1
    //label.new(bar_index, low, tostring(count_open_shorts, "#"), xloc.bar_index, yloc.belowbar, color.red, label.style_none, color.red, size.large)

if (long_condition)
    count_open_shorts := 0


//------------------------------ calculate entryprice
entryprice_long = long_condition ? close : na
entryprice_short = short_condition ? close : na


//------------------------------ calculate SL & TP
SL_distance = atr(ATR_periode) * ATR_SL_multiplier
TP_distance  = atr(ATR_periode) * ATR_TP_multiplier
trailing_SL_distance = atr(ATR_periode) * trailing_SL_ATR_multiplier

SL_long = entryprice_long - SL_distance
SL_short = entryprice_short + SL_distance

trailing_SL_short = lowest(close, lookback_trailing_SL) + trailing_SL_distance
trailing_SL_long  = highest(close, lookback_trailing_SL) - trailing_SL_distance

trailing_SL_short_signal = crossover(high, trailing_SL_short[1])
trailing_SL_long_signal = crossunder(low, trailing_SL_long[1])


//------------------------------ plot entry price & SL  
plot(entryprice_long, style=plot.style_linebr, color=color.white)
plot(SL_long, style=plot.style_linebr, color=color.red)
plot(SL_short, style=plot.style_linebr, color=color.green)
plot(trailing_SL_short, style=plot.style_linebr, color=color.red)
plot(trailing_SL_long, style=plot.style_linebr, color=color.green)


//------------------------------ submit entry orders
if (long_condition) and (count_open_longs <= max_sequel_trades) and (trade_long == true)
    strategy.entry("Long" + tostring(count_open_longs, "#"), strategy.long)
    strategy.exit("SL Long"+ tostring(count_open_longs, "#"), 
     from_entry="Long" + tostring(count_open_longs, "#"), stop=SL_long)

if (short_condition) and (count_open_shorts <= max_sequel_trades) and (trade_short == true)
    strategy.entry("Short" + tostring(count_open_shorts, "#"), strategy.short)
    strategy.exit("SL Short" + tostring(count_open_shorts, "#"), 
     from_entry="Short" + tostring(count_open_shorts, "#"), stop=SL_short)
    

//------------------------------ submit exit conditions
if (trailing_SL_long_signal)
    strategy.close("Long" + tostring(count_open_longs, "#"))
    strategy.close("Long" + tostring(count_open_longs-1, "#"))
    strategy.close("Long" + tostring(count_open_longs-2, "#"))
    strategy.close("Long" + tostring(count_open_longs-4, "#"))
    strategy.close("Long" + tostring(count_open_longs-5, "#"))
    strategy.close("Long" + tostring(count_open_longs-6, "#"))
    strategy.close("Long" + tostring(count_open_longs-7, "#"))
    strategy.close("Long" + tostring(count_open_longs-8, "#"))
    strategy.close("Long" + tostring(count_open_longs-9, "#"))
    
if (trailing_SL_short_signal)
    strategy.close("Short" + tostring(count_open_shorts, "#"))
    strategy.close("Short" + tostring(count_open_shorts-1, "#"))
    strategy.close("Short" + tostring(count_open_shorts-2, "#"))
    strategy.close("Short" + tostring(count_open_shorts-3, "#"))
    strategy.close("Short" + tostring(count_open_shorts-4, "#"))
    strategy.close("Short" + tostring(count_open_shorts-5, "#"))
    strategy.close("Short" + tostring(count_open_shorts-6, "#"))
    strategy.close("Short" + tostring(count_open_shorts-7, "#"))
    strategy.close("Short" + tostring(count_open_shorts-8, "#"))
    strategy.close("Short" + tostring(count_open_shorts-9, "#"))



Más.