Estratégia quantitativa de cruzamento de pares de Bollinger Bands

Autora:ChaoZhang, Data: 2023-12-27 14:28:21
Tags:

img

Resumo

Esta estratégia gera sinais de compra e venda comparando o cruzamento da linha rápida e linha lenta do indicador MACD. Quando um sinal de compra é gerado, ele abrirá uma posição com uma certa porcentagem do patrimônio da conta. Posições adicionais serão adicionadas em pontos de retração específicos. Quando o lucro acumulado das posições atingir o ponto de lucro configurado, todas as posições serão fechadas. A lógica para sinais de venda é semelhante aos sinais de compra.

Estratégia lógica

A lógica central desta estratégia é comparar o cruzamento da linha rápida e lenta do MACD para determinar a tendência.

Quando a linha rápida cruza acima da linha lenta, uma cruz de ouro é gerada, indicando que o mercado está em uma tendência ascendente, e a estratégia abrirá posições longas.

Após a abertura de posições, a estratégia será adicionada a posições longas ou curtas existentes em pontos de retração específicos. Isso pode aumentar o potencial de lucro através do princípio Martingale.

Análise das vantagens

Esta estratégia tem as seguintes vantagens:

  1. Utiliza o indicador MACD para determinar a tendência do mercado, que é um indicador clássico e confiável de análise técnica.

  2. Adota a abordagem da abertura de posições em lotes, que pode controlar o risco de uma única negociação.

  3. A adição de posições pode expandir o potencial de lucro através do princípio de Martingale.

  4. Configurar o ponto de lucro para limitar as perdas.

Análise de riscos

Esta estratégia tem também alguns riscos:

  1. O indicador MACD não pode prever perfeitamente os movimentos do mercado, podendo ocorrer sinais falsos.

  2. O risco de expansão do retracement com a adição de posições completas pode ajustar adequadamente a percentagem de cada posição adicionada.

  3. A fixação de um ponto de lucro demasiado baixo pode limitar o potencial de lucro.

  4. Precisa de definir uma percentagem razoável do capital para a abertura de posições por produto, a fim de evitar o excesso dos limites da conta.

Orientações de otimização

Esta estratégia pode ser otimizada nos seguintes aspectos:

  1. Teste os parâmetros do MACD, encontre parâmetros que se adequem melhor a produtos comerciais específicos.

  2. Otimizar percentagem de dinheiro e percentagem de retracement para cada posição adicionada, encontrar combinações de parâmetros ideais.

  3. Teste pontos de lucro a longo prazo e a curto prazo, respectivamente, para determinar os níveis ideais.

  4. Avaliar a capacidade de margem da conta, definir um limite máximo razoável de posição por produto.

  5. Adicione a lógica de stop loss. Stop loss pode controlar efetivamente as perdas quando ocorre uma mudança drástica no mercado.

Resumo

Em resumo, esta é uma estratégia típica de seguimento de tendências. Ele usa o indicador MACD para determinar a direção da tendência do mercado, adota a abordagem de adicionar posições em lotes para seguir a tendência e tira lucro quando o lucro acumulado atinge um certo nível. Esta estratégia simples e prática é fácil de implementar e adequada para iniciantes em negociação quantitativa. Ao otimizar os parâmetros e expandir a lógica de controle de risco, a estratégia pode se tornar mais robusta.


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

// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © TradingSoft_tech

//@version=5
strategy("MAPM-V1", overlay=true, default_qty_value=10, max_bars_back=5000,default_qty_type = strategy.percent_of_equity, commission_value=0.1, initial_capital = 100, pyramiding=6, currency=currency.USD)

///////// Options
SignalFast = input.int(300, step=10)
SignalSlow = input.int(600, step=10)
StepAddPurchases = input.float(2.5, step=0.1)
VolumePurchases = input.int(6,step=1)
Buy = input(true)
Sell = input(true)
longProfitPerc = input.float(title="Long Take Profit (%)", minval=0.0, step=0.1, defval=1) * 0.01
shortProfitPerc = input.float(title="Short Take Profit (%)", minval=0.0, step=0.1, defval=1) * 0.01
Martingale = input.float(1.6, minval = 1, step = 0.1)
VolumeDepo = input.int(100, step=1)
PercentOfDepo = input.float(10, step=1)
Close = (close)
EnterVolume = VolumeDepo*PercentOfDepo*0.01/Close

///////// Calculation indicator
fastAverage = ta.ema(close, 8)
slowAverage = ta.ema(close, 49)
macd = fastAverage - slowAverage
macdSignalF = ta.ema(macd,SignalFast)
macdSignalS = ta.ema(macd,SignalSlow)

// Test Start
startYear = input(2005, "Test Start Year")
startMonth = input(1, "Test Start Month")
startDay = input(1, "Test Start Day")
startTest = timestamp(startYear,startMonth,startDay,0,0)

//Test End
endYear = input(2050, "Test End Year")
endMonth = input(12, "Test End Month")
endDay = input(30, "Test End Day")
endTest = timestamp(endYear,endMonth,endDay,23,59)

timeRange = time > startTest and time < endTest ? true : false

///////// Plot Data
//plot(macd, style = plot.style_histogram)
//plot(macdSignalF*10000, style = plot.style_line, color=color.red)
//plot(macdSignalS*10000, style = plot.style_line, color=color.blue)
//plot(fastAverage, style = plot.style_line, color=color.red)
//plot(slowAverage, style = plot.style_line, color=color.blue)

///////// Calculation of the updated value
var x = 0.0
if strategy.opentrades>strategy.opentrades[1]
    x := x + 1
else if strategy.opentrades==0
    x := 0
y = x+1

///////// Calculation of reference price data
entryPrice = strategy.opentrades==0? 0 : strategy.opentrades.entry_price(0)
limitLong = strategy.position_avg_price * (1 + longProfitPerc)
limitShort = strategy.position_avg_price * (1 - shortProfitPerc)
SteplimitLong = entryPrice[0]*(1-StepAddPurchases*y/100)
SteplimitShort = entryPrice[0]*(1+StepAddPurchases*y/100)

///////// Conditions for a long
bool EntryLong = ta.crossover(macdSignalF, macdSignalS) and Buy and strategy.opentrades==0 and strategy.position_size==0
bool PurchasesLong = Buy and strategy.opentrades==x and strategy.position_size>0 and x<=VolumePurchases
bool CancelPurchasesLong = strategy.position_size==0 and strategy.opentrades==0
bool TPLong = strategy.position_size>0 and strategy.opentrades!=0
///////// Entry Long + add.purchases + cancel purchases + Take profit Long
switch 
    EntryLong => strategy.entry("Entry Long", strategy.long, qty = EnterVolume)
    PurchasesLong => strategy.entry("PurchasesLong", strategy.long, qty = EnterVolume*math.pow(Martingale,y), limit = SteplimitLong)
    CancelPurchasesLong => strategy.cancel("PurchasesLong")
switch
    TPLong => strategy.exit("TPLong", qty_percent = 100, limit = limitLong)

///////// Conditions for a Short
bool EntryShort = ta.crossunder(macdSignalF, macdSignalS) and Sell and strategy.opentrades==0 and strategy.position_size==0
bool PurchasesShort = Sell and strategy.opentrades==x and strategy.position_size<0 and x<=VolumePurchases
bool CancelPurchasesShort = strategy.position_size==0 and strategy.opentrades==0
bool TPShort = strategy.position_size<0 and strategy.opentrades!=0

///////// Entry Short + add.purchases + cancel purchases + Take profit Short
switch
    EntryShort => strategy.entry("Entry Short", strategy.short, qty = EnterVolume)
    PurchasesShort => strategy.entry("PurchasesShort", strategy.short, qty = EnterVolume*math.pow(Martingale,y), limit = SteplimitShort)
    CancelPurchasesShort => strategy.cancel("PurchasesShort")
switch
    TPShort => strategy.exit("TPShort", qty_percent = 100, limit = limitShort)
    
/////////Calculation of conditions and reference data for level drawing
InTradeLong = strategy.position_size<0
InTradeShort = strategy.position_size>0
PickInLong = strategy.opentrades.entry_price(0)*(1-StepAddPurchases*y/100)
PickInShort = strategy.opentrades.entry_price(0)*(1+StepAddPurchases*y/100)

/////////Displaying the level of Take Profit
plot(InTradeLong ? na : limitLong, color=color.new(#00d146, 0), style=plot.style_linebr, linewidth=1)
plot(InTradeShort ? na : limitShort, color=color.new(#00d146, 0), style=plot.style_linebr, linewidth=1)

/////////Displaying the level of add.purchases
plot(InTradeLong ? na : PickInLong, color=color.white, style=plot.style_linebr, linewidth=1)
plot(InTradeShort ? na : PickInShort, color=color.white, style=plot.style_linebr, linewidth=1)

Mais.