VPS do Metatrader dando erro de indicador customizado - página 2

 
Alexandre Borela #:


Tenta compilar o código que você postou e vai ver os erros. Esse outro ponto também não faz sentido você fazer um && com a string.


Ah, sim! Agora eu entendi do que vc se refere. Na verdade, eu retirei a lógica de entrada e a variável "Entrada" que seria um preço para proteger o código, mas poderia substituir por qualquer outra lógica de entrada para ver se daria o mesmo erro de "Failed with code 1". como eu disse acima, eu uso esse robô normalmente no meu pc, o problema ocorre quando eu migro para a VPS do MT5. Você poderia substituir o preço de entrada por qualquer outro assim também como a lógica de entrada.

 
Alexandre Borela #:


Tenta compilar o código que você postou e vai ver os erros. Esse outro ponto também não faz sentido você fazer um && com a string.


//+------------------------------------------------------------------+
//|                                                Minima15Teste.mq5 |
//|                                  Copyright 2020, Leandro Kalemba |
//|                                            leangel2007@gmail.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2020, Leandro Kalemba"
#property link      "leangel2007@gmail.com"
#property version   "1.00"
//+------------------------------------------------------------------+
//|                            Biblioteca                            |
//+------------------------------------------------------------------+
#include <Trade\Trade.mqh>
//---Instância
CTrade trade;
//+------------------------------------------------------------------+
//|                        Variáveis Globais                         |
//+------------------------------------------------------------------+
string HorarioInicial = "09:00";
string HorarioFinal = "17:50";
string HorarioFechamento = "17:55";
string Ativo = "WINZ21";
double Lote = 1;
double TakeProfit = 0;
double StopLoss = 500;
ulong MagicNumber = 001;
ulong Spread = 100;
ENUM_ORDER_TYPE_FILLING Preenchimento = ORDER_FILLING_FOK;
//+------------------------------------------------------------------+
//| Média Móvel Simples de 200 Períodos                              |
//+------------------------------------------------------------------+
//---Handle
int MMAHandle;

//---Buffer
double MMABuffer[];

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--------------------Biblioteca CTrade--------------------\\  
 
   trade.SetExpertMagicNumber(MagicNumber);
   trade.LogLevel(2);
   trade.SetAsyncMode(false);
   trade.SetTypeFilling(Preenchimento);
   trade.SetDeviationInPoints(Spread);
   
//-------------------Validação do Handle-------------------\\

//---Chamando o handle da Média Móvel
MMAHandle = iMA(Ativo,PERIOD_M15,200,0,MODE_SMA,PRICE_CLOSE);

//---Verificando se há erros no handle da Média Móvel
if(MMAHandle == INVALID_HANDLE)
  {
   return INIT_FAILED;
   Print("Erro na Inicialização do handle da Média Móvel."," Erro: ", GetLastError());
  }
  
//-------------------Validação do Array-------------------\\

//---Invertendo o Array da Média Móvel e verificando se há erros na inversão
if(!ArraySetAsSeries(MMABuffer, true))
  {
   return INIT_FAILED;
   Print("Erro ao inverter o array da Média Móvel."," Erro: ", GetLastError());
  }

//-------------------Inserção do Indicador no Gráfico-------------------\\

//---Inserindo a Média Móvel no Gráfico e verificando se há erros na inserção
if(!ChartIndicatorAdd(ChartID(),0,MMAHandle))
  {
   return INIT_FAILED;
   Print("Erro na inserção da Média Móvel no gráfico."," Erro: ", GetLastError());
  }

//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {

//-------------------Cópia do Buffer-------------------\\

//---Copiando o buffer da Média Móvel e verificando se há erros na cópia
   if(CopyBuffer(MMAHandle, 0, 0, 2, MMABuffer) != 2)
     {
      Print("Erro ao copiar o buffer da Média Móvel."," Erro: ", GetLastError());
      return;
     }  
//--------------Deleta uma ordem ao surgir uma nova barra------------\\
   if(NovaBarra() && OrdemPendente() == true) //Essa nova barra é para que se o preço não alcançar a ordem de compra, a ordem seja cancelada por se descaracterizar da estratégia.
     {
      DeletaOrdens();
      Print("A ordem foi deletada pois surgiu uma nova barra!");
     }
//--------------Fecha uma posição ao surgir uma nova barra------------\\     
   if(NovaBarra2() && PosicaoAberta() == true) //Essa nova barra é para que a operação termine logo que surgir uma nova barra, ou seja, só vai durar uma barra.
     {
      FechaPosicao();
      Print("A posição foi fechada pois surgiu uma nova barra!");
     }     
//-------------------Gatilho de Entrada-------------------\\
   double Entrada = iOpen(Ativo,PERIOD_M15,0);
   if(iOpen(Ativo,PERIOD_M15,0) > iLow(Ativo,PERIOD_M15,1)
   && HorarioNegocicao() && OrdemPendente() == false && PosicaoAberta() == false)
     {
      trade.BuyLimit(Lote, Entrada, Ativo, Entrada - StopLoss, 0, ORDER_TIME_GTC, 0, "");
     }    

string HorarioAtual = TimeToString(iTime(Ativo,PERIOD_M1,0),TIME_SECONDS);
//---------Limpeza das Ordens pelo horário---------\\     
if((HorarioAtual >= HorarioFechamento && OrdemPendente() == true))                                                              
  {
   DeletaOrdens();
   Print("A Ordem foi deletada pois atingimos o limite de horário!");
  }
//---------Encerramento das Posições pelo horário---------\\      
if((HorarioAtual >= HorarioFechamento && PosicaoAberta() == true))                                                              
  {
   FechaPosicao();
   Print("A Posição foi fechada pois atingimos o limite de horário!");
  }
//--
  }
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//|                      Horário de Negociação                       |
//+------------------------------------------------------------------+
bool HorarioNegocicao()
  {
   string HorarioAtual = TimeToString(iTime(Ativo,PERIOD_M1,0),TIME_SECONDS);
   if(HorarioAtual >= HorarioInicial && HorarioAtual < HorarioFinal)
  {
   return true;
  }
   return false;
  }
//+------------------------------------------------------------------+
//|                   Verificação de Ordem Pendente                  |
//+------------------------------------------------------------------+
bool OrdemPendente() //Para saber há ordens pendentes do robô em questão.
  {
   for(int i=0; i<OrdersTotal(); i++)  //Retorna o número total de ordens pendentes no momento.
     {
      if(OrderGetTicket(i) && Ativo == OrderGetString(ORDER_SYMBOL) 
      && MagicNumber == OrderGetInteger(ORDER_MAGIC))  //Se o ativo possui o mesmo nome e o magic number da posição que está aberta.                                                               //Retorna e armazena o valor do resultado total.
        {
         return true;
        }
     }
   return false;
  }
//+------------------------------------------------------------------+
//|                  Verificação de Posição Aberta                   |
//+------------------------------------------------------------------+
bool PosicaoAberta() //Para saber há posições abertas do robô em questão.
  {
   for(int i=0; i<PositionsTotal(); i++)  //Retorna o número total de posições abertas no momento.
     {
      if(Ativo == PositionGetSymbol(i) && MagicNumber == PositionGetInteger(POSITION_MAGIC))  //Se o ativo possui o mesmo nome e o magic number da posição que está aberta.                                                               //Retorna e armazena o valor do resultado total.
        {
         return true;
        }
     }
   return false;
  }
//+------------------------------------------------------------------+
//|                    Deleta Ordens Pendentes                       |
//+------------------------------------------------------------------+
void DeletaOrdens() // Verificar depois na conta demo se não há de fato a necessidade de um indice para selecionar o ativo e magic number como é feito para fechamento de posições abertas.
  {
   for(int i = OrdersTotal() - 1; i >= 0; i--)
     {
      if(OrderGetTicket(i) && Ativo == OrderGetString(ORDER_SYMBOL) 
      && MagicNumber == OrderGetInteger(ORDER_MAGIC))
        {
         if(trade.OrderDelete(OrderGetTicket(i)))
           {
            Print("Ordem deletada sem falha. ResultRetcode: ",trade.ResultRetcode(), ",RetcodeDescription: ", trade.ResultRetcodeDescription());
           }
         else
           {
            Print("Ordem deletada com falha. ResultRetcode: ",trade.ResultRetcode(), ",RetcodeDescription: ", trade.ResultRetcodeDescription());
           }  
        }
     }

  }
//+------------------------------------------------------------------+
//|                    Fecha Posição Aberta                          |
//+------------------------------------------------------------------+
void FechaPosicao()
  {
   for(int i = PositionsTotal() - 1; i >= 0; i--)
     {
      if(Ativo == PositionGetSymbol(i) && MagicNumber == PositionGetInteger(POSITION_MAGIC))
        {
         if(trade.PositionClose(PositionGetInteger(POSITION_TICKET), Spread)) //Checar a necessidade de padronizar usando o "PositionGetTicket(i)" ao invés de PositionGetInteger.
           {                    
            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());
           }  
        }
     }

  }
//+------------------------------------------------------------------+
//|               Surgimento de uma Nova Barra                       |
//+------------------------------------------------------------------+
bool NovaBarra()
  {
   static int BarraAntiga = 0;
   int BarraAtual = Bars(Ativo, PERIOD_CURRENT, iTime(NULL,PERIOD_D1,0), iTime(NULL,PERIOD_CURRENT,0));
   if(BarraAntiga == 0)
     {
      BarraAntiga = BarraAtual;
      return false;
     }
   else if(BarraAntiga != BarraAtual)
        {
         BarraAntiga = BarraAtual;
         return true;
        }
      else
        {
         return false;
        } 
  }
//+------------------------------------------------------------------+
//|               Surgimento de uma Nova Barra 2                     |
//+------------------------------------------------------------------+
bool NovaBarra2()
  {
   static int BarraAntiga = 0;
   int BarraAtual = Bars(Ativo, PERIOD_CURRENT, iTime(NULL,PERIOD_D1,0), iTime(NULL,PERIOD_CURRENT,0));
   if(BarraAntiga == 0)
     {
      BarraAntiga = BarraAtual;
      return false;
     }
   else if(BarraAntiga != BarraAtual)
        {
         BarraAntiga = BarraAtual;
         return true;
        }
      else
        {
         return false;
        } 
  }

Alterei a lógica de entrada só para fazer o teste e o erro "Failed with code 1" continua.

 
LKalemba #:

Alterei a lógica de entrada só para fazer o teste e o erro "Failed with code 1" continua.

O erro 4114 vem do ChartIndicatorAdd, acontece quando o ativo OU o timeframe do indicador são diferentes do gráfico que você está usando, alterei a linha do iMa
para manter o ativo e timeframe consistente com o gráfico e o código funciona.

MMAHandle = iMA(Symbol(),Period(),200,0,MODE_SMA,PRICE_CLOSE);
https://www.mql5.com/en/docs/chart_operations/chartindicatoradd
Documentation on MQL5: Chart Operations / ChartIndicatorAdd
Documentation on MQL5: Chart Operations / ChartIndicatorAdd
  • www.mql5.com
ChartIndicatorAdd - Chart Operations - MQL5 Reference - Reference on algorithmic/automated trading language for MetaTrader 5
 
Alexandre Borela #:

O erro 4114 vem do ChartIndicatorAdd, acontece quando o ativo OU o timeframe do indicador são diferentes do gráfico que você está usando, alterei a linha do iMa
para manter o ativo e timeframe consistente com o gráfico e o código funciona.

Alterei essa parte do código, mas pra mim continua dando erro. Começo a achar que deva ser o meu terminal MT5.

 
LKalemba #:

Alterei essa parte do código, mas pra mim continua dando erro. Começo a achar que deva ser o meu terminal MT5.

Coloca os prints dos erros antes dos returns e olha o log de erros, se for o erro 4114 é aquilo que te disse.
 
LKalemba #:

Alterei essa parte do código, mas pra mim continua dando erro. Começo a achar que deva ser o meu terminal MT5.

E aí, Kalemba! 🙂 Já encontrou a solução? Porque eu estou com o mesmo problema e ninguém sabe nada sobre o assunto. Já falaram em permissão de antivírus, do Windows, etc. Se a função do próprio MT5 (iCustom) não reconhece o seu próprio indicador nativo, então a falha é dos desenvolvedores do MT5. E o pior: não disponibilizam nenhuma solução pra nós, só esse fórum que não responde nada. 
Razão: