Funcionamento parcial de EA

 

Bom dia, amigos!
Estou com o seguinte problema. Projetei o EA e existem momentos q as condições são atendidas e ele executa ordens normalmente e  existe momentos com as mesmas condições q ele não as excuta. Alguém poderia rever algo importante que eu tenha deixado passar ?

A ideia do EA  e a seguinte: - Capturar os dados do primeiro candle do dia em 5M e coloca-las em uma variavel estatica para acessar.

                                          - Verificar de o RSI é menor que 20 e ativar uma variavel.

                                          - Se a variavel ativa executar uma ordem de compra quando a aberutura do candle anterior for menor que a mínima do primeiro candle e o preço for igual a esta mínima.

                                          - Caso comprado fazer uma compra 400 pontos abaixo da mínima do primeiro candle.

                                          - Caso a variavel ativa e não existir ordens abertas, e  ordem de compra com o lote dobrado quando atingir 400 pontos abaixo da minima.

Alguém pode ajudar ?

O EA está assim:

//+------------------------------------------------------------------+
//|                                                      ProjectName |
//|                                      Copyright 2020, CompanyName |
//|                                       http://www.companyname.net |
//+------------------------------------------------------------------+

#include <Trade\Trade.mqh>
CTrade trade;

//+------------------------------------------------------------------+
//| INPUTS DE OPERAÇÃO                                               |
//+------------------------------------------------------------------+

input double                  lote = 1;                                //Contratos
input double                  stopLoss = 800;                          //Stop Loss
input double                  takeProfit = 300;                        //Stop Gain
input double                  minimaB = 0;                             //Minima do 1° Candle
input int                     hAbertura = 9;                           //Hora de Abertura
input int                     mAbertura = 00;                          //Minuto de Aberura
input int                     hFechamento = 17;                        //Hora de Fechamento
input int                     mFechamento = 30;                        //Minuto de Fechamento
input ulong                   magicNum = 1;                            //Magic Number
input ulong                   desvPts = 10;                            //Desvio em Pontos
input ENUM_ORDER_TYPE_FILLING preenchimento = ORDER_FILLING_RETURN;    //Preenchimento da Ordem


double                        Recompra1 = 400;
double                        Recompra2 = 100;
double                        Take2 = takeProfit+400;
double                        TakeF = takeProfit+450;
double                        rsiArray[];


int                           PrecoM;
int                           RSI_Handle;
static int                    Contador_Barras;
static int                    RSIC;
string                        contador;

static datetime               Marc_LastCheck;
static datetime               CurretCandle;
static double                 HighOpenBar;
static double                 OpenOpenBar;
static double                 LowOpenBar;
static double                 CloseOpenBar;
static double                 RSICloseBar;

MqlTick                       ultimoTick;
MqlRates                      rates[];
MqlRates                      candle[];

//+------------------------------------------------------------------+
//| Inicialização do sistema                                         |
//+------------------------------------------------------------------+
int OnInit()
  {

   RSI_Handle = iRSI(_Symbol,_Period,5,PRICE_CLOSE);
   if(RSI_Handle==INVALID_HANDLE)
     {
      Print("Erro ao criar RSI - erro", GetLastError());
      return(INIT_FAILED);
     }

   trade.SetTypeFilling(preenchimento);
   trade.SetDeviationInPoints(desvPts);
   trade.SetExpertMagicNumber(magicNum);

   ArraySetAsSeries(rsiArray, true);
   ArraySetAsSeries(rates, true);
   ArraySetAsSeries(candle, true);

   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//|Tick a Tick                                                       |
//+------------------------------------------------------------------+
void OnTick()
  {

//+------------------------------------------------------------------+
//| SINCRONIZA HORARIO SERVIDOR                                      |
//+------------------------------------------------------------------+

   MqlDateTime dt;
   TimeCurrent(dt);

//+------------------------------------------------------------------+
//| ATUALIZA VARIAVEIS DE HORARIOS                                   |
//+------------------------------------------------------------------+

   double loc_horarioAtual=dt.hour*60+dt.min;
   double loc_horarioAbertura=hAbertura*60+mAbertura;
   double loc_horarioFechamento=hFechamento*60+mFechamento-5;


//+------------------------------------------------------------------+
//| VERIFICA ABERTURA                                                |
//+------------------------------------------------------------------+

   if(loc_horarioAtual<loc_horarioAbertura)
     {
      Comment("[ROBO AGUARDANDO ABERTURA]");
      LowOpenBar=0;
      Contador_Barras=0;
      PrecoM=0;
      contador = "INDEFINIDA";
      RSICloseBar=0;
      return;
     }

//+------------------------------------------------------------------+
//| VERIFICA FECHAMENTO                                              |
//+------------------------------------------------------------------+

   if(loc_horarioAtual>loc_horarioFechamento)
     {
      Comment("[ROBO ENCERROU O DIA]");
      LowOpenBar=0;
      Contador_Barras=0;
      PrecoM=0;
      contador = "INDEFINIDA";
      RSICloseBar=0;
      FechaPosicao();
      return;
     }
        

   if(loc_horarioAtual<loc_horarioAbertura)
     {
      DeletarOrdens();
      return;
     }

   if(loc_horarioAtual>loc_horarioFechamento)
     {
      DeletarOrdens();
      return;
     }


   if(!SymbolInfoTick(Symbol(),ultimoTick))
     {
      Alert("Erro ao obter informações de Preços: ", GetLastError());
      return;
     }

   if(CopyRates(_Symbol, _Period, 0, 3, rates)<0)
     {
      Alert("Erro ao obter as informações de MqlRates: ", GetLastError());
      return;
     }

   if(CopyRates(_Symbol, _Period, 0, 3, candle)<0)
     {
      Alert("Erro ao obter as informações do candle: ", GetLastError());
      return;
     }

   if(CopyBuffer(RSI_Handle, 0, 0, 3, rsiArray)<=0)
     {
      Alert("Erro ao copiar dados do RSI: ", GetLastError());
      return;
     }

//+------------------------------------------------------------------+
//| CAPTURA O PRIMEIRO CANDLE DO DIA                                 |
//+------------------------------------------------------------------+

   CurretCandle = candle[0].time;
   
   if(CurretCandle!=Marc_LastCheck)
     {
       Marc_LastCheck=CurretCandle;
       Contador_Barras=Contador_Barras+1;
     }
   
    if(Contador_Barras==2)
     {
      HighOpenBar=candle[1].high;
      OpenOpenBar=candle[1].open;
      LowOpenBar=candle[1].low;
      CloseOpenBar=candle[1].close;
      RSIC=1;
     }
 

//+------------------------------------------------------------------+
//| CONDIÇÕES DE COMPRA                                              |
//+------------------------------------------------------------------+

   if(rsiArray[1]<20 && RSIC==1 && PositionsTotal()==0)
     {
      contador ="COMPRA";
      RSICloseBar=candle[0].close;
     }
   
   if(RSICloseBar>0)
     {
      RSIC=0;
     } 
         
   if(PositionsTotal()==1)
      contador = "INDEFINIDA";
      
      
   Comment("Mínima da Primeira barra : ", LowOpenBar, "\n"
           "O contador é : ", contador, "\n"
           "Número de Candles é : ", Contador_Barras, "\n"
           "O Preço de ativação do RSI : ", RSICloseBar, "\n"
           "O RSI é Igual a : ", rsiArray[0], "\n"
           "O Preço Médio é : ", PrecoM
          );
   

   if(ultimoTick.last==LowOpenBar && contador=="COMPRA" && candle[0].open<LowOpenBar && PositionsTotal()==0)
     {
      //if(trade.Buy(lote, _Symbol, ask, ask-stopLoss, ask+takeProfit, ""))
      if(trade.Buy(lote, _Symbol, ultimoTick.ask, ultimoTick.ask-stopLoss, ultimoTick.ask+takeProfit, ""))
        {
         Print("Ordem de Compra - sem falha. ResultRetcode: ", trade.ResultRetcode(), ", RetcodeDescription: ", trade.ResultRetcodeDescription());
         PrecoM = PrecoM+1;
         RSICloseBar = 0;
         RSIC = 1;
        }
      else
        {
         Print("Ordem de Compra - com falha. ResultRetcode: ", trade.ResultRetcode(), ", RetcodeDescription: ", trade.ResultRetcodeDescription());
        }
     }

   if(ultimoTick.last==(LowOpenBar-400) && contador=="COMPRA" && RSICloseBar>LowOpenBar && PositionsTotal()==0)
     {
      //if(trade.Buy(lote, _Symbol, ask, ask-stopLoss, ask+takeProfit, ""))
      if(trade.Buy(lote*2, _Symbol, ultimoTick.ask, ultimoTick.ask-Recompra1, ultimoTick.ask+Take2, ""))
        {
         Print("Ordem de Compra - sem falha. ResultRetcode: ", trade.ResultRetcode(), ", RetcodeDescription: ", trade.ResultRetcodeDescription());     
         RSICloseBar = 0;
         RSIC = 1;        
        }
      else
        {
         Print("Ordem de Compra - com falha. ResultRetcode: ", trade.ResultRetcode(), ", RetcodeDescription: ", trade.ResultRetcodeDescription());
        }
     }


  //Recompra

   if(ultimoTick.last==(LowOpenBar-400) && PositionsTotal()==1 && PrecoM==1 )
     {
      //if(trade.Buy(lote, _Symbol, ask, ask-stopLoss, ask+takeProfit, ""))
      if(trade.Buy(lote, _Symbol, ultimoTick.ask, ultimoTick.ask-Recompra1, ultimoTick.ask+Take2, ""))
        {
         Print("Ordem de Compra - sem falha. ResultRetcode: ", trade.ResultRetcode(), ", RetcodeDescription: ", trade.ResultRetcodeDescription());
         PrecoM = PrecoM+ 1;
         RSICloseBar = 0;
         RSIC = 1;        
        }
      else
        {
         Print("Ordem de Compra - com falha. ResultRetcode: ", trade.ResultRetcode(), ", RetcodeDescription: ", trade.ResultRetcodeDescription());
        }
     }

   if(PositionsTotal()==0 && PrecoM==1)
     {
       PrecoM = 0;    
     }

   Sleep(60*1000); // CONTANDO 60 SEGUNDOS SEMPRE // SEGURANCA

  }

//+------------------------------------------------------------------+
//|FUNÇÕES                                                           |
//+------------------------------------------------------------------+

void FechaPosicao()
  {
   for(int i = PositionsTotal()-1; i>=0; i--)
     {
      string symbol = PositionGetSymbol(i);
      ulong magic = PositionGetInteger(POSITION_MAGIC);
      if(symbol == _Symbol && magic == magicNum)
        {
         ulong PositionTicket = PositionGetInteger(POSITION_TICKET);
         if(trade.PositionClose(PositionTicket, desvPts))
           {
            Print("Posição Fechada - sem falha. ResultRetcode: ", trade.ResultRetcode(), ", RetcodeDescription: ", trade.ResultRetcodeDescription());
           }
         else
           {
            Print("Posição Fechada - com falha. ResultRetcode: ", trade.ResultRetcode(), ", RetcodeDescription: ", trade.ResultRetcodeDescription());
           }
        }
     }
  }


//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+

void DeletarOrdens()
  {
   for(int i = PositionsTotal()-1; i>=0; i--)
     {
      ulong  ticket = OrderGetTicket(i);
      string symbol = OrderGetString(ORDER_SYMBOL);
      ulong magic = OrderGetInteger(ORDER_MAGIC);
      if(symbol == _Symbol && magic == magicNum)
        {
         ulong PositionTicket = PositionGetInteger(POSITION_TICKET);
         if(trade.OrderDelete(ticket))
           {
            Print("Ordem Deletada - sem falha. ResultRetcode: ", trade.ResultRetcode(), ", RetcodeDescription: ", trade.ResultRetcodeDescription());
           }
         else
           {
            Print("Ordem Deletada - com falha. ResultRetcode: ", trade.ResultRetcode(), ", RetcodeDescription: ", trade.ResultRetcodeDescription());
           }
        }
     }
  }
//+-------------------------------------------------------------------------------------------------------------------------------------+
 
André Abreu de Sá:

Bom dia, amigos!
Estou com o seguinte problema. Projetei o EA e existem momentos q as condições são atendidas e ele executa ordens normalmente e  existe momentos com as mesmas condições q ele não as excuta. Alguém poderia rever algo importante que eu tenha deixado passar ?

A ideia do EA  e a seguinte: - Capturar os dados do primeiro candle do dia em 5M e coloca-las em uma variavel estatica para acessar.

                                          - Verificar de o RSI é menor que 20 e ativar uma variavel.

                                          - Se a variavel ativa executar uma ordem de compra quando a aberutura do candle anterior for menor que a mínima do primeiro candle e o preço for igual a esta mínima.

                                          - Caso comprado fazer uma compra 400 pontos abaixo da mínima do primeiro candle.

                                          - Caso a variavel ativa e não existir ordens abertas, e  ordem de compra com o lote dobrado quando atingir 400 pontos abaixo da minima.

Alguém pode ajudar ?

O EA está assim:

André, se vc tiver qualquer posição em aberto de outro ativo vai impactar no seu código. Faça uma mudança ao invés de utilizar PositionsTotal, utilize PositionSelect(symbol).

 
Leandro Ferreira:

André, se vc tiver qualquer posição em aberto de outro ativo vai impactar no seu código. Faça uma mudança ao invés de utilizar PositionsTotal, utilize PositionSelect(symbol).

Olhando bem por cima, eu acho que seu problema eh que o codigo nao pega a vela de interesse quando ela esta fechada. Por exemplo, o copy rates nao parece ter nenhuma protecao, entao vai sempre pegando os 3 ultimos, entretanto o contador limita a copia da vela no numero 2 e isso pelo que entendi eh a primeira vela em um momento. Na sua explicacao, ali pra cima parecia que tu queria pegar a segunda vela do dia como de interesse e nao seria isso q esta acontecendo.

 
Leandro Ferreira:

André, se vc tiver qualquer posição em aberto de outro ativo vai impactar no seu código. Faça uma mudança ao invés de utilizar PositionsTotal, utilize PositionSelect(symbol).

Obrigado, vou verificar e melhorar essa condição.
 
Ricardo Rodrigues Lucca:

Olhando bem por cima, eu acho que seu problema eh que o codigo nao pega a vela de interesse quando ela esta fechada. Por exemplo, o copy rates nao parece ter nenhuma protecao, entao vai sempre pegando os 3 ultimos, entretanto o contador limita a copia da vela no numero 2 e isso pelo que entendi eh a primeira vela em um momento. Na sua explicacao, ali pra cima parecia que tu queria pegar a segunda vela do dia como de interesse e nao seria isso q esta acontecendo.

No caso de captura é do primeiro candle do dia e esta funcionando perfeitamente, desde que se inicie o bot antes do inicio do pregão. 
O que percebo é que em algumas condições da compra ele nao executa, mesmo tudo estando dentro das condições, 

if(ultimoTick.last==LowOpenBar && contador=="COMPRA" && candle[0].open<LowOpenBar && PositionsTotal()==0)


ou if(ultimoTick.last==(LowOpenBar-400) && contador=="COMPRA" && RSICloseBar>LowOpenBar && PositionsTotal()==0)

ou if(ultimoTick.last==(LowOpenBar-400) && PositionsTotal()==1 && PrecoM==1 )

  mesmo relantado isso tudo relatado no Comment e conferindo.

 
André Abreu de Sá:

No caso de captura é do primeiro candle do dia e esta funcionando perfeitamente, desde que se inicie o bot antes do inicio do pregão
O que percebo é que em algumas condições da compra ele nao executa, mesmo tudo estando dentro das condições

  mesmo relantado isso tudo relatado no Comment e conferindo.

Boa noite André!


Para identificar corretamente o candle independente da hora que iniciar o robô, você pode utilizar iBarShift(), como nesse exemplo . . .


Para identificar o motivo da não execução das ordens, você pode consultar as abas Experts e Diário, da Caixa de Ferramentas do MT5.

Valores high e low do primeiro candle do dia
Valores high e low do primeiro candle do dia
  • 2019.12.29
  • www.mql5.com
Olá amigos, Desta vez to precisando de uma ajudinha...
Razão: