MQL5 04/06/2026

Estratégia de Cruzamento de Médias Móveis (Setup 9.1) em MQL5

O acompanhamento de tendências é um dos pilares do trading quantitativo. Entre as diversas técnicas disponíveis, o Setup 9.1, popularizado pelo trader Larry Williams, destaca-se pela sua simplicidade e eficácia. Ele utiliza uma Média Móvel Exponencial (EMA) de curto período como gatilho de entrada quando o preço altera sua direção em relação a essa média.

Neste artigo, vamos desenvolver um Expert Advisor (EA) simples em MQL5 para automatizar a identificação desse setup e executar ordens de teste no testador de estratégia.

O Conceito Estratégico

A lógica por trás do Setup 9.1 é rastrear a inversão da inclinação de uma média móvel rápida (normalmente de 9 períodos).

Sinal de Compra: Ocorre quando a EMA(9), que vinha caindo, vira para cima. O gatilho de compra é acionado na máxima do candle que fez a média virar.

Sinal de Venda: Ocorre quando a EMA(9), que vinha subindo, vira para baixo. O gatilho de venda é acionado na mínima do candle correspondente.

Estrutura do Código em MQL5

Para construir nosso EA, utilizaremos as funções nativas de manipulação de indicadores do MQL5 (iMA) e a classe padrão CTrade para facilitar a abertura de posições.

Código Completo para Testes

Crie um novo arquivo no MetaEditor (tipo Expert Advisor - Template), limpe o código padrão e cole o script abaixo:
MQL5
//+------------------------------------------------------------------+
//|                                                   ArtigoSetup91.mq5|
//|                                  Copyright 2026, Desenvolvedor |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2026"
#property link      "https://www.mql5.com"
#property version   "1.00"

// Inclui a classe de negociação padrão do MQL5
#include <Trade\Trade.mqh>
CTrade trade;

//--- Parâmetros de Entrada (Inputs)
input group "--- Parâmetros do Robô ---"
input int      InpEMAPeriod   = 9;          // Período da EMA
input double   InpLotSize     = 0.1;        // Tamanho do lote
input ulong    InpMagicNumber = 123456;     // Número Mágico (Identificador)

//--- Variáveis Globais
int      handleEMA;                         // Handle do indicador
double   bufferEMA[];                       // Array para armazenar os valores da EMA
datetime datetimeUltimoCandle;              // Evita múltiplas operações no mesmo candle

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
   // Configura o identificador do robô para a classe trade
   trade.SetExpertMagicNumber(InpMagicNumber);
   
   // Inicializa o indicador EMA
   handleEMA = iMA(_Symbol, _Period, InpEMAPeriod, 0, MODE_EMA, PRICE_CLOSE);
   if(handleEMA == INVALID_HANDLE)
   {
      Print("Erro ao criar o handle da EMA.");
      return(INIT_FAILED);
   }

   // Define o array como série temporal (índice 0 é o candle atual)
   ArraySetAsSeries(bufferEMA, true);
   
   datetimeUltimoCandle = 0;
   return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   // Libera o handle do indicador para economizar memória
   IndicatorRelease(handleEMA);
}

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
   // Garante que só operamos no fechamento do candle (nova barra)
   datetime datetimeCandleAtual = iTime(_Symbol, _Period, 0);
   if(datetimeCandleAtual == datetimeUltimoCandle) return;
   
   // Copia os dados mais recentes do indicador para o nosso array
   // Copiamos 4 posições para analisar a inclinação dos candles anteriores
   if(CopyBuffer(handleEMA, 0, 0, 4, bufferEMA) < 0)
   {
      Print("Erro ao copiar dados do indicador.");
      return;
   }
   
   // Verifica se existem posições abertas com o mesmo Magic Number
   if(PositionsTotal() > 0)
   {
      for(int i = PositionsTotal() - 1; i >= 0; i--)
      {
         if(PositionGetSymbol(i) == _Symbol && PositionGetInteger(POSITION_MAGIC) == InpMagicNumber)
         {
            // Já existe uma posição aberta por este robô, não faz nada
            return; 
         }
      }
   }

   /*
      Índices do buffer após ArraySetAsSeries:
      bufferEMA[0] -> Candle atual (ainda em formação, não usamos)
      bufferEMA[1] -> Candle recém-fechado
      bufferEMA[2] -> Penúltimo candle
      bufferEMA[3] -> Antepenúltimo candle
   */

   //--- Lógica do Setup 9.1 ---
   
   // Condição de Compra: EMA[2] estava caindo em relação a EMA[3], e EMA[1] virou para cima
   bool compra91 = (bufferEMA[1] > bufferEMA[2]) && (bufferEMA[2] < bufferEMA[3]);
   
   // Condição de Venda: EMA[2] estava subindo em relação a EMA[3], e EMA[1] virou para baixo
   bool venda91  = (bufferEMA[1] < bufferEMA[2]) && (bufferEMA[2] > bufferEMA[3]);

   // Execução das Ordens
   if(compra91)
   {
      double precoAsk = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
      if(trade.Buy(InpLotSize, _Symbol, precoAsk, 0, 0, "Compra Setup 9.1"))
      {
         datetimeUltimoCandle = datetimeCandleAtual; // Atualiza para evitar novas ordens nesta barra
         Print("Ordem de Compra enviada com sucesso.");
      }
   }
   else if(venda91)
   {
      double precoBid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
      if(trade.Sell(InpLotSize, _Symbol, precoBid, 0, 0, "Venda Setup 9.1"))
      {
         datetimeUltimoCandle = datetimeCandleAtual;
         Print("Ordem de Venda enviada com sucesso.");
      }
   }
}
//+------------------------------------------------------------------+

Como Testar o Código no MetaTrader 5

Para ver o robô funcionando em um ambiente simulado, siga os passos abaixo:

Abra o MetaTrader 5.

Pressione CTRL + F4 para abrir o MetaEditor.

No painel esquerdo (Navegador), clique com o botão direito na pasta Experts e selecione Novo Arquivo.

Escolha Expert Advisor (modelo), avance, dê o nome de ArtigoSetup91 e conclua.

Apague todo o conteúdo gerado automaticamente e cole o código fornecido acima.

Clique no botão Compilar (ou pressione F7). Certifique-se de que nenhum erro apareça na aba de descrição abaixo.

Volte ao MetaTrader 5 e pressione CTRL + R para abrir o Verificador de Estratégia (Strategy Tester).

Na aba de configurações, selecione o arquivo ArtigoSetup91.ex5, defina o ativo (ex: WIN$ ou EURUSD), o tempo gráfico (ex: M5 ou M15) e marque a opção Modo Visual.

Clique em Iniciar para observar o robô identificando as viradas da média móvel e abrindo as posições automaticamente na virada do candle.

Conclusão

Este artigo demonstrou a base da automação de estratégias em MQL5. O código apresentado lida de forma segura com o controle de novos candles (evitando ordens repetidas no mesmo tick) e utiliza as funções modernas de gerenciamento de indicadores da linguagem.

Como próximos passos de estudo, sugere-se a implementação de travas de gerenciamento de risco, como Stop Loss e Take Profit, diretamente na chamada das funções trade.Buy() e trade.Sell().