MQL4: missing ticks

 

Hi

here is a simple expert advisor which writes some tickdata for each tick arriving, and - if there is a new 1 minute bar - writes some bar data to a file:

 

#property strict
int g_fp;
class CNewTick {
   private:
   string m_symbol;
   long m_tickno;
   public:
   void Init (string symbol) {
      m_symbol = symbol;
      m_tickno = 0;
   }
   void Reset () {
      m_tickno = 0;
   }
   void WriteTickdata () {
      MqlTick last_tick;
      if(SymbolInfoTick(m_symbol,last_tick)) {
         string digits = IntegerToString (SymbolInfoInteger (m_symbol, SYMBOL_DIGITS));
         int spread = (int)MathRound((last_tick.ask-last_tick.bid)/SymbolInfoDouble(m_symbol,SYMBOL_POINT));
         FileWrite(g_fp, StringFormat ("%7I64d", ++m_tickno), " ", m_symbol, " ", last_tick.time,
            StringFormat(", bid %8."+digits+"f",last_tick.bid),
            StringFormat(", ask %8."+digits+"f",last_tick.ask),
            StringFormat(", Spread %4d", spread));        
      } else FileWrite(g_fp, "SymbolInfoTick() failed, error = ", GetLastError());
   }
};
class CNewBar {
   private:
   string m_symbol;
   ENUM_TIMEFRAMES m_timeframe;
   datetime m_lastbartime;
   public:
   void Init (string symbol, ENUM_TIMEFRAMES timeframe) {
      m_symbol = symbol;
      m_timeframe = timeframe;
      m_lastbartime = 0;
   }
   bool IsNewBar () {
      bool ret = true;
      datetime bartime = iTime (m_symbol, m_timeframe, 0);
      if (bartime == m_lastbartime) return false;
      if (m_lastbartime == 0) ret = false;
      m_lastbartime = bartime;
      return ret;
   }
   void WriteBardata () {
      RefreshRates(); //may be unneccessary???
      string digits = IntegerToString (SymbolInfoInteger (m_symbol, SYMBOL_DIGITS));
      FileWrite (g_fp, m_symbol, " ", iTime(m_symbol, m_timeframe, 1),
            StringFormat("%10s",EnumToString(m_timeframe)),
            StringFormat(" iOpen %8."+digits+"f",iOpen(m_symbol, m_timeframe, 1)),
            StringFormat(" iHigh %8."+digits+"f",iHigh(m_symbol, m_timeframe, 1)),
            StringFormat(" iLow  %8."+digits+"f",iLow(m_symbol, m_timeframe, 1)),
            StringFormat(" iClose %8."+digits+"f",iClose(m_symbol, m_timeframe, 1)),
            StringFormat(" iVolume %6I64d", iVolume(m_symbol, m_timeframe, 1)));
   }
};

/*-------------------------------------*/
CNewTick g_NewTick;
CNewBar g_NewBarM1;
int OnInit() {
   g_fp = FileOpen (Symbol() + "TickCounter.csv", FILE_TXT|FILE_WRITE);
   g_NewTick.Init (Symbol());
   g_NewBarM1.Init (Symbol(), PERIOD_M1);
   return INIT_SUCCEEDED;
}
void OnDeinit(const int reason) {
   FileClose (g_fp);
}
void OnTick() {
   if (g_NewBarM1.IsNewBar ()) {
      g_NewBarM1.WriteBardata ();
      g_NewTick.Reset ();
   }
   g_NewTick.WriteTickdata ();
}

 

 

 I noticed that very often (not always) the number of ticks written into the output file is smaller than the volume of the belonging bar.

E.g.:

 

 

For the M1-Period 17:52:00 I would expect 14 ticks but I only see 13????

 

Often the discrepancies are much greater, for example the volume of the M1-Period  is 142, but there are only 121 ticks.

Do I suffer from a basic misunderstanding? Is there any error in the mql4-Program? Or may be a performance issue: the expert advisor is too slow (although it does not do much)?

I'm grateful for any answer. Thank you.

Matthias/Bobcat 

 

There is always lost ticks if you use OnTick(), please read the documentation. See https://www.mql5.com/en/forum/14960

You have to use CopyTicks().

 
Alain Verleyen:

There is always lost ticks if you use OnTick(), please read the documentation. See https://www.mql5.com/en/forum/14960

You have to use CopyTicks().

Hallo Alain,

thanks for your answer.

Unfortunately I cannot find CopyTicks() in MQL4, only in MQL5. But I'm using MQL4 :-(

 

Matthias 

 
Dr Matthias Hammelsbeck:

Hallo Alain,

thanks for your answer.

Unfortunately I cannot find CopyTicks() in MQL4, only in MQL5. But I'm using MQL4 :-(

 

Matthias 

Sorry I didn't note it was for mql4.

For mql4, there is no 'true' solution. You can use a VPS to reduce the latency and optimize your code to return quickly so you will minimize the chance to loss ticks.

Reason: