Ponteiro Inválido Quando Troco o Timeframe do Gráfico

 

Olá pessoal! :)
Tudo bem?

Quando troco o timeframe do gráfico, meu EA dispara o erro de ponteiro inválido, atualmente utilizo muitos ponteiros, notei que com poucos ponteiros o erro não ocorre. Gostaria de ideias e soluções para esta situação. Se eu puder seguir trabalhando com os ponteiros melhor, pois eles são perfeitos pra armazenar informações em EAs mais complexos. Atualmente utilizo os ponteiros no escopo global do EA, o que me facilita bastante o trabalho com eles.

Eu utilizo ponteiros para armazenar as informações de ordens que não puderam ser modificadas (positions e pending orders), ou não puderam ser fechadas (positions), ou não puderam ser deletadas (pending orders). Para posteriormente, pegar estas ordens/positions e fazer as devidas verificações e tentar novamente com os valores anteriores ou atualizados conforme o preço do mercado atual.

Meu código de teste:

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright ""
#property link      ""
#property version   "1.00"

#include <Arrays\ArrayLong.mqh>
CArrayLong *ArrayOrdersModifyTickets = new CArrayLong;
CArrayLong *ArrayPositionsModifyTicket = new CArrayLong;
CArrayLong *ArrayOrdersModifyExpiration = new CArrayLong;
CArrayLong *ArrayOrdersDeleteTickets = new CArrayLong;
CArrayLong *ArrayPositionsCloseTickets = new CArrayLong;
CArrayLong *arraytest = new CArrayLong;

#include <Arrays\ArrayDouble.mqh>
CArrayDouble *ArrayPositionsModifySL_Price = new CArrayDouble;
CArrayDouble *ArrayPositionsModifyTP_Price = new CArrayDouble;
CArrayDouble *ArrayOrdersModifyPrice = new CArrayDouble;
CArrayDouble *ArrayOrdersModifySL_Price = new CArrayDouble;
CArrayDouble *ArrayOrdersModifyTP_Price = new CArrayDouble;
CArrayDouble *ArrayOrdersModifyVolume = new CArrayDouble;
CArrayDouble *ArrayOrdersModifyStopLimit = new CArrayDouble;

#include <Arrays\ArrayInt.mqh>
CArrayInt *ArrayOrdersModifyTypeTime = new CArrayInt;

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int OnInit() {
   if (CheckPointer(arraytest) != POINTER_INVALID ){ Print("Valid Pointer "); } 
   else {       Print("Invalid Pointer "); }
   if (CheckPointer(ArrayPositionsModifyTicket) != POINTER_INVALID ){ Print("Valid Pointer "); } 
   else {       Print("Invalid Pointer "); }
   if (CheckPointer(ArrayOrdersDeleteTickets) != POINTER_INVALID ){ Print("Valid Pointer "); } 
   else {       Print("Invalid Pointer "); }
   if (CheckPointer(ArrayOrdersModifyExpiration) != POINTER_INVALID ){ Print("Valid Pointer "); } 
   else {       Print("Invalid Pointer "); }
   if (CheckPointer(ArrayOrdersModifyPrice) != POINTER_INVALID ){ Print("Valid Pointer "); }  
   else {       Print("Invalid Pointer "); }
   if (CheckPointer(ArrayOrdersModifySL_Price) != POINTER_INVALID ){ Print("Valid Pointer "); } 
   else {       Print("Invalid Pointer "); }
   if (CheckPointer(ArrayOrdersModifyStopLimit) != POINTER_INVALID ){ Print("Valid Pointer "); } 
   else {       Print("Invalid Pointer "); }
   if (CheckPointer(ArrayOrdersModifyTP_Price) != POINTER_INVALID ){ Print("Valid Pointer "); } 
   else {       Print("Invalid Pointer "); }
   if (CheckPointer(ArrayOrdersModifyTickets) != POINTER_INVALID ){ Print("Valid Pointer "); } 
   else {       Print("Invalid Pointer "); }
   if (CheckPointer(ArrayOrdersModifyTypeTime) != POINTER_INVALID ){ Print("Valid Pointer "); } 
   else {       Print("Invalid Pointer "); }
   if (CheckPointer(ArrayOrdersModifyVolume) != POINTER_INVALID ){ Print("Valid Pointer "); } 
   else {       Print("Invalid Pointer "); }
   if (CheckPointer(ArrayPositionsCloseTickets) != POINTER_INVALID ){ Print("Valid Pointer "); } 
   else {       Print("Invalid Pointer "); }
   if (CheckPointer(ArrayPositionsModifySL_Price) != POINTER_INVALID ){ Print("Valid Pointer "); } 
   else {       Print("Invalid Pointer "); }
   if (CheckPointer(ArrayPositionsModifyTP_Price) != POINTER_INVALID ){ Print("Valid Pointer "); } 
   else {       Print("Invalid Pointer "); }

   if(ArrayOrdersModifyTickets == NULL || ArrayPositionsModifyTicket == NULL || ArrayOrdersModifyExpiration == NULL || ArrayPositionsModifySL_Price == NULL || ArrayPositionsModifyTP_Price == NULL || ArrayOrdersModifyPrice == NULL
         || ArrayOrdersModifySL_Price == NULL || ArrayOrdersModifyTP_Price == NULL || ArrayOrdersModifyVolume == NULL || ArrayOrdersModifyStopLimit == NULL || ArrayOrdersModifyTypeTime == NULL || ArrayOrdersDeleteTickets == NULL
         || ArrayPositionsCloseTickets == NULL)
   {
      Print("ObjectCreateError()");
      return(INIT_FAILED);
   }
          
   return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Função de Desinicialização do Expert                             |
//+------------------------------------------------------------------+
void OnDeinit(const int reason) {
   delete ArrayOrdersModifyTickets;
   delete ArrayPositionsModifyTicket;
   delete ArrayOrdersModifyExpiration;
   delete ArrayPositionsModifySL_Price;
   delete ArrayPositionsModifyTP_Price;
   delete ArrayOrdersModifyPrice;
   delete ArrayOrdersModifySL_Price;
   delete ArrayOrdersModifyTP_Price;
   delete ArrayOrdersModifyVolume;
   delete ArrayOrdersModifyStopLimit;
   delete ArrayOrdersModifyTypeTime;
   delete ArrayOrdersDeleteTickets;
   delete ArrayPositionsCloseTickets;
        delete arraytest;
        
        Print(TimeCurrent(),": " ,__FUNCTION__," código de motivo = ",reason);
//--- "limpa" comentário
   Comment("");
}

//+------------------------------------------------------------------+
//| Função tick (ponto) de um Expert                                 |
//+------------------------------------------------------------------+
void OnTick() {
   //if (CheckPointer(arraytest) != POINTER_INVALID ){ Print("Valid Pointer "); } 
   //else {     Print("Invalid Pointer "); }
   //if (CheckPointer(ArrayPositionsModifyTicket) != POINTER_INVALID ){ Print("Valid Pointer "); } 
   //else {     Print("Invalid Pointer "); }
   //if (CheckPointer(ArrayOrdersDeleteTickets) != POINTER_INVALID ){ Print("Valid Pointer "); } 
   //else {     Print("Invalid Pointer "); }
   //if (CheckPointer(ArrayOrdersModifyExpiration) != POINTER_INVALID ){ Print("Valid Pointer "); } 
   //else {     Print("Invalid Pointer "); }
   //if (CheckPointer(ArrayOrdersModifyPrice) != POINTER_INVALID ){ Print("Valid Pointer "); }  
   //else {     Print("Invalid Pointer "); }
   //if (CheckPointer(ArrayOrdersModifySL_Price) != POINTER_INVALID ){ Print("Valid Pointer "); } 
   //else {     Print("Invalid Pointer "); }
   //if (CheckPointer(ArrayOrdersModifyStopLimit) != POINTER_INVALID ){ Print("Valid Pointer "); } 
   //else {     Print("Invalid Pointer "); }
   //if (CheckPointer(ArrayOrdersModifyTP_Price) != POINTER_INVALID ){ Print("Valid Pointer "); } 
   //else {     Print("Invalid Pointer "); }
   //if (CheckPointer(ArrayOrdersModifyTickets) != POINTER_INVALID ){ Print("Valid Pointer "); } 
   //else {     Print("Invalid Pointer "); }
   //if (CheckPointer(ArrayOrdersModifyTypeTime) != POINTER_INVALID ){ Print("Valid Pointer "); } 
   //else {     Print("Invalid Pointer "); }
   //if (CheckPointer(ArrayOrdersModifyVolume) != POINTER_INVALID ){ Print("Valid Pointer "); } 
   //else {     Print("Invalid Pointer "); }
   //if (CheckPointer(ArrayPositionsCloseTickets) != POINTER_INVALID ){ Print("Valid Pointer "); } 
   //else {     Print("Invalid Pointer "); }
   //if (CheckPointer(ArrayPositionsModifySL_Price) != POINTER_INVALID ){ Print("Valid Pointer "); } 
   //else {     Print("Invalid Pointer "); }
   //if (CheckPointer(ArrayPositionsModifyTP_Price) != POINTER_INVALID ){ Print("Valid Pointer "); } 
   //else {     Print("Invalid Pointer "); }
}

Em anexo, o arquivo de teste.

Desde já, muito obrigado pela ajuda! :D

Atenciosamente,

Samuel.

Arquivos anexados:
Teste.mq5  7 kb
 
Testando encontrei a seguinte solução:

Quando a razão do OnDeinit for REASON_CHARTCHANGE ou REASON_PARAMETERS, não deletar os ponteiros, pois de todas as razões OnDeinit foram as únicas que geraram ponteiro inválido ao reiniciar o EA. Funcionou esta solução! Tem algum efeito colateral ruim no EA em fazer isso?
void OnDeinit(const int reason) {
	if(reason != REASON_CHARTCHANGE && reason != REASON_PARAMETERS){
           delete ArrayOrdersModifyTickets;
           delete ArrayPositionsModifyTicket;
           delete ArrayOrdersModifyExpiration;
           delete ArrayPositionsModifySL_Price;
           delete ArrayPositionsModifyTP_Price;
           delete ArrayOrdersModifyPrice;
           delete ArrayOrdersModifySL_Price;
           delete ArrayOrdersModifyTP_Price;
           delete ArrayOrdersModifyVolume;
           delete ArrayOrdersModifyStopLimit;
           delete ArrayOrdersModifyTypeTime;
           delete ArrayOrdersDeleteTickets;
           delete ArrayPositionsCloseTickets;
                delete arraytest;
        }
        Print(TimeCurrent(),": " ,__FUNCTION__," código de motivo = ",reason);
//--- "limpa" comentário
   Comment("");
}
 
Samuel Sant Anna:
Testando encontrei a seguinte solução:

Quando a razão do OnDeinit for REASON_CHARTCHANGE ou REASON_PARAMETERS, não deletar os ponteiros, pois de todas as razões OnDeinit foram as únicas que geraram ponteiro inválido ao reiniciar o EA. Funcionou esta solução! Tem algum efeito colateral ruim no EA em fazer isso?

Faça assim e não se preocupe em qual tipo de desinicialização está ocorrendo.


int OnInit()
{
 if(m_trade==NULL)
   m_trade =new CTrade();
}

void OnDeinit(const int reason)
  {
   if(m_trade!=NULL)
     {
      delete m_trade;
      m_trade=NULL;
     }
  }
 
Jonathan Pereira:

Faça assim e não se preocupe em qual tipo de desinicialização está ocorrendo.


Muito obrigado Jonathan!

Você é o cara! 

Grande abraço!