Estratégia de fuga baseada em momentum


Data de criação: 2024-02-23 14:27:21 última modificação: 2024-02-23 14:27:21
cópia: 0 Cliques: 641
1
focar em
1617
Seguidores

Estratégia de fuga baseada em momentum

Visão geral

A estratégia de ruptura dinâmica é uma estratégia de tendência que acompanha a dinâmica do mercado. Combina vários indicadores para determinar se o mercado está atualmente em uma tendência ascendente ou descendente, e faz uma posição maior ao romper os pontos críticos de resistência e fechada ao romper os pontos críticos de suporte.

Princípio da estratégia

A estratégia é baseada na determinação de tendências de mercado e níveis-chave de preços através da análise de vários canais de Donchian de longo prazo. Concretamente, ele determina uma tendência ascendente quando o preço ultrapassa um ciclo mais longo, como o canal de Donchian de 40 dias, e emite vários sinais de filtragem com base nisso, incluindo novos altos do ano e uma direção linear da média móvel; e emite um sinal de vazio quando o preço entra em uma trajetória mais longa do ciclo de Donchian, para determinar uma tendência descendente, incluindo novos baixos do ano.

No que diz respeito à saída de posições, a estratégia oferece duas opções: a linha de cancelamento fixo e a parada de rastreamento. A linha de cancelamento fixo é a de estabelecer um ponto de parada com base em períodos mais curtos, como o canal Donchian de 20 dias; a parada de rastreamento é a de um ponto de parada flutuante calculado diariamente com base no valor do ATR.

Análise de vantagens

Esta estratégia, combinada com o discernimento de tendências e a operação de rupturas, é capaz de capturar efetivamente oportunidades direcionais de linhas curtas no mercado. Em comparação com um único indicador, ela usa vários filtros em conjunto, o que pode filtrar algumas das falsas rupturas e, assim, melhorar a qualidade do sinal de entrada. Além disso, a aplicação da estratégia de parada de perdas também a torna mais resistente, mesmo que a regressão seja de curta duração.

Análise de Riscos

O principal risco desta estratégia é que a situação pode ser muito volátil, o que pode levar a que o stop loss seja acionado para sair da posição. Se a situação se inverter rapidamente, a oportunidade pode ser perdida. Além disso, a aplicação de várias condições de filtragem também pode filtrar algumas oportunidades, reduzindo a frequência de posse da estratégia.

Para reduzir o risco, pode-se ajustar adequadamente o valor do ATR ou ampliar o intervalo de órbita Donchian, o que reduz a probabilidade de que a parada seja batida. Também pode-se reduzir ou cancelar parte das condições de filtragem, aumentando a frequência de entrada, mas o risco também aumenta.

Direção de otimização

A estratégia pode ser melhorada em vários aspectos:

  1. Optimizar o comprimento do canal Donchian para encontrar a melhor combinação de parâmetros
  2. Experimentar diferentes tipos de médias móveis como indicadores de fluxo
  3. Ajustar a multiplicação do ATR ou mudar para um ponto fixo de parada
  4. Adicionar mais indicadores de tendência, como o MACD
  5. Optimizar o período de janela de julgamento de novos altos e baixos no ano, etc.

Testando diferentes parâmetros, é possível encontrar a melhor combinação de parâmetros, alcançando um equilíbrio entre riscos e benefícios.

Resumir

Esta estratégia utiliza vários indicadores para determinar a direção da tendência, emitindo sinais de negociação quando os pontos críticos são ultrapassados. Seu mecanismo de stop loss também permite que a estratégia tenha uma maior capacidade de controle de risco. Através da configuração de parâmetros otimizados, a estratégia pode alcançar um lucro excedente estável.

Código-fonte da estratégia
/*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)