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.
MQL5
04/06/2026
Estratégia de Cruzamento de Médias Móveis (Setup 9.1) em MQL5
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.
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.
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().
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().