Estratégia de negociação algorítmica de filtragem de impulso duplo e volatilidade

Autora:ChaoZhang, Data: 22-12-2023 12:01:21
Tags:

img

Resumo

Esta estratégia utiliza essencialmente o cruzamento do duplo ímpeto EMA e do ímpeto DEMA para identificar tendências e incorpora o índice de volatilidade ATR para filtrar falsos breakouts, implementando uma estratégia quantitativa de negociação com indicadores de duplo ímpeto e filtragem de volatilidade.

Princípio da estratégia

Os principais componentes desta estratégia incluem:

  1. Calcule a EMA e a DEMA do preço como indicadores de impulso duplo. O EMA de período mais longo reflete tendências de longo prazo, enquanto a DEMA serve como um indicador de impulso de curto prazo mais sensível. Um sinal de compra é gerado quando a DEMA cruza acima da EMA.

  2. Calcule o índice de volatilidade ATR. Use o valor ATR para determinar a volatilidade do mercado e as condições de liquidez. Filtre os sinais do indicador de impulso quando a volatilidade for muito alta para evitar falhas.

  3. A volatilidade do ATR é julgada como alta ou baixa por uma linha de média móvel parametrizada.

  4. Os parâmetros controlam o período de tempo do ATR, o comprimento do ATR, o tipo e o comprimento da média móvel do ATR, etc.

  5. Estabelecer regras de stop loss, take profit e trailing stop para posições longas.

Análise das vantagens

O filtro duplo da EMA pode reduzir significativamente os sinais falsos e o excesso de negociação em comparação com as estratégias cruzadas básicas da EMA. A adição do índice de volatilidade ATR efetivamente filtra os sinais enganosos de pequenas flutuações e evita ser preso.

Em comparação com os indicadores de momento únicos, o design duplo pode melhorar a eficácia do julgamento.

Ao ajustar os parâmetros do ATR, podem ser estabelecidos limiares de volatilidade adequados para diferentes indicadores, melhorando a adaptabilidade da estratégia.

Análise de riscos

O maior risco é que configurações de parâmetros inadequadas possam resultar em poucos sinais de negociação. comprimentos DEMA e EMA muito longos, ou limiares de volatilidade ATR definidos muito altos, podem minar o desempenho real da estratégia.

Outro risco potencial é que, em condições de mercado extremas, as variações de preços possam violar as restrições do parâmetro ATR, levando a perdas.

Orientações de otimização

  1. Teste diferentes combinações de parâmetros do indicador de momento para encontrar as definições ideais.

  2. Tente substituir os indicadores de ímpeto da EMA dupla pelo MACD ou por outros indicadores.

  3. Teste diferentes configurações de índices de volatilidade, tais como ATR histórico global, índice de volatilidade de mercado, etc.

  4. Adicionar filtragem de volume para evitar o risco de falhas nos preços.

  5. Otimizar os mecanismos de stop loss e take profit para melhorar a relação risco/recompensa.

Conclusão

Esta estratégia integra análise de momento e pesquisa de volatilidade com uma base teórica sólida. Através do ajuste de parâmetros e otimização de lógica, pode se tornar um sistema de negociação algorítmica estável e confiável. Com sinais comerciais claros e riscos controláveis, vale a pena verificar e implementar na negociação ao vivo.


/*backtest
start: 2023-11-21 00:00:00
end: 2023-12-21 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/
// © Qorbanjf

//@version=4
strategy("ORIGIN DEMA/EMA & VOL LONG ONLY", shorttitle="ORIGIN DEMA/EMA & VOL LONG", overlay=true)

// DEMA
length = input(10, minval=1, title="DEMA LENGTH")
src = input(close, title="Source")
e1 = ema(src, length)
e2 = ema(e1, length)
dema1 = 2 * e1 - e2
plot(dema1, "DEMA", color=color.yellow)

//EMA
len = input(25, minval=1, title="EMA Length")
srb = input(close, title="Source")
offset = input(title="Offset", type=input.integer, defval=0, minval=-500, maxval=500)
ema1 = ema(srb, len)
plot(ema1, title="EMA", color=color.blue, offset=offset)


// Inputs
atrTimeFrame = input("D", title="ATR Timeframe", type=input.resolution)
atrLookback = input(defval=14,title="ATR Lookback Period",type=input.integer)
useMA = input(title = "Show Moving Average?", type = input.bool, defval = true)
maType = input(defval="EMA", options=["EMA", "SMA"], title = "Moving Average Type")
maLength = input(defval = 20, title = "Moving Average Period", minval = 1)
//longLossPerc = input(title="Long Stop Loss (%)",
    // type=input.float, minval=0.0, step=0.1, defval=1) * 0.01
longTrailPerc = input(title="Trail stop loss (%)",
     type=input.float, minval=0.0, step=0.1, defval=50) * 0.01
longProfitPerc = input(title="Long Take Profit (%)",
     type=input.float, minval=0.0, step=0.1, defval=3000) / 100

// === INPUT BACKTEST RANGE ===
FromMonth = input(defval = 1, title = "From Month", minval = 1, maxval = 12)
FromDay   = input(defval = 1, title = "From Day", minval = 1, maxval = 31)
FromYear  = input(defval = 2017, title = "From Year", minval = 2000)
ToMonth   = input(defval = 1, title = "To Month", minval = 1, maxval = 12)
ToDay     = input(defval = 1, title = "To Day", minval = 1, maxval = 31)
ToYear    = input(defval = 9999, title = "To Year", minval = 2017)


// ATR Logic // atrValue = atr(atrLookback) // atrp = (atrValue/close)*100 // plot(atrp, color=color.white, linewidth=2, transp = 30)

atrValue = security(syminfo.tickerid, atrTimeFrame, atr(atrLookback))
atrp = (atrValue/close)*100

// Moving Average Logic
ma(maType, src, length) =>
    maType == "EMA" ? ema(src, length) : sma(src, length) //Ternary Operator (if maType equals EMA, then do ema calc, else do sma calc)
maFilter = security(syminfo.tickerid, atrTimeFrame, ma(maType, atrp, maLength))

// variables for enter position
enterLong = crossover(dema1, ema1) and atrp < maFilter

// variables for exit position
sale = crossunder(dema1, ema1)

// stop loss
//longStopPrice  = strategy.position_avg_price * (1 - longLossPerc)

// trail stop
// Determine trail stop loss prices
longStopTrail = 0.0

longStopTrail := if (strategy.position_size > 0)
    stopValue = close * (1 - longTrailPerc)
    max(stopValue, longStopTrail[1])
else
    0
//Take profit Percentage
longExitPrice  = strategy.position_avg_price * (1 + longProfitPerc)

//Enter trades when conditions are met
strategy.entry(id="long",
 long=strategy.long,
 when=enterLong,
 comment="long")

//
strategy.close("long", when = sale, comment = "Sell")
//place exit orders (only executed after trades are active)

strategy.exit(id="sell",
 limit = longExitPrice,
 stop = longStopTrail,
 comment = "SL/TP")



Mais.