Estratégia de criador de mercado de limite de banda de Bollinger

Autora:ChaoZhang, Data: 2024-01-24 11:05:56
Tags:

img

Resumo

Esta é uma estratégia de criador de mercado que usa Bandas de Bollinger como entradas, média móvel como fechamento e stop loss percentual simples.

Estratégia lógica

A estratégia usa as faixas superior e inferior das Bandas de Bollinger como áreas de oportunidade para entrar em posições. Especificamente, quando o preço está abaixo da faixa inferior, será longo para abrir posições longas; quando o preço está acima da faixa superior, será curto para abrir posições curtas.

Além disso, a estratégia também utiliza a média móvel como referência para o fechamento de posições. Ao manter posições longas, se o preço estiver acima da média móvel, optará por fechar longs; da mesma forma, ao manter posições curtas, se o preço estiver abaixo da média móvel, também optará por fechar shorts.

Para o stop loss, ele usa um percentual simples de stop loss baseado no preço de entrada.

Análise das vantagens

As principais vantagens desta estratégia são:

  1. O uso de Bandas de Bollinger pode capturar efetivamente a volatilidade dos preços e obter mais oportunidades de negociação quando a volatilidade aumenta.
  2. As estratégias de criadores de mercado podem beneficiar do spread de compra e venda negociando em ambos os lados.
  3. O percentual de stop loss pode controlar proativamente os riscos e evitar grandes perdas em mercados de tendência.

Análise de riscos

Há também alguns riscos com esta estratégia:

  1. As Bandas de Bollinger nem sempre são sinais de entrada confiáveis e podem dar sinais falsos às vezes.
  2. As estratégias de market maker são vulneráveis a serem destruídas em mercados variados.
  3. A percentagem de stop loss pode ser demasiado bruta e incapaz de se adaptar a situações de mercado complexas.

Para mitigar esses riscos, podemos considerar a adição de outros filtros, otimizar as configurações de stop loss ou limitar adequadamente os tamanhos das posições.

Orientações de otimização

Há espaço para uma maior otimização:

  1. Podemos testar diferentes combinações de parâmetros para encontrar os parâmetros ideais.
  2. Podemos adicionar mais filtros para verificação multifator.
  3. Podemos usar métodos de aprendizagem automática para otimizar parâmetros.
  4. Podemos considerar métodos mais sofisticados de stop loss como SAR parabólica.

Conclusão

No geral, esta é uma estratégia de criação de mercado de alta frequência muito lucrativa. Ele capitaliza as Bandas de Bollinger para sinais de negociação e controla o risco. Mas também precisamos estar cientes de suas falhas e verificar cuidadosamente na negociação ao vivo. Com melhorias adicionais, essa estratégia tem o potencial de gerar retornos ainda mais estáveis e de grande porte.


/*backtest
start: 2023-12-24 00:00:00
end: 2024-01-23 00:00:00
period: 1h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=3
strategy(shorttitle="BBL", title="BB limit", overlay = true)


length = input(200, minval=1)
src = input(hlc3, title="Source")
xmult = input(44, minval=0.001, maxval=5000, title = "bb mult (0.1%)")
s = input(title="Trend source", defval = "sma", options = ["ema", "sma", "rma", "wma"])
basis = s == "ema" ? ema(src, length) : s == "sma" ? sma(src, length) : s =="rma" ? rma(src, length) : wma(src, length)
sd = input(title="Dev source", defval = "stdev", options = ["stdev", "dev"])
mult = xmult / 10  
dev = sd == "stdev" ? mult * stdev(src, length) : mult * dev(src, length)
diff = input(0.5, title = "Spread")
LongPrice(p) =>
    LongPrice = diff == 0 ? p : floor(p / diff) * diff

ShortPrice(p) =>
    ShortPrice = diff == 0 ? p : ceil(p / diff) * diff

pyr = input(1, title = "Pyramiding")
useStopLoss = input(true)
stoploss_xmult = input(15, minval=0.001, maxval=5000, title = "StopLoss 0.1%")
stopLoss_mult = sd == "simple" ? 1 + stoploss_xmult / 10 / 100 : stoploss_xmult / 10  
dev2 = sd == "stdev" ? stopLoss_mult * stdev(src, length) : sd == "dev" ? stopLoss_mult * dev(src, length) : (stopLoss_mult - 1) * basis
upper = basis + (1*dev)
lower = basis - (1*dev)
plot(basis, color=fuchsia, linewidth=2)
plot(upper, color=green, linewidth=2)
plot(lower, color=green, linewidth=2)


strategy.cancel_all()

if strategy.position_size > 0 and close <= basis + diff * 2
    strategy.order("Close long", strategy.short, strategy.position_size, limit = ShortPrice(basis))
else 
    if strategy.position_size < 0 and close >= basis - diff * 2
        strategy.order("Close short", strategy.long, -strategy.position_size, limit = LongPrice(basis))
            
stopLossPrice1 = na
stopLossPrice2 = na
add = na
openOrderCondition = close > lower - 2 * diff and (strategy.opentrades < pyr or (strategy.position_size < 0 and strategy.position_avg_price > lower * (1 + stopLoss_mult / 100)))
if openOrderCondition
    add := strategy.position_size > 0 ? -strategy.position_size : close >= basis - diff * 2 ? 0 : -strategy.position_size
    strategy.order("Open long", strategy.long, strategy.equity / pyr / lower + add, limit = LongPrice(lower))
if useStopLoss and (strategy.position_size > 0 or openOrderCondition)
    add = openOrderCondition ? strategy.equity / pyr / lower : 0
    posPrice = strategy.position_size <= 0 ? lower : strategy.position_avg_price
    posSize = strategy.position_size <= 0 ? 0 : strategy.position_size
    stopLossPrice1 := posPrice * (1 - stopLoss_mult / 100)
    strategy.order("StopLoss open short ", strategy.short, posSize + add + strategy.equity / pyr / stopLossPrice1, stop = ShortPrice(stopLossPrice1))


openOrderCondition := close < upper + 2 * diff and (strategy.opentrades < pyr or (strategy.position_size > 0 and strategy.position_avg_price * (1 + stopLoss_mult / 100) < upper))
if openOrderCondition
    add := strategy.position_size < 0 ? strategy.position_size : close <= basis + diff * 2 ? 0 : strategy.position_size
    strategy.order("Open short", strategy.short, strategy.equity / pyr / upper + add, limit = ShortPrice(upper))
if useStopLoss and (strategy.position_size < 0 or openOrderCondition)
    add = openOrderCondition ? strategy.equity / pyr / upper : 0
    posPrice = strategy.position_size >= 0 ? upper : strategy.position_avg_price
    posSize = strategy.position_size >= 0 ? 0 : -strategy.position_size
    stopLossPrice2 := posPrice * (1 + stopLoss_mult / 100)
    strategy.order("StopLoss open long", strategy.long, posSize + add + strategy.equity / pyr / stopLossPrice2, stop = LongPrice(stopLossPrice2))

plot(not useStopLoss ? na : stopLossPrice1, color=red, linewidth=2)
plot(not useStopLoss ? na : stopLossPrice2, color=red, linewidth=2)

// === Backtesting Dates ===
testPeriodSwitch = input(false, "Custom Backtesting Dates")
testStartYear = input(2018, "Backtest Start Year")
testStartMonth = input(1, "Backtest Start Month")
testStartDay = input(1, "Backtest Start Day")
testStartHour = input(0, "Backtest Start Hour")
testPeriodStart = timestamp(testStartYear,testStartMonth,testStartDay,testStartHour,0)
testStopYear = input(2018, "Backtest Stop Year")
testStopMonth = input(12, "Backtest Stop Month")
testStopDay = input(14, "Backtest Stop Day")
testStopHour = input(14, "Backtest Stop Hour")
testPeriodStop = timestamp(testStopYear,testStopMonth,testStopDay,testStopHour,0)
testPeriod() =>
    time >= testPeriodStart and time <= testPeriodStop ? true : false
isPeriod = testPeriodSwitch == true ? testPeriod() : true
// === /END
if not isPeriod
    strategy.cancel_all()
    strategy.close_all()

Mais.