CopyTicksRange congela.

 

Pessoal boa tarde. Há tempos que tento solucionar um problema de congelamento da CopyTicksRange(), ela funciona perfeitamente por horas mas num determinado momento ela deixa de funcionar sem apresentar erro e não retorna mais a normalidade, bastando reiniciar o EA para voltar a funcionar normalmente. O código está abaixo e o LOG (anexo) há melhor compreensão do instante de congelamento, em resumo iniciei o EA as 11:08hrs e ele congela no horário 12:31hrs (Log anexado e de hoje).

Agradeceria se pudessem ajudar a resolver este congelamento inesperado, qualquer sugestão será bem vinda ...


NOTA ==>:   RefreshTicks é chamada a cada evento OnTick() e o simbolo é o WDO, porém testei com DOL, com WIN e IND e o problema também ocorre.

bool RefreshTicks(void) {

   if(!SymbolInfoTick(m_symbol, m_lasttick_refreshed)){

      printf(__FUNCTION__+":Falha na SymbolInfoTick em '%s'",m_symbol);

      return(false);

   }

   MqlDateTime today; 

   datetime current_time=TimeCurrent();      // Retorna a última hora conhecida do servidor, hora da última cotação recebida

   TimeToStruct(current_time,today);                             

   today.hour=0; today.min=0; today.sec=0;   // Zero hora, min e seg da ultima cotação recebida para pegar desde o inicio do dia atual

   datetime startday=StructToTime(today);    // startday = D'2021.06.24 00:00:00';

   datetime endday=startday+24*60*60-1;      // endday = D'2021.06.24 23:59:59';



   if((m_ticks_total=CopyTicksRange(_Symbol,m_tick_array,COPY_TICKS_TRADE,startday*1000,endday*1000))==-1) { 

      if(GetLastError()==ERR_HISTORY_TIMEOUT) {

         printf(__FUNCTION__+":Falha na CopyTicksRange - Esgotado o tempo de espera de sincronização, a função enviou tudo o que havia para '%s'",m_symbol);

         return(false);

      }

      if(GetLastError()==ERR_HISTORY_SMALL_BUFFER) {

         printf(__FUNCTION__+":Falha na CopyTicksRange - O buffer estático é muito pequeno, enviado tanto quanto cabia na matriz para '%s'",m_symbol);

         return(false);

      }

      if(GetLastError()==ERR_NOT_ENOUGH_MEMORY) {

         printf(__FUNCTION__+":Falha na CopyTicksRange - Não há memória suficiente para obter o histórico a partir do intervalo especificado na matriz dinâmica de ticks para '%s'",m_symbol);

         return(false);

      }

      return false;

   }

   else{

      int ticks=ArraySize(m_tick_array);

      //--- Mostrando a hora da primeira marca no array

      datetime firstticktime=m_tick_array[ticks-1].time;

      PrintFormat("Horário do último tick = %s.%03I64u, qtde de ticks = %d",

                  TimeToString(firstticktime,TIME_DATE|TIME_MINUTES|TIME_SECONDS),m_tick_array[ticks-1].time_msc%1000, m_ticks_total);

   }

   if(m_ticks_total < 1)

      return false;



   m_count_refresh++;



   return true;

}
Arquivos anexados:
 
fabianolr:

Pessoal boa tarde. Há tempos que tento solucionar um problema de congelamento da CopyTicksRange(), ela funciona perfeitamente por horas mas num determinado momento ela deixa de funcionar sem apresentar erro e não retorna mais a normalidade, bastando reiniciar o EA para voltar a funcionar normalmente. O código está abaixo e o LOG (anexo) há melhor compreensão do instante de congelamento, em resumo iniciei o EA as 11:08hrs e ele congela no horário 12:31hrs (Log anexado e de hoje).

Agradeceria se pudessem ajudar a resolver este congelamento inesperado, qualquer sugestão será bem vinda ...


NOTA ==>:   RefreshTicks é chamada a cada evento OnTick() e o simbolo é o WDO, porém testei com DOL, com WIN e IND e o problema também ocorre.

Comecemos com:

1- Por quê você precisa desses Ticks?

2- Qual uso será feito desses ticks?

Já de cara te falo  requisitar essa tonelada (e, a mesma tonelada!) a cada OnTick() é um erro gravíssimo...

 
Flavio Jarabeck #:

Comecemos com:

1- Por quê você precisa desses Ticks?

2- Qual uso será feito desses ticks?

Já de cara te falo  requisitar essa tonelada (e, a mesma tonelada!) a cada OnTick() é um erro gravíssimo...

1) Para montagem de um Value@Price... vide print abaixo:

De fato é uma tonelada, eu deixei assim para forçar o erro mais rapidamente, de outra forma o erro demora mais a acontecer... mas concordo contigo que é uma tonelada a cada OnTick() desnecessária... 


 
fabianolr:

Pessoal boa tarde. Há tempos que tento solucionar um problema de congelamento da CopyTicksRange(), ela funciona perfeitamente por horas mas num determinado momento ela deixa de funcionar sem apresentar erro e não retorna mais a normalidade, bastando reiniciar o EA para voltar a funcionar normalmente. O código está abaixo e o LOG (anexo) há melhor compreensão do instante de congelamento, em resumo iniciei o EA as 11:08hrs e ele congela no horário 12:31hrs (Log anexado e de hoje).

Agradeceria se pudessem ajudar a resolver este congelamento inesperado, qualquer sugestão será bem vinda ...


NOTA ==>:   RefreshTicks é chamada a cada evento OnTick() e o simbolo é o WDO, porém testei com DOL, com WIN e IND e o problema também ocorre.

Tente mudar a forma de solicitar para limitar por quantidade de eventos, na minha cabeca eh um absurdo muito grande pedir todos os ticks do dia contando que temos mais de 20milhoes de negocio no mini (isso sem considerar as movimentacoes do bid/ask que deve mover isso pra uns 80 milhoes facil...)

Se nao quiser trocar, o mais rapido seria ir pro OnTimer.
 
Ricardo Rodrigues Lucca #:

Tente mudar a forma de solicitar para limitar por quantidade de eventos, na minha cabeca eh um absurdo muito grande pedir todos os ticks do dia contando que temos mais de 20milhoes de negocio no mini (isso sem considerar as movimentacoes do bid/ask que deve mover isso pra uns 80 milhoes facil...)

Se nao quiser trocar, o mais rapido seria ir pro OnTimer.

Ricardo, agradeço pela rápida réplica, assim como agradeço ao Flávio.

Vou fazer a alteração no código conforme sugerido. Se persistir volto aqui no tópico... 

 
fabianolr:

Pessoal boa tarde. Há tempos que tento solucionar um problema de congelamento da CopyTicksRange(), ela funciona perfeitamente por horas mas num determinado momento ela deixa de funcionar sem apresentar erro e não retorna mais a normalidade, bastando reiniciar o EA para voltar a funcionar normalmente. O código está abaixo e o LOG (anexo) há melhor compreensão do instante de congelamento, em resumo iniciei o EA as 11:08hrs e ele congela no horário 12:31hrs (Log anexado e de hoje).

Agradeceria se pudessem ajudar a resolver este congelamento inesperado, qualquer sugestão será bem vinda ...


NOTA ==>:   RefreshTicks é chamada a cada evento OnTick() e o simbolo é o WDO, porém testei com DOL, com WIN e IND e o problema também ocorre.

Fabiano, tenho opinião parecida com o Ricardo. Se tiver dificuldade em implementar, me envie uma mensagem privada.

 
fabianolr #:

1) Para montagem de um Value@Price... vide print abaixo:

De fato é uma tonelada, eu deixei assim para forçar o erro mais rapidamente, de outra forma o erro demora mais a acontecer... mas concordo contigo que é uma tonelada a cada OnTick() desnecessária... 


Para isso você não precisa solicitar todos os ticks sempre. Usa o CopyTicksRange apenas na inicialização ou enquanto a solicitação falhar. CopyTicksRange deve ser usado para obter os dados mais antigos. Uma vez que obteve esses ticks mais antigos, você deve realizar a manipulação desses ticks e armazenar os resultados em arrays. Feito isso salva a data e horário dos último tick recebido. Daí pra frente quando for atualizar os dados utilize o CopyTicks para copiar os novos ticks a partir da data e horário do ultimo tick e utilize os dados salvos em arrays e os novos ticks para realizar os calculos e atualizar os arrays. Daí basta repetir :

salva a data e horário dos último tick recebido , copia os novos ticks a partir da data e horário do ultimo tick e utilize os dados salvos em arrays e os novos ticks para realizar os calculos  e atualizar os arrays .


Outra coisa. Quando usar o CopyTicksRange você pode fazer isso em etapas, não precisa tentar receber todos os dados de uma vez.

 

Um exemplo se quiser trabalhar com dados de 10 dias, solicitando um dia de cada vez.

MqlTick ticks[];
ulong compra = 0, venda = 0;
int shift = iBarShift(_Symbol, PERIOD_D1, iTime(_Symbol, PERIOD_D1, 10));
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void Function(void)
  {
   static ulong from = 0;
// primeira solicitação
   while(shift >= 0)
     {
      from = (ulong)iTime(_Symbol, PERIOD_D1, shift) * 1000;
      ulong to = (ulong)fmin(TimeCurrent(), from + 84600);
      if(CopyTicksRange(_Symbol, ticks, COPY_TICKS_TRADE, from, to) <= 0)
         break;
      ProcessarOsTicks(ticks);
      shift--;
     }
// se baixou todos os ticks apenas atualiza os novos ticks
   if(shift < 0)
     {
      int size = ArraySize(ticks);
      if(size > 0)
         from = ticks[size - 1].time_msc;
      ulong to = TimeCurrent();
      if(CopyTicks(_Symbol, ticks, from, to) > 0)
         ProcessarOsTicks(ticks);
     }
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void ProcessarOsTicks(MqlTick &ticks[])
  {
   /*
      para cada ticks
         se o tick teve alteração no tick buy
            soma o volume

            compra += tick[i].volume
         se o tick teve alteração no tick sell
            soma o volume

            venda += tick[i].volume
   */
  }
//+------------------------------------------------------------------+
 
Acima tem um erro, em vez de 
ulong to = TimeCurrent();

seria

ulong to = (ulong)TimeCurrent()*1000;
Razão: