Estratégia de inversão de média móvel dupla

Autora:ChaoZhang, Data: 2023-12-25 13:24:14
Tags:

img

Resumo

A estratégia de inversão de média móvel dupla é uma estratégia quantitativa de negociação que utiliza médias móveis duplas para identificar tendências de curto e longo prazo.

Estratégia lógica

A estratégia de reversão da média móvel dupla baseia-se nos seguintes pressupostos:

  1. A SMA de 200 dias identifica a tendência de longo prazo predominante do mercado. Quando o preço está acima da linha de 200 dias, ele sinaliza que o mercado está em uma tendência de alta de longo prazo.

  2. A SMA de 10 dias indica pullbacks de curto prazo no preço. Quando o preço cai abaixo da linha de 10 dias, indica que ocorreu um pullback temporário.

  3. Em uma tendência de alta do mercado de alta em curso, qualquer retração a curto prazo pode ser vista como uma oportunidade de compra para capturar de forma eficiente o rebote ascendente.

Com base nos pressupostos acima referidos, os sinais comerciais são gerados da seguinte forma:

  1. Quando o preço de fechamento cruza acima da SMA de 200 dias e cruza simultaneamente abaixo da SMA de 10 dias, ele desencadeia um sinal de compra, pois mostra que a tendência de longo prazo permanece positiva, mas ocorreu uma retração de curto prazo.

  2. Se o preço retrocede acima da SMA de 10 dias quando em uma posição longa, a tendência de curto prazo se inverteu, de modo que a posição será fechada imediatamente.

  3. Sempre que ocorre uma grande desaceleração (excedendo um limiar predefinido), apresenta uma oportunidade para comprar a queda como sinal contrário.

Com esta concepção, a estratégia visa capitalizar de forma eficiente os snapbacks ascendentes durante tendências ascendentes sustentadas, controlando o risco utilizando stop losses.

Vantagens

A estratégia de inversão de média móvel dupla tem as seguintes vantagens principais:

  1. A lógica estratégica é direta e facilmente compreensível.
  2. Os dois filtros de média móvel identificam eficazmente as tendências a curto e a longo prazo.
  3. Oferece uma boa eficiência de tempo, capitalizando as reversões de curto prazo.
  4. O mecanismo de stop loss integrado controla rigorosamente o risco das posições individuais.
  5. A parametrização flexível torna esta estratégia amplamente aplicável a índices e ações.

Riscos

Apesar de ser eficaz em geral, a estratégia tem as seguintes limitações:

  1. A estratégia deve ser desativada durante consolidações prolongadas.
  2. A dependência exclusivamente de médias móveis tem limitações de precisão do sinal.
  3. A metodologia de stop loss fixo não é flexível, podendo ser testadas outras técnicas.
  4. Os parâmetros ótimos devem ser calibrados para diferentes mercados.

Oportunidades de melhoria

Outras melhorias desta estratégia incluem:

  1. Teste de outras medias móveis de comprimento para encontrar a combinação ideal.
  2. Adicionar indicadores de apoio para gerar sinais mais fiáveis, por exemplo, volume, métricas de volatilidade.
  3. Explorando outras técnicas de stop loss como trailing stop loss, stop loss baseado no tempo.
  4. Desenvolver capacidades de adaptação nas regras de entrada e nos parâmetros de stop loss que permitam o ajustamento às mudanças da dinâmica do mercado.
  5. Incorporar algoritmos de aprendizagem de máquina para otimizar ainda mais os parâmetros aproveitando mais dados históricos.

Conclusão

Em resumo, a Estratégia de Reversão de Média Móvel Dupla é uma abordagem altamente prática. Ela permite a diminuição de pullback lucrativo durante tendências de alta sustentadas usando análise de média móvel emparelhada com stop losses. Também oferece capacidades de detecção de regime de mercado e controle de risco. Com melhoria contínua, a estratégia oferece um forte potencial para oferecer desempenho diferenciado.


/*backtest
start: 2023-11-24 00:00:00
end: 2023-12-24 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/
// © Gold_D_Roger
//note: spreading 1 statement over multiple lines needs 1 apce + 1 tab | multi line function is 1 tab
//Recommended tickers: SPY (D), QQQ (D) and big indexes, AAPL (4H)

//@version=5
strategy("Davin's 10/200MA Pullback on SPY Strategy v2.0",
     overlay=true,
     initial_capital=10000,
     default_qty_type=strategy.percent_of_equity,
     default_qty_value=10, // 10% of equity on each trade
     commission_type=strategy.commission.cash_per_contract, 
     commission_value=0.1) //Insert your broker's rate, IB is 0.005USD or tiered

//Best parameters
// SPY D
// Stop loss 0.15
// commission of 0.005 USD using Interactive brokers
// Exit on lower close 
// Buy more when x% down --> 14%
// DO NOT include stop condition using MA crossover

// Get User Input
i_ma1           = input.int(title="MA Length 1", defval=200, step=10, group="Strategy Parameters", tooltip="Long-term MA 200")
i_ma2           = input.int(title="MA Length 2", defval=10, step=10, group="Strategy Parameters", tooltip="Short-term MA 10")
i_ma3           = input.int(title="MA Length 3", defval=50, step=1, group="Strategy Parameters", tooltip="MA for crossover signals`")
i_stopPercent   = input.float(title="Stop Loss Percent", defval=0.15, step=0.01, group="Strategy Parameters", tooltip="Hard stop loss of 10%")
i_startTime     = input(title="Start filter", defval=timestamp("01 Jan 2013 13:30 +0000"), group="Time filter", tooltip="Start date and time to begin")
i_endTime       = input(title="End filter", defval=timestamp("01 Jan 2099 19:30 +0000"), group="Time filter", tooltip="End date and time to stop")
i_lowerClose    = input.bool(title="Exit on lower close", defval=true, group="Strategy Parameters", tooltip="Wait for lower close after above 10SMA before exiting") // optimise exit strat, boolean type creates tickbox type inputs
i_contrarianBuyTheDip = input.bool(title="Buy whenever more than x% drawdown", defval=true, group="Strategy Parameters", tooltip="Buy the dip! Whenever x% or more drawdown on SPY")
i_contrarianTrigger = input.int(title="Trigger % drop to buy the dip", defval=14, step=1, group="Strategy Parameters", tooltip="% drop to trigger contrarian Buy the Dip!") 
//14% to be best for SPY 1D
//20% best for AMZN 1D
i_stopByCrossover_MA2_3 = input.bool(title="Include stop condition using MA crossover", defval=false, group="Strategy Parameters", tooltip="Sell when crossover of MA2/1 happens")

// Get indicator values
ma1 = ta.sma(close,i_ma1) //param 1
ma2 = ta.sma(close,i_ma2) //param 2
ma3 = ta.sma(close,i_ma3) //param 3
ma_9 = ta.ema(close,9) //param 2
ma_20 = ta.ema(close,20) //param 3

// Check filter(s)
f_dateFilter = true //make sure date entries are within acceptable range

// Highest price of the prev 52 days: https://www.tradingcode.net/tradingview/largest-maximum-value/#:~:text=()%20versus%20ta.-,highest(),max()%20and%20ta.
highest52 = ta.highest(high,52)
overall_change = ((highest52 - close[0]) / highest52) * 100

// Check buy/sell conditions
var float buyPrice = 0 //intialise buyPrice, this will change when we enter a trade ; float = decimal number data type 0.0
buyCondition  = (close > ma1 and close < ma2 and strategy.position_size == 0 and f_dateFilter) or (strategy.position_size == 0 and i_contrarianBuyTheDip==true and overall_change > i_contrarianTrigger and f_dateFilter) // higher than 200sma, lower than short term ma (pullback) + avoid pyramiding positions
sellCondition = close > ma2 and strategy.position_size > 0 and (not i_lowerClose or close < low[1])  //check if we already in trade + close above 10MA; 
// third condition: EITHER i_lowerClose not turned on OR closing price has to be < previous candle's LOW [1]

stopDistance  = strategy.position_size > 0 ? ((buyPrice - close)/close) : na // check if in trade > calc % drop dist from entry, if not na
stopPrice     = strategy.position_size > 0 ? (buyPrice - (buyPrice * i_stopPercent)) : na // calc SL price if in trade, if not, na
stopCondition = (strategy.position_size > 0 and stopDistance > i_stopPercent) or (strategy.position_size > 0 and (i_stopByCrossover_MA2_3==true and ma3 < ma1))


// Enter positions
if buyCondition 
    strategy.entry(id="Long", direction=strategy.long) //long only

    
if buyCondition[1] // if buyCondition is true prev candle
    buyPrice := open // entry price = current bar opening price

// Exit position
if sellCondition or stopCondition 
    strategy.close(id="Long", comment = "Exit" + (stopCondition ? "Stop loss=true" : "")) // if condition? "Value for true" : "value for false"
    buyPrice := na //reset buyPrice

// Plot
plot(buyPrice, color=color.lime, style=plot.style_linebr)
plot(stopPrice, color=color.red, style=plot.style_linebr, offset = -1)
plot(ma1, color=color.blue) //defval=200
plot(ma2, color=color.white) //defval=10
plot(ma3, color=color.yellow) // defval=50






Mais.