Estrategia de seguimiento de tendencias de Bollinger adaptativa

El autor:¿ Qué pasa?, Fecha: 2023-11-16 16:35:01
Las etiquetas:

img

Resumen general

Esta estrategia se basa en el indicador de bandas de Bollinger, combinado con un promedio móvil adaptativo, para juzgar y rastrear con precisión las tendencias. Al ajustar dinámicamente los parámetros, la estrategia puede adaptarse a diferentes productos y entornos de mercado, con una gran estabilidad y adaptabilidad.

Estrategia lógica

La estrategia consta de las siguientes partes principales:

  1. Calcular el promedio móvil adaptativo. Utilice el indicador de regresión lineal para calcular la curva de regresión lineal durante un determinado período como promedio móvil.

  2. Utilice el indicador ATR adaptativo para calcular bandas, combinado con el parámetro ratio2 especificado por el usuario, para obtener bandas superiores e inferiores.

  3. Determinar entradas y salidas. Juzgar la dirección de la tendencia y las entradas/salidas basadas en la ruptura del precio a través de las bandas de Bollinger.

  4. Utilizar puntos fijos de stop loss para controlar los riesgos y stop profit para maximizar las ganancias de tendencia.

  5. Combinar con la ventana de tiempo de backtesting para la optimización y verificación de la estrategia.

Ventajas

  1. Parámetros adaptativos: el diseño de la media móvil y de las bandas se adapta a los cambios del mercado.

  2. Las bandas de Bollinger ofrecen claras señales de reversión de tendencia.

  3. Establecimiento de paradas razonables: las paradas fijas controlan los riesgos y las paradas de ganancias de seguimiento tienen como objetivo maximizar las ganancias de tendencia.

  4. Validado por backtesting, la ventana de backtesting verifica la efectividad de la estrategia.

  5. La lógica es clara y el código es conciso para una fácil comprensión.

Los riesgos

  1. Las bandas de Bollinger necesitan ajuste de parámetros. El ancho de la banda y el período pueden necesitar optimización para diferentes productos. Parámetros incorrectos conducen a señales faltantes o falsos disparadores.

  2. Período de pruebas de retroceso limitado: el intervalo de pruebas de retroceso reciente puede ser insuficiente para verificar completamente la estabilidad de los datos históricos completos.

  3. Riesgo de sobreajuste: los parámetros optimizados actuales pueden adaptarse demasiado a las condiciones específicas del mercado recientes.

  4. El nivel de stop loss necesita evaluación. Las pequeñas pérdidas de stop pueden ser demasiado sensibles y ser detenidas por pequeñas fluctuaciones.

  5. Falta de validación cuantificable: actualmente solo se utiliza el desglose gráfico para señales comerciales sin validación de métricas cuantificables.

Direcciones de mejora

  1. Introducir indicadores más adaptables: probar combinaciones de varias medias móviles y canales adaptativos para construir un sistema de seguimiento de tendencias robusto.

  2. Optimización de parámetros. Utilice métodos más sistemáticos como algoritmos genéticos para encontrar la combinación óptima de parámetros.

  3. Ampliar el período de backtest. Prueba en datos históricos más amplios para examinar la estabilidad de los parámetros. Incorpore costos de transacción para una backtest más realista.

  4. Introduzca filtros cuantitativos. Configure filtros como la ruptura de volumen, el hueco del histograma MACD para evitar rupturas falsas.

  5. Optimice las paradas. Evalúe diferentes niveles de pérdida de paradas fijas y métodos de paradas posteriores para encontrar paradas óptimas.

  6. Ejecuta la estrategia optimizada en vivo para registrar el rendimiento para futuras mejoras.

Conclusión

La estrategia tiene una lógica clara utilizando bandas de Bollinger para determinar la dirección de la tendencia y capturar señales de ruptura, con promedios móviles que definen la tendencia general. Con las optimizaciones adecuadas, puede convertirse en una tendencia estable y confiable después de la estrategia. Pero las consideraciones clave incluyen la representatividad de las pruebas de retroceso, filtros cuantitativos y ajuste de stop loss. Si estos aspectos se manejan bien, la estrategia puede lograr ganancias constantes y considerables en el comercio en vivo.


/*backtest
start: 2023-10-16 00:00:00
end: 2023-11-09 00:00:00
period: 1h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=4
strategy("Linear Regression (Backtest / Trailing Stop)",overlay=true)
close_price = close[0]

len = input(40)
linear_reg = linreg(close_price, len, 0)

calculationToPlotAverageMeanLine=linear_reg
useUpperDeviation = input(true, "Upper Deviation", bool)
useLowerDeviation = input(true, "Lower Deviation", bool)
ratio2=input(defval=2,title=" Ratio 2")
avg=atr(len)
r2=avg*ratio2
top=linear_reg+r2
bott=linear_reg-r2

calculationToPlotUpperLine=top
calculationToPlotLowerLine=bott

plotUpperDeviationLine = plot(not useUpperDeviation ? na : calculationToPlotUpperLine, color=color(blue,0))
plotAverageMeanLine = plot(calculationToPlotAverageMeanLine, color=color(olive,0))
plotLowererDeviationLine = plot(not useLowerDeviation ? na : calculationToPlotLowerLine, color=color(red,0))
fill(plotUpperDeviationLine, plotAverageMeanLine, color=color(blue,85))
fill(plotLowererDeviationLine, plotAverageMeanLine, color=color(red,85))


//
length = input(title="linear Length",  defval=40, minval=1)
multiplier = input(title="linear Deviation", type=float, defval=2, minval=1)
overbought = input(title="Overbought",  defval=1, minval=1)
oversold = input(title="Oversold",  defval=0, minval=1)
custom_timeframe = input(title="Use another Timeframe?", type=bool, defval=false)
highTimeFrame = input(title="Select The Timeframe",  defval="60")
res1 = custom_timeframe ? highTimeFrame : timeframe.period

fixedSL = input(title="SL Activation", defval=70)
trailSL = input(title="SL Trigger", defval=10)
fixedTP = input(title="TP Activation", defval=50)
trailTP = input(title="TP Trigger", defval=10)

// === INPUT BACKTEST RANGE ===
FromMonth = input(defval = 1, title = "From Month", minval = 1, maxval = 12)
FromDay   = input(defval = 1, title = "From Day", minval = 1, maxval = 31)
FromYear  = input(defval = 2019, title = "From Year", minval = 2015)
ToMonth   = input(defval = 1, title = "To Month", minval = 1, maxval = 12)
ToDay     = input(defval = 1, title = "To Day", minval = 1, maxval = 31)
ToYear    = input(defval = 9999, title = "To Year", minval = 2015)

start     = timestamp(FromYear, FromMonth, FromDay, 00, 00)  // backtest start window
finish    = timestamp(ToYear, ToMonth, ToDay, 23, 59)        // backtest finish window
window()  => time >= start and time <= finish ? true : false // create function "within window of time"

smabasis = linreg(close_price, length, 0)
stdev = stdev(close, length)
cierre = request.security(syminfo.tickerid, res1, close, false)
alta = request.security(syminfo.tickerid, res1, high, false)
baja = request.security(syminfo.tickerid, res1, low, false)
basis1 = request.security(syminfo.tickerid, res1, smabasis, false)
stdevb = request.security(syminfo.tickerid, res1, stdev, false)
dev = multiplier * stdevb // stdev(cierre, length)
upper = basis1 + dev
lower = basis1 - dev

bbr = (cierre - lower)/(upper - lower)

// plot(bbr)

// // MARCA LAS RESISTENCIAS
pintarojo = 0.0
pintarojo := nz(pintarojo[1])
pintarojo := bbr[1] > overbought and bbr < overbought ? alta[1] :  nz(pintarojo[1])
p = plot(pintarojo, color = red, style=circles, linewidth=2)

// // MARCA LOS SOPORTES
pintaverde = 0.0
pintaverde := nz(pintaverde[1])
pintaverde := bbr[1] < oversold and bbr > oversold ? baja[1] :  nz(pintaverde[1])
g = plot(pintaverde, color = black, style=circles, linewidth=2)
zz= crossover(pintaverde,pintaverde[1]) or crossunder(pintaverde,pintaverde[1])
kp= crossover(pintarojo,pintarojo[1]) or crossunder(pintarojo,pintarojo[1]) 
plotshape(zz,  title="buy", style=shape.triangleup,location=location.belowbar, color=green, transp=0, size=size.small)
plotshape(kp, title="sell", style=shape.triangledown,location=location.abovebar, color=red, transp=0, size=size.small)


strategy.entry("BUY", strategy.long, qty=10, oca_name="BUY",  when=zz and window())
strategy.exit("B.Exit", "BUY", qty_percent = 100, loss=fixedSL, trail_offset=trailTP, trail_points=fixedTP)

strategy.entry("SELL", strategy.short, qty=10, oca_name="SELL",  when=kp and window())
strategy.exit("S.Exit", "SELL", qty_percent = 100, loss=fixedSL, trail_offset=trailSL, trail_points=fixedTP)


Más.