Estrategia de ruptura de volatilidad dinámica


Fecha de creación: 2023-11-13 11:26:50 Última modificación: 2023-11-13 11:26:50
Copiar: 1 Número de Visitas: 750
1
Seguir
1617
Seguidores

Estrategia de ruptura de volatilidad dinámica

Descripción general

Esta estrategia aprovecha la dinámica de subida y bajada de la banda de Brin para hacer más cuando el precio rompe la banda de Brin y se mantiene en equilibrio cuando el precio cae por debajo de la banda de Brin. A diferencia de las estrategias de ruptura tradicionales, la subida y bajada de la banda de Brin cambia en función de la dinámica de la fluctuación histórica, lo que permite un mejor juicio del estado de sobreventa y sobreventa del mercado.

Principio de estrategia

La estrategia se basa principalmente en la brecha de los precios en el indicador de la banda de Brin. La banda de Brin contiene tres líneas:

  1. Línea central: promedio móvil de n días
  2. Trayecto superior: línea media + k * n días de diferencia estándar
  3. Baja línea: línea media - k * n días diferencia estándar

Cuando el precio sube más de lo esperado, se considera que el mercado está sobrecomprando y se puede hacer más. Cuando el precio baja más de lo esperado, se considera que el mercado está sobrevendido y se debe cerrar.

La estrategia permite personalizar los parámetros de la franja de Bryn: longitud de la línea media n y multiplicador de la diferencia estándar k. La longitud de la línea media por defecto es de 20 días y el multiplicador de la diferencia estándar es de 2.

Después del cierre diario de la acción, se comprueba si el precio de cierre del día ha roto la vía superior. Si es así, se ejecuta una señal de plus cuando se abre el día siguiente. Después de hacer más, se monitorea en tiempo real si el precio ha roto la vía inferior, y si se rompe, se elimina la posición.

La estrategia también introdujo un filtro de medianería, que sólo se genera cuando el precio está por encima de la medianería. Se puede optar por trazar la medianería en el ciclo actual o en un ciclo superior para controlar el punto de entrada.

El método de parada de pérdidas también ofrece dos opciones: un porcentaje fijo de parada o el seguimiento de la banda de Brin. El último puede proporcionar un mayor espacio para que las ganancias funcionen.

Ventajas estratégicas

  • El uso de la cinta de Brin para juzgar el mercado SUPERBUY/SUPPERSELL
  • Filtración uniforme para evitar el cambio a la baja
  • Parámetros de banda de Bryn personalizados para adaptarse a diferentes períodos
  • Ofrece dos opciones para detener el daño
  • Soporte para parámetros de optimización de retroalimentación y estrategias de verificación en el disco

Riesgo estratégico

  • La banda de Brin no puede juzgar por completo la sobrecompra y la sobreventa
  • El filtro de línea media puede perder oportunidades de brecha más rápidas
  • El stop-loss fijo puede ser demasiado conservador, el stop-loss de seguimiento puede ser demasiado radical.
  • Se necesitan parámetros optimizados para adaptarse a diferentes variedades y ciclos
  • No se puede limitar el tamaño de las pérdidas, y se debe considerar la gestión de los fondos

Optimización de la estrategia

  • Prueba de diferentes combinaciones de parámetros de la mediana
  • Prueba con diferentes parámetros de la banda de Bryn
  • Comparación de las tasas de ganancias de los puntos de parada fijos y los puntos de parada de seguimiento
  • Aumentar el módulo de gestión de fondos y limitar las pérdidas individuales
  • Combinación de otros indicadores para verificar la señal de la banda de Bryn

Resumir

La estrategia utiliza la dinámica de las bandas de Brin para determinar el alza y bajada de las estrategias de sobreventa y sobreventa, se basa en las señales de filtración en línea uniforme, y utiliza fondos de protección contra pérdidas. En comparación con las rupturas de trayectoria fija tradicionales, es más adaptable a las fluctuaciones del mercado.

Código Fuente de la Estrategia
/*backtest
start: 2022-11-06 00:00:00
end: 2023-11-12 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=5

// Revision:        1
// Author:          @millerrh
// Strategy:  
//      Entry: Buy when price breaks out of upper Bollinger Band
//      Exit: Trail a stop with the lower Bollinger Band 
// Conditions/Variables:
//    1. Can add a filter to only take setups that are above a user-defined moving average on current timeframe and/or longer timeframe (helps avoid trading counter trend) 
//    2. Manually configure which dates to back test
//    3. User-Configurable Bollinger Band Settings
//    4. Optionally use a tighter initial stop level.  Once Bollinger Band catches up, trail with lower Bollinger Band to give more breathing room.

// strategy('Donchian Breakout', overlay=true, initial_capital=100000, currency='USD', default_qty_type=strategy.percent_of_equity, calc_on_every_tick = true,
//   default_qty_value=100, commission_type=strategy.commission.percent, commission_value=0.1)

strategy('Bollinger Breakout', overlay=true, initial_capital=100000, currency='USD', default_qty_type=strategy.percent_of_equity,
  default_qty_value=100, commission_type=strategy.commission.percent, commission_value=0.0, calc_on_order_fills=true)

// === BACKTEST RANGE ===
Start = input(defval = timestamp("01 Jan 2019 06:00 +0000"), title = "Backtest Start Date", group = "backtest window")
Finish = input(defval = timestamp("01 Jan 2100 00:00 +0000"), title = "Backtest End Date", group = "backtest window")

// == INPUTS ==
// Bollinger Band Inputs
bbLength = input.int(20, minval=1, group = "Bollinger Band Settings", title="Bollinger Band Length",
  tooltip = "Bollinger Band moving average length.")
bbMultTop = input.float(2.0, minval=0.001, maxval=50, title="Standard Deviation (Top)")
bbMultBot = input.float(2.0, minval=0.001, maxval=50, title="Standard Deviation (Bottom)")

useTightStop = input.bool(title='Use Fixed Percentage for Initial Stop?', defval=false, group = "order entry",
  tooltip = "'Keep your losers small and let winners run' is the saying.  This will allow you to use a tight initial stop
  until the lower Bollinger Band catches up.")
percStop = input.int(title="Stop", defval=8, group = "order entry", inline = "perc")
trigInput = input.string(title='Execute Trades On...', defval='Wick', options=['Wick', 'Close'], group = "order entry",
  tooltip = "Useful for comparing standing stop orders at the Bollinger Band boundary (executing on the wick) vs. waiting for candle closes prior to taking action")

// Moving Average Filtering Inputs
useMaFilter = input.bool(title='Use Moving Average for Filtering (Current Timeframe)?', defval=false, group = "moving average filtering",
  tooltip = "Signals will be ignored when price is under this moving average.  The intent is to keep you out of bear periods and only buying when 
             price is showing strength.")
maType = input.string(defval='SMA', options=['EMA', 'SMA'], title='MA Type For Filtering', group = "moving average filtering")
maLength = input.int(defval=50, title="Moving Average:    Length", minval=1, group = "moving average filtering", inline = "1ma")
ma1Color = input.color(color.new(color.green, 50), title = " Color", group = "moving average filtering", inline = "1ma")
useMaFilter2 = input.bool(title='Use Moving Average for Filtering (High Timeframe)?', defval=false, group = "moving average filtering")
tfSet = input.timeframe(defval="D", title="Timeframe of Moving Average", group = "moving average filtering",
  tooltip = "Allows you to set a different time frame for a moving average filter.  Trades will be ignored when price is under this moving average.
  The idea is to keep your eye on the larger moves in the market and stay on the right side of the longer term trends and help you be pickier about 
  the stocks you trade.")
ma2Type = input.string(defval='SMA', options=['EMA', 'SMA'], title='MA Type For Filtering', group = "moving average filtering")
ma2Length = input.int(defval=50, title="Moving Average:    Length", minval=1, group = "moving average filtering", inline = "2ma")
ma2Color = input.color(color.new(color.white, 50), title = " Color", group = "moving average filtering", inline = "2ma")


// === THE BOLLINGER BAND ===
// Logic
bbBasis = ta.sma(close, bbLength)
bbUpper = bbBasis + bbMultTop * ta.stdev(close, bbLength)
bbLower = bbBasis - bbMultBot * ta.stdev(close, bbLength)

// Plotting
plot(bbBasis, "Basis", color=color.new(color.white, 50))
p1 = plot(bbUpper, color=color.new(color.blue, 50), linewidth=1, title='Upper Bollinger Band')
p2 = plot(bbLower, color=color.new(color.blue, 50), linewidth=1, title='Lower Bollinger Band')
fill(p1, p2, title = "Background", color=color.rgb(33, 150, 243, 95))

// == FILTERING LOGIC ==
// Declare function to be able to swap out EMA/SMA
ma(maType, src, length) =>
    maType == 'EMA' ? ta.ema(src, length) : ta.sma(src, length)  //Ternary Operator (if maType equals EMA, then do ema calc, else do sma calc)
maFilter = ma(maType, close, maLength)
maFilter2 = request.security(syminfo.tickerid, tfSet, ma(ma2Type, close, ma2Length))

// Plotting
plot(useMaFilter ? maFilter : na, title='Trend Filter MA - CTF', color=ma1Color, linewidth=2, style=plot.style_line)
plot(useMaFilter2 ? maFilter2 : na, title='Trend Filter MA - HTF', color=ma2Color, linewidth=2, style=plot.style_line)


// == ENTRY AND EXIT CRITERIA ==
// Trigger stop based on candle close or High/Low (i.e. Wick)
trigResistance = trigInput == 'Close' ? close : trigInput == 'Wick' ? high : na
trigSupport = trigInput == 'Close' ? close : trigInput == 'Wick' ? low : na
buySignal = trigResistance >= bbUpper 

buyConditions = (useMaFilter ? bbUpper > maFilter : true) and
  (useMaFilter2 ? bbUpper > maFilter2 : true) 
  
// == STOP AND PRICE LEVELS ==
// Configure initial stop level
inPosition = strategy.position_size > 0
stopLevel = strategy.position_avg_price - (strategy.position_avg_price * percStop/100)
posStop = stopLevel > bbLower ? stopLevel : bbLower


// Check if using stop vs. not
stop = useTightStop ? posStop : bbLower
plot(inPosition ? stop : na, style=plot.style_linebr, color=color.new(color.red, 40), linewidth = 1, title = "Stop Levels", trackprice=false)

sellSignal = trigSupport <= stop

// == STRATEGY ENTRIES & EXITS ==
// This string of code enters and exits at the candle close
if trigInput == 'Close'
    strategy.entry('Long', strategy.long, when=buyConditions and buySignal)
    strategy.close('Long', when=sellSignal)

// This string of code enters and exits at the wick (i.e. with pre-set stops)
if trigInput == 'Wick'
    strategy.entry('Long', strategy.long, stop=bbUpper, when=buyConditions)
    strategy.exit('Exit Long', from_entry='Long', stop=stop)
strategy.cancel('Long',when= not(buyConditions)) // Resets stop level once buyConditions aren't true anymore