Expert Advisor-parte1: Programação de robôs de trade (videoaula)

Finalmente, trataremos a codificação do Expert Advisor (robô ou assistente especializado). As etapas tratadas anteriormente foram fundamentais para melhor compreensão e aprendizado da linguagem MQL5. Neste artigo, veremos como codificar um EA e integrá-lo com o indicador implementado anteriormente.

Vale lembrar que o segredo deste EA está no indicador, não no EA. Logo, é preciso melhorar a eficiência do indicador APF-Color-Base!”

O download do projeto pode ser feito pelo link:
http://aprendizfinanceiro.com.br/APF-Color-Base-EA.zip

Para agilizar o processo de codificação e reduzir a margem de erros, incluímos as bibliotecas internas CPositionInfo (controle de posição), CTrade (operações de trade) e CSymbolInfo (informações de mercado, referentes ao ativo analisado).

#include <Trade\PositionInfo.mqh>
#include <Trade\Trade.mqh>
#include <Trade\SymbolInfo.mqh>

CPositionInfo  m_position;                 // trade position object
CTrade         m_trade;                    // trading object
CSymbolInfo    m_symbol;                   // symbol info object

Como o robô se orienta pelo indicador APF-Color-Base, precisamos obter a cor da barra através de uma chamada iCustom, no bloco OnInit:

hAPF=iCustom(_Symbol,PERIOD_CURRENT,"\\Indicators\\APF-Color-base-1.1.ex5");
if(hAPF==INVALID_HANDLE) {
  Print("Expert: iCustom call: Error code=",GetLastError());
  return(INIT_FAILED);
}

Percebam que a chamada não difere muito dos exemplos que utilizamos no indicador com chamadas iMA e iSAR.

A leitura do sinal (obtenção da cor da barra) foi codificada na função GetSignal.

Mas, para ampliar a segurança das operações, a primeira verificação é referente a tentativa de encerrar operações em aberto (m_trade.PositionClose).

int signal=GetSignal();

if (signal==0 || close_trade) {
   if (count_buy>0 || count_sell>0) {
      int close_pos=0;
      for(int i=PositionsTotal()-1;i>=0;i--)
         if(m_position.SelectByIndex(i))
           if(m_position.Symbol()==Symbol() && m_position.Magic()==m_magic) {
              close_pos=0;
              if (signal==0 || close_trade) {
                  m_trade.PositionClose(m_position.Ticket());
                  close_pos=1;
              }
           }
   }
   return;
}

A função GetSignal retornará a cor da barra: sendo 0 (branco), 1 (verde/long) e 2 (vermelho/short) – vide indicador!

Quando count_buy ou count_sell for maior que 0, certamente existirá uma operação em aberto (Long ou Short). Neste caso, a posição será fechada caso GetSignal retorne 0 (a barra mudou de cor – para branco) ou close_trade seja diferente de zero (para forçar o fechamento).

Confiram o código da função GetSignal:

int GetSignal()
  {
      
      //--- load buf_color_line
      if (CopyBuffer(hAPF,4,0,2,buf_APF) < 0){
         Print("CopyBuffer APF error =",GetLastError());
         return(0);
      }
      
      int vSignal=0;
      if ((buf_APF[0]==1 && buf_APF[1]==0) || (count_buy>0 && buf_APF[0]==1 && buf_APF[1]==1))  vSignal=1;
      if ((buf_APF[0]==2 && buf_APF[1]==0) || (count_sell>0 && buf_APF[0]==2 && buf_APF[1]==2))  vSignal=2;

      return (vSignal);
  }

A cor dos dois últimos candles é obtida através da função do MQL5 CopyBuffer: o primeiro parâmetro identifica o handle do indicador (hAPF), o segundo parâmetro a posição do buffer do indicador (4 é o índice que representa buf_color_line – consulte os mapeamentos feitos com SetIndexBuffer), o terceiro a posição inicial (0 – última barra) e o último corresponde ao número de elementos para copiar (2 – duas barras).

A leitura dos dois últimos candles se faz necessário para comparar uma possível mudança de cor

Já a abertura de posição foi codificada na função OpenBuy (posição comprada) e OpenSell (posição vendida). Conforme exposto anteriormente, utilizamos a biblioteca CTrade para controlar a abertura de posição (m_trade.PositionOpen):

void OpenBuy(double sl,double tp)
  {
   sl=m_symbol.NormalizePrice(sl);
   tp=m_symbol.NormalizePrice(tp);
   int aux_Lots=InpLots;
   
//--- check volume before OrderSend to avoid "not enough money" error (CTrade)
   double check_volume_lot=m_trade.CheckVolume(m_symbol.Name(),aux_Lots,m_symbol.Ask(),ORDER_TYPE_BUY);

   if (count_buy>0) return;
   
   if(check_volume_lot!=0.0) {
      if(m_trade.PositionOpen(m_symbol.Name(),ORDER_TYPE_BUY,aux_Lots,m_symbol.Ask(),sl,tp,"LONG"))
      {
         if (trade_maxgain==0) {
            count_buy++;
            max_trades++;
         }
         Print("PositionOpen() BUY method executed SUCCESSFULLY. Return code=",m_trade.ResultRetcode(),
               " (",m_trade.ResultRetcodeDescription(),")");
         PrintResultTrade(m_trade,m_symbol);

         // preço confirmado pela corretora
         trade_open=m_trade.ResultPrice();
      }
...

   }
...

//---
  }

Cada ordem será enviada à mercado (ORDER_TYPE_BUY). Sendo assim, logo que o indicador sinalizar a mudança de cor, o robô fará a negociação pelo preço negociado naquele instante!

Caso tenha ficado alguma dúvida referente a lógica básica de construção de um EA, também recomendo acessar o seguinte vídeo:

No vídeo anterior, algumas estrategias foram escritas de maneira um pouco diferente (até porque abordou uma codificação em MQL4). Mas a lógica padrão é a mesma.

Espero que o artigo seja útil e até a próxima! 😉

One thought on “Expert Advisor-parte1: Programação de robôs de trade (videoaula)

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *