Estratégia de acompanhamento da tendência de Bollinger adaptativa

Autora:ChaoZhang, Data: 2023-11-16 16:35:01
Tags:

img

Resumo

Esta estratégia baseia-se no indicador Bollinger Bands, combinado com uma média móvel adaptativa, para julgar e rastrear com precisão as tendências.

Estratégia lógica

A estratégia consiste nas seguintes partes principais:

  1. Calcular a média móvel adaptativa Usar indicador de regressão linear para calcular a curva de regressão linear durante um determinado período como média móvel.

  2. Calcular Bandas de Bollinger Usar o indicador ATR adaptativo para calcular bandas, combinado com o parâmetro ratio2 especificado pelo usuário, para obter bandas superiores e inferiores.

  3. Determine entradas e saídas. Julgue a direção da tendência e as entradas/saidas com base na quebra de preços através das Bandas de Bollinger.

  4. Use pontos fixos de stop loss para controlar riscos e trailing stop profit para maximizar os lucros da tendência.

  5. Combinar com a janela de tempo de backtesting para otimização e verificação da estratégia.

Vantagens

  1. Parâmetros adaptáveis: a média móvel adaptável e o desenho das bandas adaptam-se às alterações do mercado.

  2. Os breakouts das bandas de Bollinger oferecem sinais claros de inversão de tendência.

  3. Estabelecimento de paradas razoáveis: paradas de perda fixas controlam os riscos e paradas de lucro de rastreamento visam maximizar os lucros da tendência.

  4. A janela de backtesting verifica a eficácia da estratégia

  5. A lógica é clara e o código é conciso para facilitar a compreensão.

Riscos

  1. As bandas de Bollinger precisam de ajuste de parâmetros. A largura da banda e o período podem precisar de otimização para diferentes produtos. Parâmetros inadequados levam a sinais perdidos ou falsos gatilhos.

  2. Período de backtest limitado: o intervalo de backtest recente pode ser insuficiente para verificar plenamente a estabilidade em dados históricos abrangentes.

  3. Risco de adaptação excessiva: os parâmetros atualmente otimizados podem ser excessivamente adaptados às recentes condições específicas do mercado.

  4. O nível de stop loss precisa ser avaliado. A pequena stop loss pode ser muito sensível e ser interrompida por pequenas flutuações.

  5. Falta de validação quantificável.

Orientações para melhorias

  1. Introduzir indicadores mais adaptáveis, testar combinações de várias médias móveis adaptativas e canais para construir um sistema robusto de rastreamento de tendências.

  2. Optimização de parâmetros. Usar métodos mais sistemáticos como algoritmos genéticos para encontrar combinações ótimas de parâmetros.

  3. Expandir o período de backtest. Teste em dados históricos mais amplos para examinar a estabilidade dos parâmetros. Incorporar custos de transação para um backtest mais realista.

  4. Introduza filtros quantitativos, configure filtros como ruptura de volume, lacuna do histograma do MACD para evitar falhas.

  5. Otimize as paradas. Avalie diferentes níveis de stop loss fixos e métodos de trailing stop para encontrar paradas ideais.

  6. Execute a estratégia otimizada ao vivo para registrar o desempenho para melhorias adicionais.

Conclusão

A estratégia tem uma lógica clara usando Bandas de Bollinger para determinar a direção da tendência e capturar sinais de ruptura, com a média móvel definindo a tendência geral. Com otimizações adequadas, ela pode se tornar uma tendência estável e confiável após a estratégia.


/*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)


Mais.