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! 😉
O EA ficou bem profissional e detalhado