Is it possible to work with live ticks in MQL5 indicators? - page 5

Dominik Egert  
Fernando Carreiro #:

Yes, I am beginning to see that this may indeed be the case, and it also explains why the indicators stall/freeze so much during high impact news.

I suppose, maybe we could enhance the testing code even further.

But one thing is for sure, it is completely different than we have anticipated...

MQL stays a box of surprises...
Dominik Egert  
phade #:

Hm ok, but I thought OnCalculate is per-bar data. I assumed that to gather tick data, we have to go back in time until after a bar (of minimum 1 minute) has occurred. Let me know if I'm mistaken here, and if so, I'd like to see a small example of a for loop capturing ticks in OnCalculate (nested for loop I'm guessing)

For an actual example, see my second test indicator code. It retrieves all ticks coming in on live markets.

Should give you an idea on how to get tick data as you require.
phade  
Dominik Egert #:
For an actual example, see my second test indicator code. It retrieves all ticks coming in on live markets.

Should give you an idea on how to get tick data as you require.

Thanks Dominik, I will take a look at this

Samuel Manoel De Souza  

@Dominik Egert was correct in his inital stament. It is called for all live tick.

This is my test. I tested with and without delay. Even when the chart freezes the result is the same.

//+------------------------------------------------------------------+
//|                                             OnCalculateCheck.mq5 |
//|                           Copyright 2023, Samuel Manoel De Souza |
//|                          https://www.mql5.com/en/users/samuelmnl |
//+------------------------------------------------------------------+
#property copyright "Copyright 2023, Samuel Manoel De Souza"
#property link      "https://www.mql5.com/en/users/samuelmnl"
#property version   "1.00"
#property indicator_chart_window
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping

//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
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[])
  {
//---
   static int calls = 0, copied = 0;
   static datetime time_open = 0, time_close = 0;
   if(prev_calculated == 0)
     {
      calls = 0;
      time_open = 0;
      time_close = 0;
      copied = 0;
      Print("Test started.");
     }

   ArraySetAsSeries(time, true);
   if(time_open == 0 && rates_total - prev_calculated == 1)
     {
      time_open = time[0];
      Print("range start set to ", (string)time_open);
     }

   if(time_open == time[0])
      calls++;

   if(time_close == 0 && rates_total > 1 && time_open == time[1])
     {
      time_close = time[0];
      Print("range end set to ", (string)time_close);
     }

   if(time_close > 0 && copied <= 0)
     {
      MqlTick ticks[];
      copied = CopyTicksRange(_Symbol, ticks, COPY_TICKS_ALL, 1000 * (long)time_open, 1000 * (long)time_close);
      if(copied > 0)
        {
         while(copied > 0 && ticks[copied-1].time >= time_close)
            copied--;
         Print("In the period from  ", (string)time_open, " to ", (string)time_close,
               " the OnCalculate was called ", (string)calls, " times, and CopyTicksRanges copied ", (string)copied, " ticks.");
        }
     }
   
   uint tick_count = GetTickCount();
   while(GetTickCount() - tick_count < 10)
     {
      
     }
   
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
Dominik Egert  
Samuel Manoel De Souza #:

@Dominik Egert was correct in his inital stament. It is called for all live tick. i don't know for historical.

This is my test. I tested with and without delay. Event when the chart freezes the result is the same.

Actually, OnCalculate is only called by new ticks.

Even the initial run is first triggered by a tick arrival.

So you get the first live tick, then you calculate all historical periods in your loop, you return rates_total, then you get tick updates.

Even if you are not done with the history, and return a value lower than rates_total, your next call will be triggered only by a new tick arrival.

That's why I have the split calculations called step interval in my testing code, to show this. And to show how to make sure, the terminal does not complain about slow indicator calculations.
Samuel Manoel De Souza  
Dominik Egert #:
Actually, OnCalculate is only called by new ticks.

Even the initial run is first triggered by a tick arrival.

So you get the first live tick, then you calculate all historical periods in your loop, you return rates_total, then you get tick updates.

Even if you are not done with the history, and return a value lower than rates_total, your next call will be triggered only by a new tick arrival.

That's why I have the split calculations called step interval in my testing code, to show this. Andto show how to make sure, the terminal does not complain about slow indicator calculations.

yeah, i did edit my post. i remember it is called only once after in the initialization and for new ticks.

Alain Verleyen  
Samuel Manoel De Souza #:

@Dominik Egert was correct in his inital stament. It is called for all live tick.

This is my test. I tested with and without delay. Even when the chart freezes the result is the same.

More than 5,000 ticks in 1 minute, what symbol is that ?
Samuel Manoel De Souza  
Alain Verleyen #:
More than 5,000 ticks in 1 minute, what symbol is that ?

WINV23, exchange is B3 in Brazil.

phade  
CopyTicksRange(_Symbol, ticks, COPY_TICKS_ALL, 1000 * (long)time_open, 1000 * (long)time_close);


Why is it that we multiply 1000 by the time? I've seen this in other codebase codes as well and I'm confused about this

Reason: