A estratégia de ruptura de canal de média móvel adaptativa é uma estratégia de ruptura de tendência baseada na média móvel adaptativa (AMA) e em uma faixa de canal adaptativa para gerar sinais de negociação.
O indicador central desta estratégia é a média móvel adaptativa (AMA), que é usada para capturar a tendência de preços.
AMA (t) = α (t-1) * P (t) + [1 - α (t-1) ] * AMA (t-1)
onde P (t) é o preço atual e α (t) é a constante de suavização entre 0 e 1. α (t) é ajustado dinamicamente de acordo com certas regras para controlar a sensibilidade da AMA às mudanças de preço.
SNRT = (P(t) - AMA(t-1)) / AMA(t-1)
Assim, à medida que as flutuações de preços aumentam, α ((t) aumentará para tornar a AMA mais sensível; quando as flutuações diminuem, α ((t) diminuirá para tornar a AMA mais suave.
Com base no AMA, a estratégia constrói uma faixa de canal adaptável para detectar sinais de ruptura de preços.
Superiores: H (t) = (1 + β*H (t-1)) * AMA (t)
Inferior: L (t) = (1 - β*L (t-1)) * AMA (t)
onde β é um parâmetro ajustável que controla a largura do canal.
Entre em longo quando o preço ultrapassa o nível superior.
Entrar em curto quando o preço quebra abaixo do nível mais baixo.
Caso contrário, fiquem no chão.
As vantagens desta estratégia incluem:
O AMA é mais flexível na captação das tendências dos preços em comparação com as médias móveis simples, especialmente em mercados voláteis.
O canal adaptativo pode ajustar dinamicamente a sua largura, expandindo-se quando a tendência não é clara e estreitando-se quando uma tendência emerge.
Os sinais de ruptura de preço podem capturar a tendência a tempo com taxas de ganho mais altas.
A lógica é simples e clara, fácil de entender e automatizar para negociação quantitativa.
Os riscos desta estratégia incluem:
Os parâmetros de AMA incorretos podem perder a tendência dos preços ou gerar sinais falsos.
Os parâmetros do canal adaptativo, como β, precisam de um ajuste cuidadoso, caso contrário, pode ocorrer muita serralheira ou tendências perdidas.
As rupturas de preços são suscetíveis a falhas, exigindo mais filtros.
A estratégia não inclui mecanismos de gestão de riscos ou de stop loss.
A estratégia pode ser otimizada por:
Melhorar o cálculo α para tornar a AMA mais sensível.
Adicionando mais confirmação após o início das fugas para evitar sinais falsos.
Aplicando filtros como volume ou volatilidade para validar a validade da fuga.
Incorporar o stop loss para bloquear os lucros e controlar o risco.
Otimizar o dimensionamento das posições para diferentes classes de ativos.
Em resumo, a estratégia de ruptura de canal de média móvel adaptativa é uma estratégia de ruptura de tendência simples e prática. Ela usa a AMA flexível para rastrear tendências de preços e um canal adaptativo para detectar sinais de ruptura. A estratégia tem algumas vantagens, mas também riscos potenciais. Com otimizações como ajuste de parâmetros, adição de filtros e melhoria de paradas, ela pode se tornar mais robusta.
/*backtest start: 2022-10-26 00:00:00 end: 2023-11-01 00:00:00 period: 1d basePeriod: 1h exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] */ //@version=4 // CryptoStatistical - 2019 // AMA Strategy Channel Breakout Strategy from E. Durenard - Professional Automated Trading // https://www.amazon.com/Professional-Automated-Trading-Theory-Practice/dp/1118129857 strategy(title="[CS] AMA Strategy - Channel Break Out", shorttitle="AMA_ChannelBreakout_Strategy", initial_capital = 1000, overlay=true, pyramiding = 0, calc_on_every_tick=false, calc_on_order_fills=false, commission_type= strategy.commission.percent, commission_value = 0.08, currency=currency.USD) testStartYear = input(2019, "Backtest Start Year") testStartMonth = input(6, "Backtest Start Month") testStartDay = input(1, "Backtest Start Day") testPeriodStart = timestamp(testStartYear,testStartMonth,testStartDay,0,0) testStopYear = input(2019, "Backtest Stop Year") testStopMonth = input(12, "Backtest Stop Month") testStopDay = input(31, "Backtest Stop Day") testPeriodStop = timestamp(testStopYear,testStopMonth,testStopDay,0,0) testPeriodBackground = input(title="Color Background?", type=input.bool, defval=true) testPeriodBackgroundColor = testPeriodBackground and (time >= testPeriodStart) and (time <= testPeriodStop) ? #00FF00 : na bgcolor(testPeriodBackgroundColor, transp=95) testPeriod() => true price = input(title='Price Source:', type=input.source, defval=close) ama = price hb = price lb = price // Static model parameters minfactor = 0. maxfactor = 1. deviation_max = 1. deviation_min = 1. beta_hb = 1. beta_lb = 1. snr = 1. normalized_atan= 0. alpha = 0.5 // Suggested snr-factor from .5 upto 3.1 by .3 to find best parameter snrfactor = input(title='SNR Factor:', type=input.float, minval=0.6, maxval=3.3, step=0.3, defval=2.1) // Sensitivity Lookback search for the best perdiod from 5 to 20 lookback = input(title='Sensitivity Lookback:', type=input.integer, defval=5) // Suggested Beta from .5 below 4.5 by .3, usually in the range 1.2, 1.5 beta = input(title='Beta:', type=input.float, minval=0.6, maxval=4.5, step=0.3, defval=2.1) offsetlabel = input(title='Offset Label:', type=input.float, minval=0.001, maxval=0.03, step=0.001, defval=0.001) // pi/2 pi2 = 1.5707963267948966 // Zero-lag resampled moving average (Durschner nwma) f_nwma(_src, _period) => fast = _period/2 lambda = _period/fast alpha = lambda * (_period - 1)/(_period - lambda) average1 = wma(_src,_period) average2 = wma(average1,fast) nwma = (1+alpha)*average1 - alpha*average2 ama := alpha[1]*price + (1-alpha[1])*nz(ama[1]) deviation_max := alpha[1]*max((price[0] - price[1])/price[1],0) + (1-alpha[1])*nz(deviation_max[1]) deviation_min := -alpha[1]*min((price[0] - price[1])/price[1],0) + (1-alpha[1])*nz(deviation_min[1]) beta_hb := beta*deviation_max beta_lb := beta*deviation_min hb := (1 + beta_hb[1])*ama lb := (1 - beta_lb[1])*ama snr := if price > hb ((price - ama[1])/ama[1])/beta_lb else if price < lb -((price - ama[1])/ama[1])/beta_hb else 0 normalized_atan := (atan(snrfactor*snr) + pi2)/(2*pi2) alpha := f_nwma(minfactor + (maxfactor - minfactor)*normalized_atan, lookback) plot(ama, color=color.black) plot(hb, color=color.green) plot(lb, color=color.red) // Buy Condition Var bc = false // Sell Condition Var sc = false d = color.black // Buy Condition if(price > hb) bc := true d := color.green // Sell Condition if(price < lb) sc := true d := color.red if(testPeriod()) strategy.entry("Long", strategy.long, when = bc) strategy.entry("Short", strategy.short, when = sc) alertcondition(bc, title='BuyCondition', message='Buy') alertcondition(sc, title='SellCondition', message='Sell') plotshape(title='Buy', series=bc ? price * (1 - offsetlabel) : na, text='A1B', style=shape.labelup, location=location.absolute, color=d, textcolor=color.white, offset=0) plotshape(title='Sell', series=sc ? price * (1 + offsetlabel) : na, text='A1S', style=shape.labeldown, location=location.absolute, color=d, textcolor=color.white, offset=0)