Estratégia quantitativa de acompanhamento das tendências

Autora:ChaoZhang, Data: 2024-02-01 11:42:22
Tags:

img

Resumo

Esta estratégia adota múltiplos indicadores como Bollinger Bands, RSI, ADX, MACD para julgar as tendências do mercado e tem forte capacidade de identificação de tendências.

Princípio da estratégia

  • Use Bandas de Bollinger para julgar se o preço está perto do trilho superior ou inferior para determinar se uma tendência é formada
  • Combinar com o indicador RSI para evitar áreas sobrecompradas e sobrevendidas para evitar falsas rupturas
  • Usar o ADX para determinar a força da tendência e somente sinalizar quando a força da tendência for forte
  • Adotar o MACD para avaliar a coerência das tendências a curto e a longo prazo
  • Limitação das sessões de negociação para evitar riscos overnight

Através do julgamento combinado de múltiplos indicadores, pode identificar com precisão as tendências de preços e acompanhá-las em tempo útil quando a tendência ocorre para alcançar retornos excessivos.

Análise das vantagens

A maior vantagem desta estratégia é que o julgamento da combinação de indicadores é mais abrangente e preciso, o que permite identificar eficazmente as tendências de preços e evitar falsos sinais causados por indicadores únicos.

Especificamente, as vantagens são:

  1. As bandas de Bollinger podem determinar a amplitude e a força da flutuação dos preços
  2. RSI evita comprar em áreas de sobrecompra e vender em áreas de sobrevenda
  3. ADX determina a força da tendência, só segue tendências fortes
  4. O MACD julga a coerência dos preços a curto e a longo prazo
  5. Limitação das sessões de negociação para evitar riscos overnight

Através do julgamento da combinação de indicadores, pode maximizar reduzir os falsos sinais e aumentar a estabilidade da estratégia.

Análise de riscos

Os principais riscos desta estratégia são:

  1. Eventos de mercado que causam falha do indicador
  2. Sinais falsos frequentes em mercados de intervalo

Para o risco 1, a dependência de múltiplos indicadores pode mitigar, até certo ponto, o problema da falha de um único indicador, mas os mecanismos de gestão do risco ainda precisam ser melhorados.

Para o risco 2, os parâmetros podem ser ajustados de forma adequada para uma gama de negociação estreita e reduzir a frequência de negociação para mitigar os riscos.

Orientações de otimização

Os principais aspectos otimizáveis desta estratégia incluem:

  1. Adicionar mecanismos de stop loss, como stop loss de trailing, stop loss de time, stop loss de breakout, etc. para evitar recuo muito profundo
  2. Otimizar parâmetros, ajustar indicador combinação de parâmetros para encontrar o ideal
  3. Adicionar filtros como o filtro de volume para evitar falhas em baixo volume
  4. Incorporar mais indicadores como KDJ, OBV para melhorar a precisão do sinal
  5. Adotar métodos de aprendizagem de máquina para otimizar automaticamente parâmetros

Através da otimização contínua, melhorar continuamente a robustez dos parâmetros e reduzir as probabilidades de falsos sinais.

Resumo

No geral, esta estratégia tem uma capacidade relativamente forte de identificar sinais de tendência através de julgamentos de combinação de indicadores que podem identificar efetivamente as tendências de preços.

Mas também tem certos riscos, a gestão de riscos e a otimização de parâmetros precisam ser continuamente melhoradas para operações estáveis a longo prazo.


/*backtest
start: 2024-01-01 00:00:00
end: 2024-01-31 00:00:00
period: 5h
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/
// © abilash.s.90


dIMinusCalc(adxLen) =>
    
    smoothedTrueRange = 0.0
    smoothedDirectionalMovementMinus = 0.0
    dIMinus = 0.0
    trueRange = 0.0
    directionalMovementMinus = 0.0
    
    trueRange := max(max(high-low, abs(high-nz(close[1]))), abs(low-nz(close[1])))
    directionalMovementMinus := nz(low[1])-low > high-nz(high[1]) ? max(nz(low[1])-low, 0): 0
    
    smoothedTrueRange := nz(smoothedTrueRange[1]) - (nz(smoothedTrueRange[1])/adxLen) + trueRange
    smoothedDirectionalMovementMinus := nz(smoothedDirectionalMovementMinus[1]) - (nz(smoothedDirectionalMovementMinus[1])/adxLen) + directionalMovementMinus
    
    dIMinus := smoothedDirectionalMovementMinus / smoothedTrueRange * 100
    
    dIMinus

dIPlusCalc(adxLen) =>
    
    smoothedTrueRange = 0.0
    smoothedDirectionalMovementPlus = 0.0
    dIPlus =  0.0
    trueRange = 0.0
    directionalMovementPlus = 0.0
    
    trueRange := max(max(high-low, abs(high-nz(close[1]))), abs(low-nz(close[1])))
    directionalMovementPlus := high-nz(high[1]) > nz(low[1])-low ? max(high-nz(high[1]), 0): 0
    
    smoothedTrueRange := nz(smoothedTrueRange[1]) - (nz(smoothedTrueRange[1])/adxLen) + trueRange
    smoothedDirectionalMovementPlus := nz(smoothedDirectionalMovementPlus[1]) - (nz(smoothedDirectionalMovementPlus[1])/adxLen) + directionalMovementPlus
    
    dIPlus := smoothedDirectionalMovementPlus / smoothedTrueRange * 100
    
    dIPlus
    
    
Adx(adxLen) =>
    dIPlus =  0.0
    dIMinus = 0.0
    dX = 0.0
    aDX = 0.0
    dIPlus := dIPlusCalc(adxLen)
    dIMinus := dIMinusCalc(adxLen)
    dX := abs(dIPlus-dIMinus) / (dIPlus+dIMinus)*100
    aDX := sma(dX, adxLen)
    
    aDX
    
BarInSession(sess) => time(timeframe.period, sess) != 0


//@version=4
strategy("Bollinger Band + RSI + ADX + MACD", overlay=true)

//Session

session = input(title="Trading Session", type=input.session, defval="0930-1500")

sessionColor = BarInSession(session) ? color.green : na

bgcolor(color=sessionColor, transp=95)

// Bollinger Bands
src = input(high, title="Bollinger Band Source", type=input.source)
length = input(3, minval=1, type=input.integer, title="Bollinger Band Length")
mult = input(4.989, minval=0.001, maxval=50, step=0.001, type=input.float, title="Bollinger Band Std Dev")
basis = sma(src, length)
dev = mult * stdev(src, length)
upper = basis + dev
lower = basis - dev


plot(upper, title="Bollinger Band Upper", color=color.red)
plot(lower, title="Bollinger Band Lower", color=color.green)

// RSI
rsiSrc = input(close, title="RSI Source", type=input.source)
rsiLength = input(16, minval=1, type=input.integer, title="RSI Length")
rsiComparator = input(39.2, title="RSI Comparator", type=input.float, step=0.1)

rsi = rsi(rsiSrc, rsiLength)

// ADX
adxLength = input(14, minval=1, type=input.integer, title="ADX Length")
adxComparator = input(14, minval=1, type=input.integer, title="ADX Comparator")

adx = Adx(adxLength)

// Heikinashi

haClose = security(heikinashi(syminfo.ticker), timeframe.period, close)
haOpen = security(heikinashi(syminfo.ticker), timeframe.period, open)

nextHaOpen = (haOpen + haClose) / 2

//MACD

macdCalcTypeProcessed = input(title="MACD Source", type=input.source, defval=high)
fast = input(12, title="MACD Fast")
slow = input(20, title="MACD Slow")
signalLen = input(15, title="MACD Signal")

fastMA = ema(macdCalcTypeProcessed, fast)
slowMA = ema(macdCalcTypeProcessed, slow)
macd = fastMA - slowMA
signal = sma(macd, signalLen)



longCondition() =>
    (low < lower) and (rsi[0] > rsiComparator) and (adx > adxComparator) and (close > nextHaOpen) and BarInSession(session) and macd > signal

stop = (close - max((low - (low * 0.0022)), (close - (close * 0.0032)))) / syminfo.mintick
target = (max(upper, (close + (close * 0.0075))) - close) / syminfo.mintick


strategy.entry("SX,LE", strategy.long, when=longCondition(), comment="SX,LE")
strategy.close_all(when=(not BarInSession(session)))
strategy.exit("LX", from_entry="SX,LE", profit=target, loss=stop)


Mais.