
Exemplo de Expert Advisor
Este artigo exibe os princípios de desenvolvimento de programas em MQL4 mediante a criação de um sistema Expert Advisor simples de exemplo com base no indicador MACD padrão. Neste Expert Advisor, nós também veremos exemplos de implementação de tais características como a criação dos níveis de take profit com suporte ao stop móvel (trailing stop), bem como a maioria dos meios que garantam um funcionamento seguro. Em nosso exemplo, a negociação é feita através da abertura e gestão de uma única posição.
Princípios de negociação:
Entrada de compra (BUY) - Indicador MACD está abaixo de zero, vai para cima e cruza a linha de sinal que vai para baixo.
Entrada de venda (SELL) - Indicador MACD está acima de zero, vai para baixo e cruza a linha de sinal que vai para cima.
Encerramento da compra - pela execução do take profit, pela execução do trailing stop ou quando o MACD cruzar a linha de sinal (MACD está acima de zero, vai para baixo e cruza a linha de sinal que vai para cima).
Encerramento da venda - pela execução do take profit, pela execução do trailing stop ou quando o MACD cruzar a linha de sinal (MACD está abaixo de zero, vai para cima e cruza a linha de sinal que vai para baixo).
Notícia importante: para excluir alterações insignificantes do indicador MACD (pequenas 'colinas' no gráfico) de nossa análise, introduzimos uma medida adicional para controlar o tamanho das "colinas" plotadas como se segue: o tamanho do indicador deve ser de, pelo menos, 5 unidades do preço mínimo (5*Point, o que para USD/CHF = 0.0005 e para o USD/JPY = 0.05).

Passo 1 - Escrever a descrição do Expert Advisor
![]() |
Aponte o cursor do mouse na seção Expert Advisors da janela do navegador, pressione o botão direito do mouse e selecione o comando "Criar no MetaEditor" no menu que aparece. O Assistente de Inicialização do Expert Advisor irá pedir-lhe para introduzir determinados dados. Na janela que aparece, escreva o nome (Nome) do Expert Advisor - Exemplo MACD, o autor (Autor) - indique o seu nome, o link (Link) - um link para seu website, nas notas (Notas) - Exemplo de teste de um Expert Advisor baseado no MACD. |
Passo 2 - Criar a estrutura primária do programa
O código-fonte do Expert Advisor só irá ocupar várias páginas, mas mesmo esse volume é muitas vezes difícil de entender, especialmente pelo fato de não sermos programadores profissionais - caso contrário, não teríamos necessidade de descrever tudo, não é mesmo? :)
Para se ter uma ideia da estrutura de um Expert Advisor padrão, vamos dar uma olhada na descrição dada abaixo:
Variáveis de inicialização
Verificação dos dados iniciais
consultar a tabela, número de barras no gráfico
verificar os valores das variáveis externas: Lots, S/L, T/P, T/S
Definir as variáveis internas para acessar os dados de forma rápida
Verificar o terminal de negociação - ele esta vazio? Se sim, então:
verificações: disponibilidade de saldo na conta etc ...
é possível abrir uma posição comprada (BUY)?
abrir uma posição comprada e encerrar
é possível abrir uma posição vendida (SELL)?
abrir uma posição vendida e encerrar
Controle das posições previamente abertas no ciclo
se for uma posição comprada
ela deve ser fechada?
o stop móvel deve ser resetado?
se for uma posição comprada
ela deve ser fechada?
o stop móvel deve ser resetado?
Variáveis de inicialização
Primeiramente, todas as variáveis a serem utilizadas no programa Expert devem ser definidas de acordo com a sintaxe da linguagem MQL 4. É por isso que inserimos o bloco para inicializar as variáveis no início do programaextern double TakeProfit = 50; extern double Lots = 0.1; extern double TrailingStop = 30; extern double MACDOpenLevel=3; extern double MACDCloseLevel=2; extern double MATrendPeriod=26;
A linguagem MQL 4 é completada pelo termo "variáveis externas". Variáveis externas podem ser definidas por fora sem modificar o código fonte do programa. Ela fornece flexibilidade adicional. No nosso programa, a variável MATrendPeriod é definida como uma variável extern. Nós inserimos a definição dessa variável, no início do programa.
extern double MATrendPeriod=26;
Verificação dos dados iniciais
Esta parte do código é geralmente utilizado em qualquer Expert com pequenas modificações, porque é um bloco de verificação praticamente padrão:// verificações dos dados iniciais // ele é importante para se certificar de que o Expert trabalhe com um gráfico, // normal e o usuário não cometa erros nas configurações externas // variáveis (Lots, StopLoss, TakeProfit, // TrailingStop) no nosso caso, vamos verificar o TakeProfit // em um gráfico menor do que 100 barras if(Bars<100) { Print("menor do que 100 barras"); return(0); } if(TakeProfit<10) { Print("TakeProfit menor que 10"); return(0); // verifica o TakeProfit }
Definindo as variáveis internas para acesso rápido aos dados
No código-fonte, muitas vezes é necessário acessar os valores dos indicadores ou lidar com os valores calculados. Para simplificar a codificação e acelerar o acesso, os dados são colocados em variáveis internas.int start() { double MacdCurrent, MacdPrevious, SignalCurrent; double SignalPrevious, MaCurrent, MaPrevious; int cnt, ticket, total; // para simplificar a codificação e acelerar o acesso // os dados são colocados em variáveis internas MacdCurrent=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,0); MacdPrevious=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,1); SignalCurrent=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_SIGNAL,0); SignalPrevious=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_SIGNAL,1); MaCurrent=iMA(NULL,0,MATrendPeriod,0,MODE_EMA,PRICE_CLOSE,0); MaPrevious=iMA(NULL,0,MATrendPeriod,0,MODE_EMA,PRICE_CLOSE,1);
Agora, em vez da notação monstruosa de IMACD (NULL, 0,12,26,9, PRICE_CLOSE, MODE_MAIN, 0), você pode usar MacdCurrent no código-fonte.
Verificar o terminal de negociação - ele está vazio? Se sim, então:
No nosso Expert Advisor, usamos apenas as posições que são abertas com ordens a mercado, nós não lidamos com as ordens pendentes. No entanto, para estar do lado seguro, vamos apresentar uma verificação do terminal de negociação para ordens colocadas anteriormente:total=OrdersTotal(); if(total<1) {
verificações: disponibilidade de saldo na conta etc...
Antes de analisar a situação do mercado, é aconselhável verificar o estado de sua conta para se certificar de que existem recursos livres para ele abrir uma posição.if(AccountFreeMargin()<(1000*Lots)) { Print("Nós não temos dinheiro. Margem Livre = ", AccountFreeMargin()); return(0); }
é possível abrir uma posição comprada (BUY)?
Condição de entrada para a posição comprada: MACD estar abaixo de zero, vai para cima e cruza a linha de sinal que vai para baixo. Isto é como nós descrevemos ele em MQL4 (note que operamos sobre os valores dos indicadores que foram salvos anteriormente nas variáveis):// verificar a possibilidade de abrir uma posição comprada (long) if(MacdCurrent<0 && MacdCurrent>SignalCurrent && MacdPrevious<SignalPrevious && MathAbs(MacdCurrent)>(MACDOpenLevel*Point) && MaCurrent>MaPrevious) { ticket=OrderSend(Symbol(),OP_BUY,Lots,Ask,3,0,Ask+TakeProfit*Point, "macd sample",16384,0,Green); if(ticket>0) { if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES)) Print("Ordem BUY aberta : ",OrderOpenPrice()); } else Print("Erro ao abrir uma ordem BUY : ",GetLastError()); return(0); }
Um controle adicional sobre o tamanho das 'colinas' já foi mencionado acima. A variável MACDOpenLevel é definida pelo usuário, podendo ser alterada, sem interferir com o código, para assegurar uma maior flexibilidade. No início do programa nós inserimos uma descrição desta variável (bem como a descrição da variável usado abaixo).
é possível abrir uma posição vendida (SELL)?
Condição de entrada de uma posição vendida: MACD está acima de zero, vai para baixo e cruza a linha de sinal que vai para cima. A notação é como se segue:// verificar a possibilidade de abrir uma posição vendida (SELL) if(MacdCurrent>0 && MacdCurrentSignalPrevious && MacdCurrent>(MACDOpenLevel*Point) && MaCurrent<MaPrevious) { ticket=OrderSend(Symbol(),OP_SELL,Lots,Bid,3,0,Bid-TakeProfit*Point, "macd sample",16384,0,Red); if(ticket>0) { if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES)) Print("Ordem SELL aberta : ",OrderOpenPrice()); } else Print("Erro ao abrir uma ordem SELL : ",GetLastError()); return(0); } return(0); }
Controle das posições previamente abertas no ciclo
// é importante entrar no mercado corretamente, // mas é mais importante sair corretamente... for(cnt=0;cnt { OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES); if(OrderType()<=OP_SELL && // verifica posições em aberto OrderSymbol()==Symbol()) // verifica o símbolo {
"cnt" - "é uma variável contadora que deve ser definida no início do programa, tal como se segue:
int cnt = 0;
se for uma posição comprada
if(OrderType()==OP_BUY) // está aberto uma posição comprada {
ela deve ser fechada?
Condição para sair de uma posição comprada: MACD cruza a linha de sinal, MACD estando acima de zero, indo para baixo e cruzando a linha de sinal que vai para cima.if(MacdCurrent>0 && MacdCurrent<SignalPrevious && MacPrevious>SignalPrevious && MacdCurrent>(MACDCloseLevel*Point)) { OrderClose(OrderTicket(),OrderLots(),Bid,3,Violet); // fecha a posição return(0); // exit }
o stop móvel deve ser resetado?
Nós definimos o stop móvel apenas no caso da posição já tiver um lucro superior ao nível do stop móvel em pontos, e no caso do novo nível de stop for melhor do que o anterior.// verificar o stop móvel if(TrailingStop>0) { if(Bid-OrderOpenPrice()>Point*TrailingStop) { if(OrderStopLoss() { OrderModify(OrderTicket(),OrderOpenPrice(),Bid-Point*TrailingStop, OrderTakeProfit(),0,Green); return(0); } } }
Nós fechamos a chave do operador.
}
se for uma posição comprada
else // vai para uma posição vendida {
ela deve ser fechada?
Condição para sair de uma posição venida: MACD cruza sua linha de sinal, MACD esta abaixo de zero, indo para cima e cruzando a linha de sinal que vai para baixo.if(MacdCurrent<0 && MacdCurrent>SignalCurrent && MacdPrevious<SignalPrevious && MathAbs(MacdCurrent)>(MACDCloseLevel*Point)) { OrderClose(OrderTicket(),OrderLots(),Ask,3,Violet); // fecha a posição return(0); // exit }
o stop móvel deve ser resetado?
Nós definimos o stop móvel apenas no caso da posição já tiver um lucro superior ao nível do stop móvel em pontos, e no caso do novo nível de stop for melhor do que o anterior.// verificar o stop móvel if(TrailingStop>0) { if((OrderOpenPrice()-Ask)>(Point*TrailingStop)) { if((OrderStopLoss()>(Ask+Point*TrailingStop)) || (OrderStopLoss()==0)) { OrderModify(OrderTicket(),OrderOpenPrice(),Ask+Point*TrailingStop, OrderTakeProfit(),0,Red); return(0); } } }
Fechando todos os colchetes que permaneceram abertos.
} } } return(0); }
Ele acaba por ser bastante simples, apenas 4 blocos principais.
Agora vamos tentar gerar pedaços do código passo a passo para cada seção da estrutura do esquema:
Então, seguindo este procedimento passo-a-passo, nós escrevemos o nosso Expert Advisor...
Passo 3 - Montagem do código resultante do programa
Vamos abrir as configurações do Expert Advisor (usando um botão ou uma linha em "Propriedades ..." do menu). Nos é oferecido uma janela na qual temos que definir as configurações externas dos parâmetros de trabalho:

Vamos montar todo o código da seção anterior:
//+------------------------------------------------------------------+ //| MACD Sample.mq4 | //| Copyright © 2005, MetaQuotes Software Corp. | //| https://www.metaquotes.net/ | //+------------------------------------------------------------------+ extern double TakeProfit = 50; extern double Lots = 0.1; extern double TrailingStop = 30; extern double MACDOpenLevel=3; extern double MACDCloseLevel=2; extern double MATrendPeriod=26; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int start() { double MacdCurrent, MacdPrevious, SignalCurrent; double SignalPrevious, MaCurrent, MaPrevious; int cnt, ticket, total; // verificações dos dados iniciais // ele é importante para se certificar de que o Expert trabalhe com um gráfico, // normal e o usuário não cometa erros nas configurações externas // variáveis (Lots, StopLoss, TakeProfit, // TrailingStop) no nosso caso, vamos verificar o TakeProfit // em um gráfico menor do que 100 barras if(Bars<100) { Print("menor do que 100 barras"); return(0); } if(TakeProfit<10) { Print("TakeProfit menor que 10"); return(0); // verifica o TakeProfit } // para simplificar a codificação e acelerar o acesso // os dados são colocados em variáveis internas MacdCurrent=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,0); MacdPrevious=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,1); SignalCurrent=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_SIGNAL,0); SignalPrevious=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_SIGNAL,1); MaCurrent=iMA(NULL,0,MATrendPeriod,0,MODE_EMA,PRICE_CLOSE,0); MaPrevious=iMA(NULL,0,MATrendPeriod,0,MODE_EMA,PRICE_CLOSE,1); total=OrdersTotal(); if(total<1) { // não foi identificado nenhuma ordem aberta if(AccountFreeMargin()<(1000*Lots)) { Print("Nós não temos dinheiro. Margem Livre = ", AccountFreeMargin()); return(0); } // verificar a possibilidade de abrir uma posição comprada (long) if(MacdCurrent<0 && MacdCurrent>SignalCurrent && MacdPrevious<SignalPrevious && MathAbs(MacdCurrent)>(MACDOpenLevel*Point) && MaCurrent>MaPrevious) { ticket=OrderSend(Symbol(),OP_BUY,Lots,Ask,3,0,Ask+TakeProfit*Point,"macd sample",16384,0,Green); if(ticket>0) { if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES)) Print("Ordem BUY aberta : ",OrderOpenPrice()); } else Print("Erro ao abrir uma ordem BUY : ",GetLastError()); return(0); } // verificar a possibilidade de abrir uma posição vendida (SELL) if(MacdCurrent>0 && MacdCurrent<SignalCurrent && MacdPrevious>SignalPrevious && MacdCurrent>(MACDOpenLevel*Point) && MaCurrent<MaPrevious) { ticket=OrderSend(Symbol(),OP_SELL,Lots,Bid,3,0,Bid-TakeProfit*Point,"macd sample",16384,0,Red); if(ticket>0) { if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES)) Print("Ordem SELL aberta : ",OrderOpenPrice()); } else Print("Erro ao abrir uma ordem SELL : ",GetLastError()); return(0); } return(0); } // é importante entrar no mercado corretamente, // mas é mais importante sair corretamente... for(cnt=0;cnt<total;cnt++) { OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES); if(OrderType()<=OP_SELL && // verifica posições em aberto OrderSymbol()==Symbol()) // verifica o símbolo { if(OrderType()==OP_BUY) // está aberto uma posição comprada { // ela deve ser fechada? if(MacdCurrent>0 && MacdCurrent<SignalCurrent && MacdPrevious>SignalPrevious && MacdCurrent>(MACDCloseLevel*Point)) { OrderClose(OrderTicket(),OrderLots(),Bid,3,Violet); // fecha a posição return(0); // exit } // verificar o stop móvel if(TrailingStop>0) { if(Bid-OrderOpenPrice()>Point*TrailingStop) { if(OrderStopLoss()<Bid-Point*TrailingStop) { OrderModify(OrderTicket(),OrderOpenPrice(),Bid-Point*TrailingStop,OrderTakeProfit(),0,Green); return(0); } } } } else // vai para uma posição vendida { // ela deve ser fechada? if(MacdCurrent<0 && MacdCurrent>SignalCurrent && MacdPrevious<SignalPrevious && MathAbs(MacdCurrent)>(MACDCloseLevel*Point)) { OrderClose(OrderTicket(),OrderLots(),Ask,3,Violet); // fecha a posição return(0); // exit } // verificar o stop móvel if(TrailingStop>0) { if((OrderOpenPrice()-Ask)>(Point*TrailingStop)) { if((OrderStopLoss()>(Ask+Point*TrailingStop)) || (OrderStopLoss()==0)) { OrderModify(OrderTicket(),OrderOpenPrice(),Ask+Point*TrailingStop,OrderTakeProfit(),0,Red); return(0); } } } } } } return(0); } // o fim.
Para a configuração final de nosso Expert Advisor, basta especificar os valores das variáveis externas "Lots = 1", "Stop Loss (S/L) = 0" (não utilizado), "Take Profit (T/P) = 120" ( apropriado para intervalos de uma hora), "Stop móvel (T/S) = 30". É claro que você pode definir os seus próprios valores. Pressione o botão "Compilar" e, se não houver nenhuma mensagem de erro (por sinal, você pode copiar o texto a partir da listagem acima no MetaEditor), pressione o botão "Salvar" para salvar o Expert Advisor.
Traduzido do russo pela MetaQuotes Ltd.
Artigo original: https://www.mql5.com/ru/articles/1510




- Aplicativos de negociação gratuitos
- 8 000+ sinais para cópia
- Notícias econômicas para análise dos mercados financeiros
Você concorda com a política do site e com os termos de uso