Neste guia completo, exploramos os fundamentos da programação de robôs de Forex e as linguagens MQL4 e MQL5.

Há muitas possibilidades para o uso de um robô de trading no mercado Forex. A aplicação mais comum é a automação de estratégias de negociação. Neste artigo, vamos examinar os conceitos básicos da programação de um robô de trading para Forex. Começaremos respondendo à pergunta: "Quais tipos de código podem ser programados na linguagem MQL4/MQL5?"
Quais tipos de código podem ser programados na linguagem de programação MQL4/MQL5?
Os exemplos apresentados aqui são baseados na linguagem de programação MQL4/MQL5. Três tipos de código podem ser criados em MQL4/MQL5:
- Expert Advisors (robôs Forex)
- Indicadores personalizados
- Scripts
1. O Expert Advisor (EA)
Ele representa a automação de um sistema de negociação manual vinculado ao gráfico de determinado ativo financeiro. Em outras palavras, qualquer código escrito para um EA precisa ser desenvolvido considerando o gráfico do ativo.
Alguns desses eventos são executados apenas uma vez, enquanto outros rodam várias vezes até receberem um sinal para parar. Sendo assim, um EA começará a operar se os eventos que compõem a sequência de inicialização (init) forem ativados.
Esses eventos incluem uma nova cotação/tick, um evento no gráfico ou eventos personalizados. Assim que forem acionados, o EA enviará uma ordem ao servidor da corretora para abrir ou encerrar uma operação. Os arquivos de EA ficam armazenados na pasta MQL4/Experts do cliente MT4.
2. O script
Trata-se de um código usado para executar determinadas funções uma única vez, como o evento Start. Os arquivos de script são armazenados na pasta MQL4/scripts do cliente MT4.
3. O indicador personalizado
É um indicador técnico personalizado que não está entre as ferramentas nativas do MT4. Ele não serve para abrir ordens diretamente, mas para identificar eventos no gráfico que podem disparar operações manuais ou por meio de um EA. Os arquivos de indicadores personalizados ficam salvos na pasta MQL4/indicators do cliente MT4.
Como criar um robô Forex usando código MQL4/MQL5
O código desenvolvido para um robô de trading para Forex, indicador ou script no ambiente MQL4/MQL5 incluirá sintaxe, variáveis, expressões e estruturas condicionais. Veja a seguir como estruturar seu robô com esses quatro elementos:
No restante deste artigo, faremos referência apenas ao MQL4, mas tudo o que for abordado também se aplica ao MQL5.
1. Familiarize-se com a sintaxe
A sintaxe de programação é o conjunto de regras e diretrizes que determina a escrita e a estrutura do código em uma linguagem específica.
A compilação e a execução corretas do código de um robô Forex dependem de uma sintaxe sem erros, adequada à linguagem utilizada para desenvolver o Expert Advisor, script ou indicador.
Veja alguns dos principais componentes da sintaxe do MQL4:
- Comentários: linhas de texto em um programa ignoradas pelo compilador ou interpretador. Usadas pelos programadores para documentar e explicar o código. Os comentários devem ficar entre /* e */ para múltiplas linhas ou começar com // para uma linha simples.
- Variáveis: espaço nomeado na memória do computador para armazenar dados. O valor de uma variável pode mudar durante a execução do programa.
- Tipos de dados: classificações que definem qual tipo de valor uma variável pode armazenar. Exemplos incluem
int(números inteiros),double(números de ponto flutuante para preços),bool(verdadeiro/falso),string(texto),datetime(data e hora) ecolor. - Identificadores: nomes dados aos elementos do programa, como variáveis, funções, classes ou módulos. Devem começar com uma letra ou sublinhado (_), podem conter letras, dígitos e sublinhados, e têm comprimento máximo de 63 caracteres. Eles também não podem ser palavras reservadas do MQL4.
- Operadores: símbolos que operam sobre um ou mais operandos (valores ou variáveis). São usados para operações aritméticas, de comparação, lógicas ou de atribuição. Exemplos incluem +, -, =, !=, || e &&.
- Estruturas condicionais: controlam o fluxo de execução de diferentes blocos de código com base em uma condição ser verdadeira ou falsa. Exemplos incluem as estruturas "if", "else if" e "else".
- Loops (laços de repetição): controlam o fluxo de execução, permitindo que um bloco de código seja executado enquanto uma condição for atendida. Usados para iterar sobre conjuntos de dados ou executar tarefas repetitivas. Exemplos incluem "for", "while" e "do-while".
- Funções: blocos de código que realizam uma tarefa específica. As funções dividem o programa em partes menores, tornando-o mais legível e evitando repetições desnecessárias.
O ambiente de desenvolvimento do MQL4 foi projetado para suportar diversos recursos de sintaxe, oferecendo a estrutura ideal para criar robôs de trading para Forex e indicadores robustos.
2. Comece com declaração e inicialização
As variáveis são a base da estrutura do seu código. Para utilizar uma variável, você precisa criá-la primeiro. A criação de uma variável é chamada de declaração. Por isso, você verá termos como "criar" ou "declarar" sendo usados de forma intercambiável, embora "declaração" seja o termo técnico padrão. Declarar uma variável informa ao código que ela deve ser criada, atribuindo a ela um tipo de dado específico.
Para declarar uma variável:
- escreva o tipo de dado, seguido de um espaço;
- escreva o nome da variável;
- finalize a linha com ponto e vírgula (;).
Veja como declarar uma variável do tipo inteiro (int):

- Aqui, o tipo de dado é int (inteiro).
- O nome da variável é hi.
- A linha é encerrada com ponto e vírgula.
As variáveis são definidas usando diferentes tipos de dados (como int para números inteiros ou double para números de ponto flutuante), seguidos de um nome para a variável (identificador). Para criar uma variável, você precisa definir seu tipo de dado. Os tipos mais comuns incluem:
- Inteiro (int): representa qualquer número entre -2 bilhões e +2 bilhões. O tipo int não armazena casas decimais.
- Double: representa números entre -1,79 X 10308 e +1,79 X 10308. Permite armazenar valores com casas decimais.
- Booleano (Bool): armazena valores lógicos, como verdadeiro (true) ou falso (false).
- Color: armazena informações de cores.
- String: armazena cadeias de texto.
- DateTime: armazena data e hora.
Por exemplo, digamos que você tenha as variáveis x, y e z com os inteiros 10, 7 e 5. Você pode decidir definir uma nova informação para a variável a. Logo, pode estabelecer que a = y + z. Como os valores de y e z já são conhecidos, tem-se que a = 12.
Para declarar uma variável inteira chamada "myVar", por exemplo, você usaria a seguinte sintaxe:
int myVar
Você também pode atribuir um valor à variável no momento da declaração. Suponha que queiramos atribuir o valor 10. A sintaxe para declarar esse valor na variável inteira myVar seria:
int myVar = 10;
Após declarar uma variável, ela pode ser usada no código MQL para executar diversas funções ou simplesmente armazenar informações. Se você for inserir o código para definir a nova variável a como a soma dos inteiros y + z, o formato será este:
int var1 = 10;
int var2 = 7;
Int var3 = 5
int result = var2 + var3; // result = 12

Neste exemplo, você declarou três variáveis inteiras: var1, var2 e var3 (ou x, y e z), com valores atribuídos de 10, 7 e 5, respectivamente. O objetivo é somar apenas var2 e var3 para obter o valor de uma nova variável a. O operador utilizado é o sinal de +, e result passa a ser a nova variável inteira que representa a. O resultado será 12, que corresponde à soma de var2 e var3.
Para a rotina prática de trading, uma função essencial ao declarar variáveis é armazenar valores que mudam ao longo do tempo, como o preço de um ativo. Como as cotações das moedas oscilam continuamente, você pode usar uma variável para guardar e atualizar essa informação a cada novo tick.
double price;
price = SymbolInfoDouble(_Symbol, SYMBOL_BID); // get the current bid price
ol, SYMBOL_BID); // get the current bid price
Em um mercado dinâmico como o Forex, é fundamental incluir variáveis na lógica da estratégia do seu robô de trading para acompanhar as oscilações e se adaptar às condições de mercado.
3. Expressões
As operações funcionam de forma semelhante aos cálculos aritméticos, como soma, subtração, multiplicação e divisão. Elas utilizam símbolos conhecidos como operadores. Quando combinados com variáveis em uma mesma linha de código, eles formam expressões.
Estes são os operadores mais comuns no código MQL4:
a) Operadores aritméticos: soma, subtração, porcentagem/módulo, divisão e multiplicação (+ – % / *)
b) Operadores lógicos: && ||
c) Operadores de atribuição: igual, soma com atribuição e multiplicação com atribuição (= += *=)
Uma instrução finalizada com ponto e vírgula (;) conclui a linha de código. Mas quais expressões são realmente úteis para um programador MQL4?
Os operadores aritméticos servem para realizar cálculos matemáticos com valores numéricos. Veja como eles são estruturados:

O operador ++ instrui o código a incrementar o valor de b na linha 27 em 1. Ou seja, se b = 70, o código atribuirá o valor de 70 + 1 (71) sempre que b++ for executado. Da mesma forma, o operador – – reduz o valor de b na linha 28 em 1, atribuindo o valor de 69 quando b- – for chamado.
Veja outro exemplo de expressão com operadores aritméticos:

A diretiva ‘#include <math.mqh>’ instrui o programa a incluir as funções da biblioteca Math, evitando erros durante a compilação. As funções da biblioteca visualizadas aqui são MathPow() e MathSqrt().
Mas o que significa cada um dos operadores aritméticos?
- Adição (+): soma os valores numéricos à esquerda e à direita do operador.
- Subtração (-): subtrai o valor à direita do operador do valor à esquerda.
- Multiplicação (*): multiplica os valores dos lados esquerdo e direito do operador.
- Divisão (/): divide o valor à esquerda pelo valor à direita do operador.
- Módulo (%): retorna o resto da divisão do valor à esquerda pelo valor à direita.
É assim que eles aparecem no ambiente de programação do MQL4:

Como 10 é divisível por 5 exatamente duas vezes sem deixar resto, o valor de 10 % 5 na linha 23 será 0.
Os operadores de atribuição servem para definir o valor de uma variável. Veja o significado dos principais operadores (= += -= *=):
- Atribuição (=): atribui o valor à direita do operador à variável situada à esquerda.
- Atribuição com soma (+=): soma o valor à direita ao valor atual da variável à esquerda e armazena o novo resultado nela.
- Atribuição com subtração (-=): subtrai o valor à direita do valor da variável à esquerda e armazena o novo resultado nela.
- Atribuição com multiplicação (*=): multiplica o valor da variável à esquerda pelo valor à direita e atribui o resultado à variável da esquerda.
- Atribuição com divisão (/=): divide o valor da variável à esquerda pelo valor à direita e armazena o resultado na variável da esquerda.
- Atribuição com módulo (%=): calcula o resto da divisão do valor da variável à esquerda pelo valor à direita e atribui o resultado à variável da esquerda.
Veja alguns exemplos de uso dos operadores de atribuição no MQL4:

4. Operadores condicionais (if/else, switch)
Os operadores condicionais são utilizados para executar instruções que dependem do cumprimento de determinados parâmetros. Ou seja, uma estrutura condicional permite realizar uma ação se uma condição prévia for verdadeira.
No MT4, as estruturas condicionais fundamentais são "if-else" e "switch". Ambas servem para controlar o fluxo de execução do código com base em condições pré-estabelecidas.
Estrutura if-else
A estrutura "if-else" é frequentemente usada quando precisamos verificar múltiplas condições no código.

Se este script for compilado e executado, ele exibirá 10 porque a condição é verdadeira. Caso precise executar essa condição em múltiplos pontos do código, você pode organizar os blocos usando chaves.
No contexto das operações de mercado, a estrutura if-else é utilizada para determinar como o código processa as variáveis de preço.
Veja um exemplo prático de funcionamento da condição if-else. Neste caso, a variável "price" assume por padrão a cotação Ask do mercado. A cláusula "if" verifica se o preço é superior a 1,0. Se for, apenas o bloco de código dentro das primeiras chaves será executado. Caso contrário (ou seja, preço < ou = 1,0), a execução passa para as instruções seguintes.
//+--------------------------------------------------------+
//| Script program start function |
//+--------------------------------------------------------+
void OnStart(){
double price = Bid;
if (price > 1.0) {
// Execute this code if price is greater than 1.0
Alert("Price is above 1.0");
}else if (price < 0.5) {
// Execute this code if price is less than 0.5
Alert("Price is below 0.5");
}else {
// Execute this code if price is between 0.5 and 1.0
Alert("Price is between 0.5 and 1.0");
}
}

Você também pode incluir uma instrução "if-else" dentro de outra já existente (isto é, entre as chaves de um bloco "if" ou "else"). Essa estrutura é conhecida como if-else aninhado. Veja o exemplo abaixo:

A instrução if-else aninhada faz o código checar se o preço é < 0,8 ou se está entre 0,8 e o alvo definido. Caso a cotação esteja abaixo de 0,8, o bloco do if aninhado é acionado; se não estiver, o bloco else correspondente será executado.
Os operadores condicionais podem ser usados nas operações para gerenciar ordens pendentes de entrada e saída, como Buy Limit/Sell Limit, Buy Stop/Sell Stop e Take Profit/Stop Loss. Trata-se de ordens executadas somente quando determinados parâmetros de preço são atingidos (uma condição). Se as condições não forem satisfeitas, a ordem não é disparada. Veja como estruturar as condicionais de entrada no ambiente MQL4:
Buy Stop
Para posicionar uma ordem Buy Stop em um determinado patamar de preço, você pode usar o código a seguir. Ele instrui o robô de trading a:
– executar uma ordem BUY STOP a uma distância de 10 pips do preço atual, com uma distância limite de 20 pips.
– utilizar 1 lote padrão (1.0 lote) como tamanho da posição.
– traçar uma linha verde no preço de entrada da ordem no gráfico para facilitar a visualização.
– atribuir um identificador exclusivo (Magic Number) a essa operação.
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
//---
double StopDistance = 10.0; // Stop distance in pips
double LimitDistance = 20.0; // Limit distance in pips
double Lots = 1.0; // Lot size
int Slippage = 3; // Maximum price deviation
int MagicNumber = 12345; // Unique identifier
color Green = Lime; // Order line color
// Get the current ask price
double price = Ask;
// Calculate the stop and limit prices
double stopPrice = NormalizeDouble(price + StopDistance * Point, Digits);
double limitPrice = NormalizeDouble(price + LimitDistance * Point, Digits);
// Place the buy stop order
int ticket = OrderSend(Symbol(), OP_BUYSTOP, Lots, stopPrice, Slippage, limitPrice, 0, "", MagicNumber, 0, Green);
if(ticket > 0)
{
Print("Buy stop order placed successfully with ticket #", ticket);
}
else
{
Print("Error placing buy stop order. Error code:", GetLastError());
}
}

O código define as seguintes variáveis:
- StopDistance
- LimitDistance
- Lots
- Slippage
- MagicNumber
- Green
Depois que a ordem é enviada, o código verifica se ela foi executada com sucesso analisando o retorno da função OrderSend() (o ticket). Se a ordem Buy Stop for executada com sucesso, uma mensagem será gravada na aba Diário (Journal) do MT4. Caso contrário, o código registrará uma mensagem contendo o código do erro.
Sell Limit
Para posicionar uma ordem Sell Limit em um nível de preço específico, você pode utilizar o seguinte código:
// Define order parameters
double lotSize = 0.1; // Lot size
double limitPrice = 1.2000; // Limit price
double stopLoss = 1.2100; // Stop loss
double takeProfit = 1.1900; // Take profit
int slippage = 3; // Maximum deviation in pips from the requested price
// Place sell limit order
bool sellLimitOrderPlaced = false;
int ticket = 0;
while (!sellLimitOrderPlaced) {
ticket = OrderSend(Symbol(), OP_SELLLIMIT, lotSize, limitPrice, slippage, stopLoss, takeProfit, "Sell Limit", MagicNumber, 0, Red);
if (ticket > 0) {
sellLimitOrderPlaced = true;
} else {
Print("Sell limit order failed with error code ", GetLastError());
Sleep(5000); // Wait for 5 seconds before retrying
}
}
// Check if the order is still open
while (OrderSelect(ticket, SELECT_BY_TICKET)){
if (OrderCloseTime() > 0) {
// Order has been closed
break;
}
// Wait for 1 second before checking again
Sleep(1000);
}

Stop Loss
É assim que você instrui o robô de trading para Forex a definir um stop loss em uma operação. Configurar o stop loss exige atenção: alguns programadores preferem que o código só posicione o stop loss quando a ordem já estiver ativa, usando uma instrução para modificar a ordem existente.
Neste exemplo, o EA foi configurado para criar uma ordem pendente e, em seguida, ajustar o stop loss assim que ela for executada.
// Define order parameters
double lotSize = 0.1; // Lot size
double limitPrice = 1.2000; // Limit price
double stopLoss = 1.2100; // Stop loss
double takeProfit = 1.1900; // Take profit
// Place the pending order
int ticket = OrderSend(Symbol(), OP_SELLLIMIT, lotSize, limitPrice, 0, stopLoss, takeProfit, "Sell Limit", MagicNumber, 0, Red);
if (ticket <= 0) {
Print("Failed to place pending order with error code ", GetLastError());
} else {
Print("Pending order placed with ticket number ", ticket);
}
// Modify the stop loss for the pending order
if (OrderSelect(ticket, SELECT_BY_TICKET, MODE_TRADES)) {
double newStopLoss = 1.2050; // New stop loss value
if (!OrderModify(ticket, OrderOpenPrice(), newStopLoss, OrderTakeProfit(), 0, Green)) {
Print("Failed to set stop loss for pending order with error code ", GetLastError());
} else {
Print("Stop loss set for pending order with ticket number ", ticket);
}
} else {
Print("Failed to select pending order with ticket number ", ticket, " with error code ", GetLastError());
}

As variáveis ficam evidentes no código:
- o volume é de 1 mini lote (0.1 lote);
- o preço limite é 1.2000;
- o stop loss é 1.2100;
- o take profit é 1.1900.
O código também inclui uma instrução para imprimir mensagens de erro no Diário se o stop loss não puder ser modificado. A ordem pendente é enviada por meio da função OrderSend(), utilizando as variáveis descritas como parâmetros.
Se a ordem for aceita, o código faz o robô de trading usar a função OrderSelect() (com o número do ticket para identificação). O parâmetro MODE_TRADES indica que o robô deve selecionar ordens abertas e pendentes para essa ação.
Você também pode usar a função OrderModify() para alterar os parâmetros da ordem e a variável newStopLoss para redefinir o nível de stop loss.
Lembre-se de consultar as regras da sua corretora quanto ao limite de alterações permitidas nesses parâmetros ao configurar as variáveis.
Take Profit
Você também pode definir uma ordem de Take Profit de forma separada, caso não a configure junto com o stop loss como exibido acima. Para isso, use o seguinte código:
void OnTick() {
// Set take profit level
double takeProfit = 1.5; // Take profit level as a multiple of the trade's open price
double stopLoss = 1.0; // Stop loss level as a multiple of the trade's open price
// Place trade with take profit and stop loss levels
int ticket = OrderSend(Symbol(), OP_BUY, 1.0, Ask, 3, Bid - stopLoss * Point, Bid + takeProfit * Point, "My Order", MagicNumber, 0, Blue);
}

Este código adota uma relação risco-retorno de 1:1,5 para definir os alvos de stop loss e take profit. Dessa forma, o TP fica estabelecido em 1,5 vez a distância em relação ao preço de entrada. Novamente, a função OrderSend() envia a ordem ao mercado com as variáveis stopLoss e takeProfit devidamente especificadas.
Switch
Já a estrutura "switch" é indicada quando há múltiplos valores possíveis a serem comparados para uma mesma variável. Veja um exemplo prático de aplicação das estruturas "if-else" e "switch" no MT4:
double price = Bid;
int tradeType = 2; // 0 = buy, 1 = sell, 2 = do nothing
// if-else statement
if (price > 1.0) {
tradeType = 0;
}else if (price < 0.5) {
tradeType = 1;
}
// switch statement
switch (tradeType) {
case 0:
// Execute this code if tradeType is 0 (buy)
OrderSend(Symbol(), OP_BUY, 0.1, price, 0, 0, 0, "Buy order", 0, 0, Green);
break;
case 1:
// Execute this code if tradeType is 1 (sell)
OrderSend(Symbol(), OP_SELL, 0.1, price, 0, 0, 0, "Sell order", 0, 0, Red);
break;
default:
// Execute this code if tradeType is not 0 or 1 (do nothing)
break;
}

A estrutura if/else analisa a condição a partir da cotação do preço:
- Se o preço for > 1.0, a variável tradeType = 0 -> COMPRA (BUY).
- Se a variável de preço for < 0.5, a variável tradeType = 1 -> VENDA (SELL).
- Se o preço estiver no nível atual de Bid (configuração padrão), tradeType = 2 -> NENHUMA AÇÃO.
Com a instrução switch, a abordagem muda: o código passa a avaliar diretamente o valor atribuído à variável tradeType.
- Se tradeType = 0 -> COMPRA (BUY) no nível de preço definido no código.
- Se tradeType = 1 -> VENDA (SELL) no preço especificado.
- Se tradeType = 2 -> NENHUMA AÇÃO.
Siga estes guias para aprender a instalar seu robô Forex no terminal de negociação:
Como instalar um robô de trading no MT4
Como instalar um robô de trading no MT5
Conclusão
Neste artigo, abordamos os diferentes elementos que compõem o código de um robô Forex e o desenvolvimento de sistemas automatizados de negociação. Você conheceu os tipos de código possíveis em MQL4 (robôs de trading para Forex, indicadores e scripts), além das estruturas que integram a lógica de um robô. Também vimos os formatos essenciais de código exigidos para cada aplicação e como trabalhar com comentários, identificadores, variáveis e condicionais na sintaxe do MQL4.
Dominar a programação em MQL4 exige estudo constante e muita prática. Esperamos que este conteúdo tenha ajudado você a compreender os fundamentos necessários para começar a programar seu próprio robô Forex.



