Expert OnTick not called for every tick, but indicators is.

 

So I was experimenting to try and fully understand the way that Experts and Indicators work, especially for slow indicators.


But when I did a base-case test, just an Expert with a fast indicator, I noticed that the OnTick (or at least the print inside the ontick) does not call sometimes, even though the indicators detected a tick.


To demo the problem, here is an indicator


//+------------------------------------------------------------------+
//|                                               fast.mq5 |
//|                                                             Cloud |
//|                                                          http:// |
//+------------------------------------------------------------------+
#property copyright "Cloud" // Author

#property version "1.00"

int c = 0;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {

   return (INIT_SUCCEEDED);
  }

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
  
  Print(c + " -- indicator called");
  
c ++;
//--- return value of prev_calculated for next call
   return (rates_total);
  }
//+------------------------------------------------------------------+



Here is an expert:


//+------------------------------------------------------------------+
//|                                                     Observer.mq5 |
//|                                                  cloud |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Cloud"
#property link      "https://www.mql5.com"
#property version   "1.00"


int handles[1];
int c = 0;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {

   handles[0] = iCustom(NULL, PERIOD_M1, "Favs/Buffed/fast");

//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| "Tick" event handler function                                    |
//+------------------------------------------------------------------+
void OnTick()
  {
  
  
  Print(c + " --Expert-");
  
  c++;
        
        
  }
//+------------------------------------------------------------------+


And here is some sample output from the Experts tab.


2024.10.07 17:56:33.332 fast (EURJPY,M1)        194 -- indicator called
2024.10.07 17:56:33.332 slowfasttesting (EURJPY,M1)     182 --Expert-
2024.10.07 17:56:33.407 fast (EURJPY,M1)        195 -- indicator called
2024.10.07 17:56:33.407 slowfasttesting (EURJPY,M1)     183 --Expert-
2024.10.07 17:56:34.206 fast (EURJPY,M1)        196 -- indicator called
2024.10.07 17:56:34.206 slowfasttesting (EURJPY,M1)     184 --Expert-
2024.10.07 17:56:34.518 fast (EURJPY,M1)        197 -- indicator called
2024.10.07 17:56:34.518 fast (EURJPY,M1)        198 -- indicator called
2024.10.07 17:56:34.518 slowfasttesting (EURJPY,M1)     185 --Expert-
2024.10.07 17:56:34.568 fast (EURJPY,M1)        199 -- indicator called
2024.10.07 17:56:34.568 slowfasttesting (EURJPY,M1)     186 --Expert-
2024.10.07 17:56:34.617 fast (EURJPY,M1)        200 -- indicator called
2024.10.07 17:56:34.617 slowfasttesting (EURJPY,M1)     187 --Expert-
2024.10.07 17:56:34.658 fast (EURJPY,M1)        201 -- indicator called
2024.10.07 17:56:34.658 slowfasttesting (EURJPY,M1)     188 --Expert-


The indicator is called 2 times before the expert is called in some cases.

How can this happen?

Does the Expert wait for the indicators OnCalculate to complete all of it's ticks before running one time? Or is this a bug?

 

As per the documentation, EAs do not get called on every tick. If a tick event is being processed then any subsequent tick events that occur during that time, are not queued.

...

All events are handled one after another in the order of their receipt. If the queue already contains the NewTick event or this event is in the processing stage, then the new NewTick event is not added to mql5 application queue.

...

Documentation on MQL5: Event Handling / OnTick
Documentation on MQL5: Event Handling / OnTick
  • www.mql5.com
The function is called in EAs when the NewTick event occurs to handle a new quote. Return Value No return value Note The NewTick event is generated...
 

It should be noted that not only expert's OnTick event, but indicator's OnCalculate event does not guarantee to present every single tick to your program.

If you want to process all ticks, you should call CopyTicks function for the time span passed since previously processed tick - you can find an example of this in the algotrading book - search for processAllTicks().

 
Stanislav Korotky #:

It should be noted that not only expert's OnTick event, but indicator's OnCalculate event does not guarantee to present every single tick to your program.

If you want to process all ticks, you should call CopyTicks function for the time span passed since previously processed tick - you can find an example of this in the algotrading book - search for processAllTicks().

We had some discussions around this topic, as far as we could figure, OnCalculate will be called for all ticks.

Please see this thread for more details:



 
Dominik Egert #:
We had some discussions around this topic, as far as we could figure, OnCalculate will be called for all ticks.

Please see this thread for more details:

The fact that you successfully received all ticks in OnCalculate online during occasional test does not mean that it will can happen every time. I suppose it depends from many factors (number of programs running, CPU load, event queue size). Actually it's a [hidden and therefore undocumented] implementation specific of the terminal which can change in future in different ways. I'd not take it for granted that your program will receive all ticks in OnCalculate.

If I'm not mistaken, I remember similar tests in the past, where according to tick counters, they are skipped by the handlers. I don't have time to search forums for it right now.

MQL5 Book: Creating application programs / General principles for executing MQL programs / Overview of event handling functions
MQL5 Book: Creating application programs / General principles for executing MQL programs / Overview of event handling functions
  • www.mql5.com
The transfer of control to MQL programs, that is, their execution, occurs by calling special functions by the terminal or test agents, which the...
 
Stanislav Korotky #:

The fact that you successfully received all ticks in OnCalculate online during occasional test does not mean that it will can happen every time. I suppose it depends from many factors (number of programs running, CPU load, event queue size). Actually it's a [hidden and therefore undocumented] implementation specific of the terminal which can change in future in different ways. I'd not take it for granted that your program will receive all ticks in OnCalculate.

If I'm not mistaken, I remember similar tests in the past, where according to tick counters, they are skipped by the handlers. I don't have time to search forums for it right now.

Yes, I agree. Alain pointed this out as well, and reposted a post by Renat.

That's why I linked the thread, because it has most details on this topic, as far as I am aware.