Estrategia de negociación de ruptura de la banda de Bollinger

El autor:¿ Qué pasa?, Fecha: 2023-09-12 16:23:12
Las etiquetas:

Esta estrategia opera la ruptura de precios de las bandas de Bollinger y tiene como objetivo capturar las oportunidades de tendencia de las rupturas de canal.

Estrategia lógica:

  1. Calcular las bandas de Bollinger con media móvil de n períodos como bandas medias y de volatilidad por encima y por debajo.

  2. Entra corto cuando el precio cae por debajo de la banda inferior. Entra largo cuando se rompe por encima de la banda superior.

  3. Establecer paradas fuera de la banda opuesta para controlar el riesgo.

  4. Ajuste el ancho de banda basado en el descenso máximo para la optimización de parámetros.

  5. Agregue el filtro de volumen para evitar falsos brotes.

Ventajas:

  1. Rompiendo bandas identifica con eficacia los giros de tendencia.

  2. La optimización del parámetro de Bollinger es simple y práctica.

  3. El filtro de volumen mejora la calidad evitando las falsas salidas.

Riesgos:

  1. Las bandas rezagadas pueden perder el mejor momento de entrada.

  2. Las reversiones posteriores a la ruptura son comunes, requiriendo paradas razonables.

  3. Buscar operaciones de baja frecuencia en la optimización puede perder oportunidades.

En resumen, esta es una estrategia típica de ruptura de canal de negociación de rupturas de Bollinger.


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

//@version=2
// strategy("ChannelBreakOutStrategyV2.1", commission_type = "percent", commission_value = 0.1, calc_on_order_fills = true, overlay=true)

length = input(title="Length",  minval=1, maxval=1000, defval=40)
maxR = input(title = "R",  minval = 1.0, maxval = 10, defval = 3, step = 0.1)
adoptR = input(title = "Auto Adjust R",  defval = false)
stepR = input(title = "Step in R",  minval = 0.01, maxval = 0.1, step = 0.01, defval = 0.02)
baseYear = input(title = "Base Year",  minval = 2000, maxval = 2016, defval = 2000)
volumeTh = input(title = "Volume Threadhold",  minval = 100.0, maxval = 200, defval = 120, step = 5)
hasLong = input(title = "Include Long",  defval = true)
hasShort = input(title = "Include Short",  defval = true)
usePositionSizing = input(title = "Enable Position Sizing",  defval = true)

getTrailStop(val, current) => 
    s = val > 1.6 ? 0.8 : val >= 1.4 ? 0.85 : val >= 1.3 ? 0.9 : 0.93
    s * current


upBound = highest(high, length)
downBound = lowest(low, length)
hasVol = (volume / sma(volume, length) * 100 >= volumeTh) ? 1 : 0

hasPos = strategy.position_size != 0 ? 1 : 0

trailstop = atr(length) * 3
ptvalue = syminfo.pointvalue
equity = strategy.openprofit > 0 ? strategy.equity - strategy.openprofit : strategy.equity
curR = adoptR == false ? maxR : n == 0 ? maxR : hasPos == 1 ? curR[1] : (rising(equity,1) > 0? curR[1] + stepR : falling(equity, 1) > 0 ? curR[1] <= 2.0 ? 2.0 : curR[1] - stepR : curR[1])
contracts = usePositionSizing == false ? 20 : floor(equity / 100 * curR / (trailstop * ptvalue))

realbuystop = close - trailstop
realsellstop = close + trailstop

isPFst = (hasPos[1] == 0 and hasPos == 1) ? 1 : 0
isPOn = (hasPos[1] + hasPos == 2) ? 1 : 0
largestR = hasPos == 0 or isPFst == 1 ? -1 : nz(largestR[1]) < close ? close : largestR[1]
pctRise =  largestR / strategy.position_avg_price

rbs = strategy.position_size <= 0 ? realbuystop : isPFst ? strategy.position_avg_price - trailstop : pctRise >= 1.3 ? getTrailStop(pctRise, largestR) : (isPOn and realbuystop > rbs[1] and close > close[1]) ? realbuystop : rbs[1]
rss = strategy.position_size >= 0 ? realsellstop : isPFst ? strategy.position_avg_price + trailstop : (isPOn and realsellstop < rss[1] and close < close[1]) ? realsellstop : rss[1]

isStart = na(rbs) or na(rss) ? 0 : 1
buyARun = close - open > 0 ? 0 : open - close
sellARun = open - close > 0 ? 0 : close - open

if (strategy.position_size > 0 and buyARun >= trailstop / 3 * 2 and pctRise < 1.3)
    strategy.close("buy")
    strategy.cancel("exit")
if (strategy.position_size < 0 and sellARun >= trailstop / 3 * 2)
    strategy.close("sell")
    strategy.cancel("exit")

strategy.cancel("buy")
strategy.cancel("sell")
conLong = hasLong == true and hasPos == 0 and year > baseYear and (isStart + hasVol) == 2
strategy.order("buy", strategy.long, qty = contracts, stop=upBound + syminfo.mintick * 5, comment="BUY", when = conLong)
if (rbs > high)
    strategy.close("buy")
strategy.exit("exit", "buy", stop = rbs, when = hasPos == 1 and isStart == 1)

conShort = hasShort == true and hasPos == 0 and year > baseYear and (isStart + hasVol) == 2
strategy.order("sell", strategy.short, qty = contracts, stop=downBound - syminfo.mintick * 5, comment="SELL", when = conShort)
if (rss < low)
    strategy.close("sell")
strategy.exit("exit", "sell", stop = rss, when = hasPos == 1 and isStart == 1)

plot(series = rbs, color=blue)
plot(series = realbuystop, color=green)
plot(series = rss, color=red)
plot(series = realsellstop, color=yellow)

Más.