Início Negociação Sistemática Postagem

MQL5 Wizard: Sinais de Trade com Crossover de Duas EMAs e Filtro Intraday

Anexo
264.zip (3.83 KB, Baixar 0 vezes)

MQL5 Wizard é uma ferramenta incrível que permite criar códigos de Sistemas de Trading (EAs) de forma automática. Para mais detalhes, confira o artigo sobre Criando EAs Prontos no MQL5 Wizard.

Os sinais de trading dessa estratégia são baseados no cruzamento de duas médias móveis exponenciais. Confira mais sobre isso no artigo MQL5 Wizard - Sinais de Trade Baseados no Crossover de Duas Médias Móveis Exponenciais. As médias móveis funcionam bem em tendências, mas podem gerar muitos sinais falsos em outras situações. Uma maneira eficaz de melhorar a estratégia é usar filtros de tempo (por exemplo, abrir novas posições apenas durante a sessão europeia do FOREX).

Neste artigo, vamos explorar uma estratégia que utiliza o crossover de duas Médias Móveis Exponenciais (EMA rápida e EMA lenta) com um filtro de tempo intraday, que chamamos de "Sinais Baseados no Crossover de Duas EMAs com Filtro Intraday" ao criar o EA automaticamente no MQL5 Wizard.

Sinais de Trading:

  • Abrir posição longa: A EMA rápida cruza para cima da EMA lenta e as condições do filtro de tempo intraday não são atendidas.
  • Abrir posição curta: A EMA rápida cruza para baixo da EMA lenta e as condições do filtro de tempo intraday não são atendidas.

Essa estratégia é implementada na classe CSignal2EMA_ITF.

A filtragem de sinais com base em períodos de tempo específicos está implementada na classe CSignalITF. Como exemplo de uso, vamos considerar a classe CSignal2EMA_ITF (que contém um objeto da classe CSignalITF).

O sistema de trading utiliza ordens pendentes, e os níveis de preço são calculados com base nos valores das médias móveis, utilizando unidades do ATR (Average True Range).

Sinais de Trade, baseados no crossover de duas EMA com filtro intraday

Sinais de Trade, baseados no crossover de duas EMA com filtro intraday

Sinais de Trading

A estratégia de trading está implementada na CSignal2EMA_ITF, que possui alguns métodos protegidos para simplificar o acesso aos valores dos indicadores:

 double  FastEMA(int ind)      // retorna o valor da EMA rápida da barra
double  SlowEMA(int ind)      // retorna o valor da EMA lenta da barra
double  StateFastEMA(int ind) // retorna o valor positivo/negativo se a EMA rápida aumentou/diminuiu
double  StateSlowEMA(int ind) // retorna o valor positivo/negativo se a EMA lenta aumentou/diminuiu
double  StateEMA(int ind)     // retorna a diferença entre a EMA rápida e a lenta
double  ATR(int ind)          // retorna o valor do ATR da barra


Uma característica deste sistema é que o trade depende do parâmetro de entrada Limit. Dependendo do seu sinal, existem diferentes casos:

  1. Limit>0. O EA entrará em movimento de retrocesso quando houver uma falsa quebra da média móvel em um preço melhor do que o preço de mercado (ordens de Buy Limit e Sell Limit serão colocadas dependendo do sinal de trade)
  2. Limit<0. O EA entrará na direção do movimento de preço (ordens de Buy Stop e Sell Stop serão colocadas dependendo do sinal de trade).
  3. Limit=0. Nesse caso, ele fará operações utilizando os preços de mercado.


1. Abrir posição longa

O EA verifica as condições para abrir uma posição longa: se a diferença entre a EMA rápida e a EMA lenta na última barra concluída mudou seu sinal de "-" para "+" (StateEMA(1)>0 && StateEMA(2)<0).

Em seguida, verifica as condições do filtro de tempo intraday chamando o método CheckOpenLong() da classe CSignalITF. Se a negociação for permitida, calculará o nível de preço base (o valor da média móvel) e o valor do intervalo ATR da última barra concluída.

Dependendo do sinal do parâmetro de entrada Limit, ele colocará a ordem pendente de compra. O preço da ordem, Take Profit e Stop Loss são calculados em relação ao nível de preço base (em unidades de ATR). O tempo de expiração da ordem é definido (em barras) pelo parâmetro de entrada Expiration.

//+------------------------------------------------------------------+
//| Verifica condições para abrir posição longa (compra)                    |
//+------------------------------------------------------------------+
bool CSignal2EMA_ITF::CheckOpenLong(double& price,double& sl,double& tp,datetime& expiration)
  {
   if(!(StateEMA(1)>0 && StateEMA(2)<0))                    return(false);
   if(!m_time_filter.CheckOpenLong(price,sl,tp,expiration)) return(false);
//---
   double ema=SlowEMA(1);
   double atr=ATR(1);
   double spread=m_symbol.Ask()-m_symbol.Bid();
//---
   price=m_symbol.NormalizePrice(ema-m_limit*atr+spread);
   sl   =m_symbol.NormalizePrice(price+m_stop_loss*atr);
   tp   =m_symbol.NormalizePrice(price-m_take_profit*atr);
   expiration+=m_expiration*PeriodSeconds(m_period);
//---
   return(true);
  }

2. Fechar posição longa

Neste caso, a função que verifica as condições para fechar uma posição longa sempre retorna falso, ou seja, assume-se que a posição longa será fechada pelo Take Profit ou Stop Loss. Se necessário, você pode escrever seu próprio código para implementar este método.

//+------------------------------------------------------------------+
//| Verifica condições para fechar posição longa                         |
//+------------------------------------------------------------------+
bool CSignal2EMA_ITF::CheckCloseLong(double& price)
  {
   return(false);
  }


3. Abrir posição curta

Verifica as condições para abrir uma posição curta: se a diferença entre a EMA rápida e a EMA lenta na última barra concluída mudou seu sinal de "+" para "-" (StateEMA(1)<0 && StateEMA(2)>0).

Em seguida, verifica as condições do filtro de tempo intraday chamando o método CheckOpenLong() da classe CSignalITF. Se a negociação for permitida, calculará o nível de preço base (o valor da média móvel) e o valor do intervalo ATR da última barra concluída.

Dependendo do sinal do parâmetro de entrada Limit, ele colocará a ordem pendente de venda. O preço da ordem, Take Profit e Stop Loss são calculados em relação ao nível de preço base (em unidades de ATR). O tempo de expiração da ordem é definido (em barras) pelo parâmetro de entrada Expiration.

//+------------------------------------------------------------------+
//| Verifica condições para abrir posição curta (venda)                  |
//+------------------------------------------------------------------+
bool CSignal2EMA_ITF::CheckOpenShort(double& price,double& sl,double& tp,datetime& expiration)
  {
   if(!(StateEMA(1)<0 && StateEMA(2)>0))                     return(false);
   if(!m_time_filter.CheckOpenShort(price,sl,tp,expiration)) return(false);
//---
   double ema=SlowEMA(1);
   double atr=ATR(1);
//---
   price      =m_symbol.NormalizePrice(ema+m_limit*atr);
   sl         =m_symbol.NormalizePrice(price+m_stop_loss*atr);
   tp         =m_symbol.NormalizePrice(price-m_take_profit*atr);
   expiration+=m_expiration*PeriodSeconds(m_period);
//---
   return(true);
  }

4. Fechar posição curta

Neste caso, a função que verifica as condições para fechar uma posição curta sempre retorna falso, ou seja, assume-se que a posição será fechada pelo Take Profit ou Stop Loss. Se necessário, você pode escrever seu próprio código para implementar este método.

//+------------------------------------------------------------------+
//| Verifica condições para fechar posição curta                        |
//+------------------------------------------------------------------+
bool CSignal2EMA_ITF::CheckCloseShort(double& price)
  {
   return(false);
  }


5. Trailing Stop da Ordem Pendente de Compra

O Expert Advisor vai ajustar as ordens pendentes dependendo do valor atual da média móvel e do ATR.

O sistema de trading vai colocar ordens pendentes com base nos sinais de trade. Se a ordem for colocada com sucesso, ela vai seguir a média móvel. A ordem será executada se o preço de mercado atingir o preço da ordem.
//+--------------------------------------------------------------------+
//| Verifica condições para modificar a ordem pendente de compra       |
//+--------------------------------------------------------------------+
bool CSignal2EMA_ITF::CheckTrailingOrderLong(COrderInfo* order,double& price)
  {
//--- verificação
   if(order==NULL) return(false);
//---
   double ema=SlowEMA(1);
   double atr=ATR(1);
   double spread=m_symbol.Ask()-m_symbol.Bid();
//---
   price=m_symbol.NormalizePrice(ema-m_limit*atr+spread);
//---
   return(true);
  }


6. Trailing Stop da Ordem Pendente de Venda

O Expert Advisor vai ajustar as ordens pendentes dependendo do valor atual da média móvel e do ATR.

A ordem será executada se o preço de mercado atingir o preço da ordem.

//+--------------------------------------------------------------------+
//| Verifica condições para modificar a ordem pendente de venda       |
//+--------------------------------------------------------------------+
bool CSignal2EMA_ITF::CheckTrailingOrderShort(COrderInfo* order,double& price)
  {
//--- verificação
   if(order==NULL) return(false);
//---
   double ema=SlowEMA(1);
   double atr=ATR(1);
//---
   price=m_symbol.NormalizePrice(ema+m_limit*atr);
//---
   return(true);
  }

Criando um Expert Advisor com o MQL5 Wizard

Para criar um robô de trading baseado nessa estratégia, você precisa selecionar as propriedades do sinal como "Sinais Baseados no Crossover de Duas EMAs com Filtro Intraday" na opção "Criando EAs Prontos" do MQL5 Wizard:

Selecione os sinais baseados no crossover de duas EMAs com filtro intraday no MQL5 Wizard

Selecione os sinais baseados no crossover de duas EMAs com filtro intraday no MQL5 Wizard

Em seguida, você deve especificar o algoritmo de trailing stop necessário e o sistema de gestão de risco e dinheiro. O código do Expert Advisor será criado automaticamente, e você poderá compilá-lo e testá-lo no Strategy Tester do terminal MetaTrader 5.


Resultados dos Testes

Vamos considerar o backtesting do Expert Advisor com dados históricos (EUenSD H1, período de teste: 1.1.2010-05.01.2011, PeriodFastEMA=5, PeriodSlowEMA=30, PeriodATR=7, Limit=1.2, StopLoss=5, TakeProfit=8, Expiration=4, GoodMinuteOfHour=-1, BadMinutesOfHour=0, GoodHourOfDay=-1, BadHoursOfDay=0, GoodDayOfWeek=-1, BadDaysOfWeek=0).

Na criação do Expert Advisor, utilizamos um volume fixo (Trading Fixed Lot, 0.1), e o algoritmo de Trailing Stop não foi utilizado (Trailing não utilizado).

Resultados de Teste do Expert Advisor com sinais de trade, baseados no crossover de duas EMAs sem uso do filtro ITF

Resultados de Teste do Expert Advisor com sinais de trade, baseados no crossover de duas EMAs sem uso do filtro ITF

Como o filtro intraday não foi utilizado, houve muitos sinais falsos. Os sinais de trade podem ser melhorados se analisarmos os resultados das operações em função do horário de trade.

Nesse caso, descobrimos que o crossover de duas EMAs gera muitos sinais falsos a partir das 6:00 até 23:59. Podemos especificar o filtro de tempo intraday definindo os parâmetros do filtro.

Por exemplo, podemos especificar um filtro de tempo que permite abrir posições apenas das 0:00 até 5:59. Isso pode ser feito definindo o valor de BadHoursOfDay=16777152=111111111111111111000000b. Todas as outras horas de trade são "ruins", então é melhor proibir a abertura de novas posições das 6:00 até o final do dia.

Se definirmos o valor de BadHoursOfDay=16777152, filtraremos muitos sinais falsos:

Resultados de Teste do Expert Advisor com sinais de trade, baseados no crossover de duas EMAs com filtro de tempo (BadHoursofDay=16777152)

Resultados de Teste do Expert Advisor com sinais de trade, baseados no crossover de duas EMAs com filtro de tempo (BadHoursofDay=16777152)


A classe CSignalITF oferece muitos outros recursos de filtragem de tempo (basta especificar os minutos "bons" e "ruins" dentro da hora, horas dentro do dia, dias da semana).

O uso de filtros de tempo permite melhorar os sinais de trade e levar em conta a dinâmica do mercado (por exemplo, as características da sessão de trade).

Anexos: O arquivo Signal2EMA-ITF.mqh com a classe CSignal2EMA_ITF deve ser colocado na pasta terminal_data_folder\MQL5\Include\Expert\Signal.

O arquivo expert_2ema_itf.mq5 contém o código do Expert Advisor, criado usando o MQL5 Wizard.


Publicações relacionadas

Comentário (0)