MT5 crashes when using iClose() or CopyRates()

Hi,

I reported this issue already one year ago to MetaQuotes but never got a helpful response. Sometimes - don´t ask me when - a simple execution of functions) like iClose(), iTime() or CopyRates(), CopyTime() whatever takes more than 30 seconds until the code-pointer returns. And of course, when you execute several commands in a row, the EA crashes.

It happens with several brokers - only on live accounts - and with several symbols and all MT5 versions. I just never saw it with real futures, but with almost any other. It happens with a local internet connect, with a VPS, with my environment and with environment of customers, very rare, but it happens and only with MT5, not MT4. I already implemented a measurement and a forced termination of the EA, when the measurement detects a timeout (>4 seconds).

This is pretty annoying and I am sure, this is general problem of MT5, not a broker specific.

Any hints?

Thank you.

  1. Probably because you aren’t checking return codes and eventually getting a divide by zero or array exceeded.
  2. On MT5: Unless the chart is that specific pair/TF, you must Synchronize the terminal Data from the Server.
    Timeseries and Indicators Access / Data Access - Reference on algorithmic/automated trading language for MetaTrader 5
    Synchronize Server Data with Terminal Data - Symbols - General - MQL5 programming forum

I’ve got home-made indicators that use all of these: iClose(), iHigh(), iLow(), CopyRates(), CopyTime(), iBarShift(), Bars(), BarsCalculated().

I’ve never get the behavior you mention.

Perhaps you could build a minimal example EA or indicator in which this happens and post the code.

What kind of call to these functions ? Multi-symbol or chart symbol ? Multi-timeframes or chart timeframe ? Executed where (OnTick, OnTimer…) ?

What is returned by the function ? Is there are error reported ?

Why “of course” ? a crash is never “of course”. What are you calling an “EA crash” exactly ? Is there anything in the log ?

Is it a single EA instance or several ? If several, how much ? Are they accessing the same data ?

  1. Only chart symbol

  2. No error code at all, just a massive delay

  3. Nothing in the log

  4. Happens on single instance

  5. The code is called during OnTimer() and OnTick(), its simple:

datetime   _iTime(string symbolname, ENUM_TIMEFRAMES tf, int shift=0)
   {
      return iTime(symbolname,tf,shift));
   }

and with measurement using also CopyTime

long quotes_suspend_time=0;
#define QUOTES_MEASURE_TIME_INIT(retval) long t_begin = ::GetTickCount(); if (quotes_suspend_time>0 && t_begin-quotes_suspend_time<4000) { Print("Critical error: Timeout reading bar data!"); return retval; }
#define QUOTES_MEASURE_TIME_UPDATE long t_measure = ::GetTickCount(); quotes_suspend_time = (t_measure-t_begin>1000) ? t_measure : 0;

datetime   _iTime(string symbolname, ENUM_TIMEFRAMES tf, int shift=0)
   {
      //--- Get out with error when suspended
      QUOTES_MEASURE_TIME_INIT(0)
      //---
      datetime dt[];
      
      if (CopyTime(symbolname,tf,shift,1,dt)<0)
         return 0;
      QUOTES_MEASURE_TIME_UPDATE
      return dt[0];
   }

#2

Thank you! Will try this and keep this topic updated.

The EA analyzes history data, but normally not more than two weeks from the past. But anyway, who knows and maybe this is the solution.

But anyway, if such data is not present, shouldn´t these function return an error instead of freezing the EA?

Typically:

ERR_HISTORY_NOT_FOUND 4401 Requested history not found

Look for it using GetLastError(). Perhaps something like this:

datetime   _iTime(string symbolname, ENUM_TIMEFRAMES tf, int shift=0)
   {
      //--- Get out with error when suspended
      QUOTES_MEASURE_TIME_INIT(0)
      //---
      datetime dt[];
      
      ResetLastError();
      int copied = CopyTime(symbolname,tf,shift,1,dt);
      int lastError = GetLastError();
      if ( copied < 0 )
      {
         PrintFormat("error [%d]", lastError);
         return 0;
      }
      QUOTES_MEASURE_TIME_UPDATE
      return dt[0];
   }