A estratégia de seguimento de tendência de média móvel exponencial dupla é uma estratégia de seguimento de tendência baseada em cruzamento de média móvel exponencial (EMA). Ele julga a direção da tendência atual calculando a linha EMA rápida e a linha EMA lenta e age sobre seus cruzamento. Quando a linha EMA rápida cruza acima da linha EMA lenta, ela é determinada como um sinal de alta. Quando a linha EMA rápida cruza abaixo da linha EMA lenta, ela é determinada como um sinal de baixa. Com base na direção da tendência identificada, essa estratégia pode ir longa ou curta, em conformidade.
A lógica central desta estratégia consiste em calcular duas linhas EMA de períodos diferentes - uma atua como a linha de baixa e outra como a linha de alta. Especificamente, a estratégia calcula uma linha EMA rápida de 8 períodos usando o indicador talib como a linha de alta. E calcula uma linha EMA lenta de 21 períodos como a linha de baixa. Em seguida, julga as relações de cruzamento entre a linha EMA rápida e a linha EMA lenta. Quando a linha rápida cruza acima da linha lenta, determina um sinal de alta para ir longo. Quando a linha rápida cruza abaixo da linha lenta, determina um sinal de baixa para ir curto.
Em termos de execução comercial real, esta estratégia pode ir longo apenas, ir curto apenas, ou ir em ambos os sentidos quando ocorre cruzamento entre linhas rápidas e lentas. Além disso, os preços de stop loss e take profit são configurados na estratégia. Após a abertura de posições, se o preço for em direção desfavorável, o stop loss será desencadeado para posições de saída. Se o preço atingir o nível alvo esperado, o take profit será realizado e as posições fechadas.
A maior vantagem da estratégia Dual EMA Trend Following reside na poderosa capacidade de identificação de tendências de cruzamento de médias móveis. Como uma ferramenta comum para análise de tendências, as linhas EMA podem identificar mudanças de tendência e pontos de virada através de cruzamento, evitando ser enganadas por ruídos de mercado a curto prazo e capturando a direção principal da tendência.
Além disso, as configurações flexíveis nas direcções de negociação tornam a estratégia adaptável tanto a tendências unidirecionais como a oscilações bidirecionais, aumentando assim a aplicabilidade da estratégia.
O maior risco desta estratégia são os sinais falsos desencadeados por pequenos crossovers frequentes em mercados de intervalo. Isso levaria a abertura e perdas excessivas de posições. Para combater isso, podemos aumentar os períodos de EMA para reduzir os tempos de crossover e as probabilidades de sinal falso.
Por outro lado, uma configuração de stop loss muito apertada também aumenta a chance de ser parado fora.
Esta estratégia pode ser melhorada nos seguintes aspectos:
Ajuste adaptativo dos períodos de EMA com base na volatilidade do mercado e nos resultados dos backtests, evitando o sobreajuste em períodos fixos.
Adicionar condições de filtragem para filtrar sinais falsos, por exemplo, combinar com os volumes de negociação para filtrar crossovers insignificantes; ou combinar outros indicadores como MACD e KDJ para evitar sinais de incerteza.
Otimizar as estratégias de stop loss e take profit, por exemplo, combinando ATR para realizar trailing dinâmico no SL/TP, evitando SL excessivamente apertado e TP prematuro.
Teste de diferentes períodos de detenção. Períodos de detenção muito longos podem ser impactados por incidentes, enquanto períodos muito curtos levam a altos custos de negociação e custos de deslizamento. Encontrar os dias de detenção ideais pode melhorar a rentabilidade da estratégia.
Em geral, a estratégia de seguimento de tendências é um sistema de negociação de tendências robusto e prático. Ele capta direções de tendências efetivamente através do sistema de cruzamento da EMA. Enquanto isso, as configurações flexíveis nas direções de negociação tornam-no adaptável; os riscos de controle de stop loss e take profit configurados. Com novas otimizações e aprimoramentos, essa estratégia pode se tornar uma ferramenta poderosa para negociação quantitativa.
/*backtest start: 2024-01-02 00:00:00 end: 2024-02-01 00:00:00 period: 2h 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/ // © TradersPostInc //@version=5 strategy('TradersPost Example MOMO Strategy', overlay=true, default_qty_value=100, initial_capital=100000, default_qty_type=strategy.percent_of_equity, pyramiding=0) startTime = input(defval = timestamp('01 Jan 2021 00:00 +0000'), title = 'Start Time', group = 'Date Range') endTime = input(defval = timestamp('31 Dec 2023 23:59 +0000'), title = 'End Time', group = 'Date Range') timeCondition = true timeConditionEnd = timeCondition[1] and not timeCondition fastEmaLength = input.int(defval = 8, title = 'Fast EMA Length') slowEmaLength = input.int(defval = 21, title = 'Slow EMA Length') sides = input.string(defval = 'Both', title = 'Sides', options = ['Long', 'Short', 'Both', 'None']) fastEma = ta.ema(close, fastEmaLength) slowEma = ta.ema(close, slowEmaLength) isUptrend = fastEma >= slowEma isDowntrend = fastEma <= slowEma trendChanging = ta.cross(fastEma, slowEma) ema105 = request.security(syminfo.tickerid, '30', ta.ema(close, 105)[1], barmerge.gaps_off, barmerge.lookahead_on) ema205 = request.security(syminfo.tickerid, '30', ta.ema(close, 20)[1], barmerge.gaps_off, barmerge.lookahead_on) plot(ema105, linewidth=4, color=color.new(color.purple, 0), editable=true) plot(ema205, linewidth=2, color=color.new(color.purple, 0), editable=true) aa = plot(fastEma, linewidth=3, color=color.new(color.green, 0), editable=true) bb = plot(slowEma, linewidth=3, color=color.new(color.red, 0), editable=true) fill(aa, bb, color=isUptrend ? color.green : color.red, transp=90) tradersPostBuy = trendChanging and isUptrend and timeCondition tradersPostSell = trendChanging and isDowntrend and timeCondition pips = syminfo.pointvalue / syminfo.mintick percentOrPipsInput = input.string('Percent', title='Percent or Pips', options=['Percent', 'Pips']) stopLossLongInput = input.float(defval=0, step=0.01, title='Stop Loss Long', minval=0) stopLossShortInput = input.float(defval=0, step=0.01, title='Stop Loss Short', minval=0) takeProfitLongInput = input.float(defval=0, step=0.01, title='Target Profit Long', minval=0) takeProfitShortInput = input.float(defval=0, step=0.01, title='Target Profit Short', minval=0) stopLossPriceLong = ta.valuewhen(tradersPostBuy, close, 0) * (stopLossLongInput / 100) * pips stopLossPriceShort = ta.valuewhen(tradersPostSell, close, 0) * (stopLossShortInput / 100) * pips takeProfitPriceLong = ta.valuewhen(tradersPostBuy, close, 0) * (takeProfitLongInput / 100) * pips takeProfitPriceShort = ta.valuewhen(tradersPostSell, close, 0) * (takeProfitShortInput / 100) * pips takeProfitALong = takeProfitLongInput > 0 ? takeProfitLongInput : na takeProfitBLong = takeProfitPriceLong > 0 ? takeProfitPriceLong : na takeProfitAShort = takeProfitShortInput > 0 ? takeProfitShortInput : na takeProfitBShort = takeProfitPriceShort > 0 ? takeProfitPriceShort : na stopLossALong = stopLossLongInput > 0 ? stopLossLongInput : na stopLossBLong = stopLossPriceLong > 0 ? stopLossPriceLong : na stopLossAShort = stopLossShortInput > 0 ? stopLossShortInput : na stopLossBShort = stopLossPriceShort > 0 ? stopLossPriceShort : na takeProfitLong = percentOrPipsInput == 'Pips' ? takeProfitALong : takeProfitBLong stopLossLong = percentOrPipsInput == 'Pips' ? stopLossALong : stopLossBLong takeProfitShort = percentOrPipsInput == 'Pips' ? takeProfitAShort : takeProfitBShort stopLossShort = percentOrPipsInput == 'Pips' ? stopLossAShort : stopLossBShort buyAlertMessage = '{"ticker": "' + syminfo.ticker + '", "action": "buy", "price": ' + str.tostring(close) + '}' sellAlertMessage = '{"ticker": "' + syminfo.ticker + '", "action": "sell", "price": ' + str.tostring(close) + '}' exitLongAlertMessage = '{"ticker": "' + syminfo.ticker + '", "action": "exit", "price": ' + str.tostring(close) + '}' exitShortAlertMessage = '{"ticker": "' + syminfo.ticker + '", "action": "exit", "price": ' + str.tostring(close) + '}' if (sides != "None") if tradersPostBuy strategy.entry('Long', strategy.long, when = sides != 'Short', alert_message = buyAlertMessage) strategy.close('Short', when = sides == "Short" and timeCondition, alert_message = exitShortAlertMessage) if tradersPostSell strategy.entry('Short', strategy.short, when = sides != 'Long', alert_message = sellAlertMessage) strategy.close('Long', when = sides == 'Long', alert_message = exitLongAlertMessage) exitAlertMessage = '{"ticker": "' + syminfo.ticker + '", "action": "exit"}' strategy.exit('Exit Long', from_entry = "Long", profit = takeProfitLong, loss = stopLossLong, alert_message = exitAlertMessage) strategy.exit('Exit Short', from_entry = "Short", profit = takeProfitShort, loss = stopLossShort, alert_message = exitAlertMessage) strategy.close_all(when = timeConditionEnd)