A estratégia de ruptura do impulso

Autora:ChaoZhang, Data: 2024-02-23 14:27:21
Tags:

img

Resumo

A estratégia de ruptura de impulso é uma estratégia de tendência que acompanha o impulso do mercado. Ela combina vários indicadores para julgar se o mercado está atualmente em uma tendência ascendente ou descendente, e abre posições longas ao quebrar os níveis de resistência chave e abre posições curtas ao quebrar os níveis de suporte chave.

Estratégia lógica

Esta estratégia usa principalmente os canais de Donchian de vários prazos para determinar as tendências do mercado e os principais níveis de preços. Especificamente, quando os preços atravessam o trilho superior do canal de Donchian de longo prazo, como 40 dias, ele é julgado como uma tendência de alta. Junto com filtros adicionais como novas altas dentro do ano e o alinhamento das médias móveis, sinais longos são desencadeados. Quando os preços quebram abaixo do trilho inferior do canal de Donchian de longo prazo, ele é julgado como uma tendência de queda. Junto com filtros como novas mínimas dentro do ano, sinais curtos são desencadeados.

A estratégia fornece duas opções para posições de saída: linha de invalidação fixa e stop loss de trail. A linha de invalidação fixa usa o trilho inferior/superior de um canal de Donchian mais curto, como 20 dias. A linha de stop loss de trail calcula uma linha de stop loss dinâmica todos os dias com base nos valores ATR. Ambos os métodos podem controlar os riscos de forma eficaz.

Análise das vantagens

Esta estratégia combina o julgamento da tendência e as operações de ruptura, que podem capturar efetivamente oportunidades direcionais de curto prazo no mercado. Em comparação com indicadores únicos, ele usa vários filtros que podem filtrar algumas rupturas falsas e melhorar a qualidade dos sinais de entrada. Além disso, a aplicação de estratégias de stop loss também aumenta sua resiliência e pode controlar efetivamente as perdas mesmo se o mercado recuar brevemente.

Análise de riscos

O principal risco desta estratégia é que os preços podem flutuar violentamente, desencadeando stop losses para as posições de saída. Se os preços reverterem rapidamente depois, as oportunidades podem ser perdidas. Além disso, o uso de múltiplos filtros também pode filtrar algumas oportunidades e reduzir a frequência das negociações.

Para reduzir os riscos, os múltiplos de ATR podem ser ajustados ou os intervalos do canal de Donchian podem ser ampliados para diminuir a probabilidade de uma perda de parada ser atingida.

Orientações de otimização

Esta estratégia pode ser otimizada nos seguintes aspectos:

  1. Otimizar os comprimentos dos canais de Donchian para encontrar a melhor combinação de parâmetros.
  2. Tente diferentes tipos de médias móveis como filtros.
  3. Ajustar o multiplicador ATR ou utilizar pontos fixos para o stop loss.
  4. Adicione mais indicadores de tendência como o MACD.
  5. Otimizar os períodos de revisão para novos máximos/mínimos no ano, etc.

Ao testar diferentes parâmetros, pode ser encontrada a combinação ideal de equilíbrio de riscos e rendimentos.

Conclusão

Esta estratégia combina múltiplos indicadores para determinar a direção da tendência e desencadeia negociações em níveis de ruptura-chave. Seu mecanismo de stop loss também o torna resistente aos riscos. Ao otimizar parâmetros, retornos excessivos estáveis podem ser alcançados. É adequado para investidores que não têm uma visão clara do mercado, mas desejam seguir as tendências.


/*backtest
start: 2024-01-23 00:00:00
end: 2024-02-22 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/
// © HeWhoMustNotBeNamed

//@version=4
strategy("BuyHigh-SellLow Strategy", overlay=true, initial_capital = 10000, default_qty_type = strategy.percent_of_equity, default_qty_value = 100, commission_type = strategy.commission.percent, pyramiding = 1, commission_value = 0.01, calc_on_order_fills = true)
donchianEntryLength = input(40, step=10)
donchianExitLength = input(20, step=10)

considerNewLongTermHighLows = input(true)
shortHighLowPeriod = input(120, step=10)
longHighLowPeriod = input(180, step=10)

considerMAAlignment = input(true)
MAType = input(title="Moving Average Type", defval="ema", options=["ema", "sma", "hma", "rma", "vwma", "wma"])
LookbackPeriod = input(40, minval=10,step=10)

atrLength = input(22)
atrMult = input(4)

exitStrategy = input(title="Exit Strategy", defval="tsl", options=["dc", "tsl"])

considerYearlyHighLow = input(true)
backtestYears = input(10, minval=1, step=1)
f_getMovingAverage(source, MAType, length)=>
    ma = sma(source, length)
    if(MAType == "ema")
        ma := ema(source,length)
    if(MAType == "hma")
        ma := hma(source,length)
    if(MAType == "rma")
        ma := rma(source,length)
    if(MAType == "vwma")
        ma := vwma(source,length)
    if(MAType == "wma")
        ma := wma(source,length)
    ma

f_getTrailingStop(atr, atrMult)=>
    stop = close - atrMult*atr
    stop := strategy.position_size > 0 ? max(stop, stop[1]) : stop
    stop

f_getMaAlignment(MAType, includePartiallyAligned)=>
    ma5 = f_getMovingAverage(close,MAType,5)
    ma10 = f_getMovingAverage(close,MAType,10)
    ma20 = f_getMovingAverage(close,MAType,20)
    ma30 = f_getMovingAverage(close,MAType,30)
    ma50 = f_getMovingAverage(close,MAType,50)
    ma100 = f_getMovingAverage(close,MAType,100)
    ma200 = f_getMovingAverage(close,MAType,200)

    upwardScore = 0
    upwardScore := close > ma5? upwardScore+1:upwardScore
    upwardScore := ma5 > ma10? upwardScore+1:upwardScore
    upwardScore := ma10 > ma20? upwardScore+1:upwardScore
    upwardScore := ma20 > ma30? upwardScore+1:upwardScore
    upwardScore := ma30 > ma50? upwardScore+1:upwardScore
    upwardScore := ma50 > ma100? upwardScore+1:upwardScore
    upwardScore := ma100 > ma200? upwardScore+1:upwardScore
    
    upwards = close > ma5 and ma5 > ma10 and ma10 > ma20 and ma20 > ma30 and ma30 > ma50 and ma50 > ma100 and ma100 > ma200
    downwards = close < ma5 and ma5 < ma10 and ma10 < ma20 and ma20 < ma30 and ma30 < ma50 and ma50 < ma100 and ma100 < ma200
    upwards?1:downwards?-1:includePartiallyAligned ? (upwardScore > 5? 0.5: upwardScore < 2?-0.5:upwardScore>3?0.25:-0.25) : 0

//////////////////////////////////// Calculate new high low condition //////////////////////////////////////////////////
f_calculateNewHighLows(shortHighLowPeriod, longHighLowPeriod, considerNewLongTermHighLows)=>
    newHigh = highest(shortHighLowPeriod) == highest(longHighLowPeriod) or not considerNewLongTermHighLows
    newLow = lowest(shortHighLowPeriod) == lowest(longHighLowPeriod) or not considerNewLongTermHighLows
    [newHigh,newLow]

//////////////////////////////////// Calculate Yearly High Low //////////////////////////////////////////////////
f_getYearlyHighLowCondition(considerYearlyHighLow)=>
    yhigh = security(syminfo.tickerid, '12M', high[1]) 
    ylow = security(syminfo.tickerid, '12M', low[1]) 
    yhighlast = yhigh[365]
    ylowlast = ylow[365]
    yhighllast = yhigh[2 * 365]
    ylowllast = ylow[2 * 365]
    
    yearlyTrendUp = na(yhigh)? true : na(yhighlast)? close > yhigh : na(yhighllast)? close > max(yhigh,yhighlast) : close > max(yhigh, min(yhighlast, yhighllast))
    yearlyHighCondition = (  (na(yhigh) or na(yhighlast) ? true : (yhigh > yhighlast) ) and ( na(yhigh) or na(yhighllast) ? true : (yhigh > yhighllast))) or yearlyTrendUp or not considerYearlyHighLow
    yearlyTrendDown = na(ylow)? true : na(ylowlast)? close < ylow : na(ylowllast)? close < min(ylow,ylowlast) : close < min(ylow, max(ylowlast, ylowllast))
    yearlyLowCondition = (  (na(ylow) or na(ylowlast) ? true : (ylow < ylowlast) ) and ( na(ylow) or na(ylowllast) ? true : (ylow < ylowllast))) or yearlyTrendDown or not considerYearlyHighLow
    
    label_x = time+(60*60*24*1000*1)
    [yearlyHighCondition,yearlyLowCondition]

donchian(rangeLength)=>
    upper = highest(rangeLength)
    lower = lowest(rangeLength)
    middle = (upper+lower)/2
    [middle, upper, lower]

inDateRange = true
[eMiddle, eUpper, eLower] = donchian(donchianEntryLength)
[exMiddle, exUpper, exLower] = donchian(donchianExitLength)
maAlignment = f_getMaAlignment(MAType, false)
[yearlyHighCondition, yearlyLowCondition] = f_getYearlyHighLowCondition(considerYearlyHighLow)
[newHigh,newLow] = f_calculateNewHighLows(shortHighLowPeriod, longHighLowPeriod, considerNewLongTermHighLows)

maAlignmentLongCondition = highest(maAlignment, LookbackPeriod) == 1 or not considerMAAlignment 

atr = atr(atrLength)
tsl = f_getTrailingStop(atr, atrMult)

//U = plot(eUpper, title="Up", color=color.green, linewidth=2, style=plot.style_linebr)
//D = plot(exLower, title="Ex Low", color=color.red, linewidth=2, style=plot.style_linebr)
longCondition = crossover(close, eUpper[1]) and yearlyHighCondition and newHigh and maAlignmentLongCondition
exitLongCondition = crossunder(close, exLower[1])

shortCondition = crossunder(close, eLower[1]) and yearlyLowCondition and newLow
exitShortCondition = crossover(close, exUpper[1])
strategy.entry("Buy", strategy.long, when=longCondition and inDateRange, oca_name="oca_buy")
strategy.exit("ExitBuyDC", "Buy", when=exitStrategy=='dc', stop=exLower)
strategy.exit("ExitBuyTSL", "Buy", when=exitStrategy=='tsl', stop=tsl)
plot(strategy.position_size > 0 ? (exitStrategy=='dc'?exLower:tsl) : na, title="Trailing Stop", color=color.red, linewidth=2, style=plot.style_linebr)
//strategy.close("Buy", when=exitLongCondition)

Mais.