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.
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 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
- 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)
- 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).
- 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.
//+--------------------------------------------------------------------+ //| 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
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
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)
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).
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
- MACD Sample: Um Guia Prático para o Expert Advisor no MetaTrader 5
- Como Integrar Eventos de Alto Impacto do ForexFactory no Seu EA para MetaTrader 4
- MQL5 Wizard: Sinais de Negócios com 3 Corvos Negros/3 Soldados Brancos + Estocástico para MetaTrader 5
- Hedger: Ferramenta de Order-Placement para MetaTrader 4
- Estratégia de Trading: 10 Pips por Dia com o EA MetaTrader 5