English Русский 中文 Español Deutsch 日本語
Exemplo de Expert Advisor

Exemplo de Expert Advisor

MetaTrader 4Exemplos | 29 abril 2016, 09:53
5 172 0
MetaQuotes
MetaQuotes

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:

  1. Variáveis de inicialização

  2. 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

  3. Definir as variáveis ​​internas para acessar os dados de forma rápida

  4. 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

  5. é possível abrir uma posição vendida (SELL)?

    • abrir uma posição vendida e encerrar

encerrar o Expert Advisor...
                    • 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?

                    • 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:

                      1. 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 programa

                        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;
                        

                        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;
                      2. 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
                             }
                        
                      3. 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.

                      4. 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);
                           }
                          

                      5. 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.

                             }
                      6. 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);
                        }
                        

                  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

                  Criamos um auxiliar na negociação manual Criamos um auxiliar na negociação manual
                  O número de robôs de negociação para trabalhar nos mercados de moedas ultimamente está crescendo como uma bola de neve. Neles estão compilados diversos conceitos e estratégias, mas vale a pena referir que ainda ninguém conseguiu criar um modelo de inteligência artificial que não esteja submetido a ricos de perda. Por isso, muitos traders continuam empenhados em negociar manualmente. E para esses especialistas são criados assistentes robóticos, chamados de painéis de negociação. Esse artigo é outro exemplo de como criar um painel de negociação "do zero".
                  Qualidade de Modelagem dos Dados de Um Minuto Qualidade de Modelagem dos Dados de Um Minuto
                  Qualidade de Modelagem dos Dados de Um Minuto
                  Calculadora de sinais Calculadora de sinais
                  A calculadora de sinais funciona diretamente a partir do terminal MetaTrader 5, e esta é a sua grande vantagem, pois o terminal pré-seleciona e classifica os sinais. Assim, no terminal MetaTrader 5, o usuário vê apenas os sinais com o máximo de compatibilidade com a sua conta de negociação.
                  O que Significa os Números no Relatório de Teste do Expert O que Significa os Números no Relatório de Teste do Expert
                  O artigo explica como ler os relatórios de teste e interpretar de forma correta os resultados obtidos.