Within OnCalculate, how can I know if the current bar has ended (the last tick was received) without waiting for the start of a next bar?

 

Hi,

I'd like to know how can I know, within an indicator's OnCalculate, that the current bar is finished (that is, no new ticks will be send to that bar) without having to wait for a new tick, a new call of OnCalculate, addressed to the next bar.

The scenario I have in mind: I have an indicator that sends alerts, such as e-mail and sounds, whenever a certain condition is met. That indicator may be loaded when the market is off (e.g at Sunday by someone preparing swing trade operations for the next week) or when is on (e.g. someone going to daytrade, but woke late). The same indicator might be loaded both for a very liquid asset awa one without many trades (like one that, in the M1 timeframe, may lack any trades for minutes in a row).

Suppose the scenario is high liquidity and market on. In this case, I can conclude the candle is finished and it's time to check for the alert condition whenever a new bar has just started, i.e. the first tick of the new bar arrived, which is what I've been doing. But suppose I'm trading with low liquidity: in this case, a bar with the alert condition may have been finished, but a new tick only arives minutes later. In this case, my alert will be send with minutes of delay away from the ideal moment of evaluation. Or consider the indicator in a Daily timeframe for swing trade with the last bar in the alert condition: in this case, no new ticks, no new call to OnCalculate will be send until the reopening of the market the next day, so there would be hours of delay between the signal formation and the sending of the alert!

So it seems what I need is a way to know if the current bar is finished without depending on a new call of OnCalculate related to a next bar. I consulted Copilot on this and it suggested looking at TimeCurrent and comparing with the current's bar "time length" to see this as follows:

    // Get the current server time
    datetime current_time = TimeCurrent();

    // Get the end time of the last bar
    datetime last_bar_end_time = time[rates_total - 1] + PeriodSeconds();

    // Check if the current time is past the end time of the last bar
    bool is_bar_finished = current_time >= last_bar_end_time;

    if (is_bar_finished)
    {
        // The current bar is finished
        Print("The current bar is finished.");
    }
    else
    {
        // The current bar is still forming
        Print("The current bar is still forming.");
    }

But it seems this code is flawed. In the low liquidity asset, the last call of OnCalculate might be from a trade in the middle of the current bar. From within this OnCalculate call, the value of TimeCurrent will still fall within that bar, so no alert will be send (what is plausible since the time of the bar is still open and maybe new ticks will arrive). Then the bar closes, minutes pass without any call to OnCalculate, and I get my problem. Now for the swing trade scenario, if I'm running this in an asset whose market closes before another, this would work (e.g. in Brazil's, stocks close at 17h while futures at 18:25). But what if I'm running the indicator precisely in the asset that produced the last ticks of the market? Then depending on TimeCurrent doesn't seem like a good idea.

An idea I had was to use the OnTimer event to check with the above function: in this case, at most I'd get a 1 second delay between the closing of the bar and alert checking, but this would still leave open the possibility of no alert being send if I'm working in the asset that produced the last tick in the Market, so not a perfect solution.

So, any better ideas?

 
Martin Bittencourt: I'd like to know how can I know, within an indicator's OnCalculate, that the current bar is finished (that is, no new ticks will be send to that bar) without having to wait for a new tick, a new call of OnCalculate, addressed to the next bar.

That is impossible! Can you predict the future?

The best you can do is monitor the current server time and assume that when the time is up for the current bar, that the next tick will be for a new bar.

However, even that is not fool-proof. Late quote data can arrive with a previous time stamp due to various reasons, especially during high volatility.

 
Martin Bittencourt:

An idea I had was to use the OnTimer event to check with the above function: in this case, at most I'd get a 1 second delay between the closing of the bar and alert checking, but this would still leave open the possibility of no alert being send if I'm working in the asset that produced the last tick in the Market, so not a perfect solution.

I don't see problems with this approach to monitor both ticks and timer - whichever one is fired first, you check conditions and make alerts.

 
Fernando Carreiro #:

The best you can do is monitor the current server time and assume that when the time is up for the current bar, that the next tick will be for a new bar.

However, even that is not fool-proof. Late quote data can arrive with a previous time stamp due to various reasons, especially during high volatility.

Yes, that's the only feasible solution and we should admit that with a (presumably small) probablity latest signal can be not 100% accurate due to trailing ticks coming too late and changing already closed (considering time boundaries) bar.

Actually, it happens that a broker changes even deeper history of quotes. We can do nothing, but count and take these specific risks.

Those who require higher accuracy, I suppose should construct conditions on ticks only, not on bars.

 
One of many flaws of MT5, IMHO.
MT5 should retrigger OnTick() on start (or end) of every candle even when there is no real tick arrives. (a #property flag could be use to enable this feature)
Then we don't have to deal with OnTimer() limitation.

For reference:
https://www.mql5.com/en/book/applications/timer/timer_ontimer
MQL5 Book: Creating application programs / Working with timer / Timer event: OnTimer
MQL5 Book: Creating application programs / Working with timer / Timer event: OnTimer
  • www.mql5.com
The OnTimer event is one of the standard events supported by MQL5 programs (see section Overview of event handling functions ). To receive timer...
 
Soewono Effendi #:
One of many flaws of MT5, IMHO.
MT5 should retrigger OnTick() on start (or end) of every candle even when there is no real tick arrives. (a #property flag could be use to enable this feature)
Then we don't have to deal with OnTimer() limitation.

Personally, I do not agree. Every event handler must do what its name implies, or in other words - have a single responsibility.

It's illogical and unexpected to trigger OnTick without a tick. OnTimer is a proper way of dealing with intervals when ticks are missing.

 
Stanislav Korotky #:

Personally, I do not agree. Every event handler must do what its name implies, or in other words - have a single responsibility.

It's illogical and unexpected to trigger OnTick without a tick. OnTimer is a proper way of dealing with intervals when ticks are missing.

I see your point and agree to some extend. Maybe MetaQuotes could create a new event that is triggered every time a bar is/should be closed regardless of new ticks arriving? This way, it wouldn't make OnTick have two meanings, but we also wouldn't have to trigger a periodic timer to constantly check if the bar has closed or not with all the imprecisions such method may bring.

Btw, a user send me a personal message suggesting that synchronizing local time with server time could help in this scenario. Here is what I thought about it: suppose I load only one symbol in Market that doesn't have much liquidity. Then my indicator has a timer that every second checks TimeCurrent to see if the bar has closed to do the alert checking. But in this scenario, in case the last tick was in the middle of the bar's time, that bar ended and no more ticks were send, the next time OnTimer is triggered and the code tries to do the checking, it won't notice that bar has closed since TimeCurrent considers the datetime of the last tick of the symbols loaded in the Market list. To counter this, at the start of OnTick, the code would try to get the time distance between TimeCurrent and TimeLocal and, from that on, use the local time to check for the closing of the bar. Since the local time could be changed, either manually or because the OS did a clock update, that "get the difference code" inside OnTick should always be run to keep the distance between server time and local time always updated.

So, is this a valid approach or am I missing something?

 
Martin Bittencourt #:

I see your point and agree to some extend. Maybe MetaQuotes could create a new event that is triggered every time a bar is/should be closed regardless of new ticks arriving? This way, it wouldn't make OnTick have two meanings, but we also wouldn't have to trigger a periodic timer to constantly check if the bar has closed or not with all the imprecisions such method may bring.

Btw, a user send me a personal message suggesting that synchronizing local time with server time could help in this scenario. Here is what I thought about it: suppose I load only one symbol in Market that doesn't have much liquidity. Then my indicator has a timer that every second checks TimeCurrent to see if the bar has closed to do the alert checking. But in this scenario, in case the last tick was in the middle of the bar's time, that bar ended and no more ticks were send, the next time OnTimer is triggered and the code tries to do the checking, it won't notice that bar has closed since TimeCurrent considers the datetime of the last tick of the symbols loaded in the Market list. To counter this, at the start of OnTick, the code would try to get the time distance between TimeCurrent and TimeLocal and, from that on, use the local time to check for the closing of the bar. Since the local time could be changed, either manually or because the OS did a clock update, that "get the difference code" inside OnTick should always be run to keep the distance between server time and local time always updated.

So, is this a valid approach or am I missing something?

To my understanding, the first of your paragraphs actually implies or makes it sufficient to use the timer event, because bar times are aligned with predefined intervals, which the timer does.

In your second paragraph you probably mean that you want to use TimeTradeServer (instead of TimeCurrent) adjusted by the intra-hour different between the local clock and the server clock, something like TimeTradeServerExact() from the algotrading book.

 
Stanislav Korotky #:

In your second paragraph you probably mean that you want to use TimeTradeServer (instead of TimeCurrent) adjusted by the intra-hour different between the local clock and the server clock, something like TimeTradeServerExact() from the algotrading book.

Yeah, I guess that's it.

So, what I got of this interesting debate so far is: if I have an indicator with some alert functionatility that should be triggered ASAP in case its condition appears in the last bar once finished/closed, then given both the possibility of loading this indicator when the market is off or in low liquidity assets, scenarios in which the next tick may arrive far after the last bar is closed, I can't resort to wait for the next tick to arrive to make the alert analysis, rather I have to set a timer to periodically monitor if the bar has closed and make my alert evaluation.

So my attention now turns to how exactly I can know from withing OnTimer event if the bar has finished without waiting for a new tick with a timestamp that tells me so. The natural way is in accordance with Fernando's reply, which is what I have implemented so far: I get "how many seconds are there until the current bar is supposed to close", set the Timer to fire right after that and do the alert checking in some specific parts of my code. And with my preliminary tests so far, is good enough.

But I was thinking on how exactly I could make that work in a Daily chart, for in that case (and higher timeframes) the end of the bar doesn't coincide with with the closing of the market.

For example, suppose I have my indicator loaded in the Daily timeframe of a stock chart from Brazil's stock market which closes at 17h and I open the terminal at 18h. Given the time, the bar is closed and I should do the alert check. The problem, though, is that the bar itself only closes at 23:59:59! So it seems the approach I was considering would give me the false understanding that the bar is still open and new ticks may arrive, so no alert evaluation should be done, when the opposite is true. 

So how could I handle this scenario, at least without demanding from the user the datetime of the market's close as an input variable? :| A user suggested looking into the functions "SymbolInfoSessionQuote" and "SymbolInfoSessionTrade" for that info, functions that would basically give me exactly what I need, but testing the scripts in the Help Files of both functions in both demo and realtime accounts gave me no results (datetimes were set to 0). I have the impression my broker (and, thus, probably others as well) isn't filling up the MT5 system with that information, or some other problem may be happening (the functions themselves didn't return any error). And btw the help files on those functions have problems.

Now I'm having a "feeling" I'll need two codes, one for intraday timeframes and another for daily and higher if I want to avoid requiring the user to manually inform the hour of the ending of the market. Maybe I should look at the M1 timeframe of that asset from the day before and look at the datetime of its last tick and assume the market is closing the next rounded half hour after that. So if it's 18h as in my example, I look at M1 from the previous day and find a datetime of 16:52, I assume the Daily bar closes at 17h and, since one hour has passed, do the alert checking. The problem is that this value is not fixed: from time to time, at least here in Brazil the ending of the market changes; now Futures ends at 18:29, but some time ago it was 18:00, so this method would open the possibility of eventually sending an alert before or later than what it should. 

So, any better ideas? :)

 
Martin Bittencourt #:
SymbolInfoSessionQuote and SymbolInfoSessionTrade

You can open symbol specification in GUI and look there if sessions are specified. Normaly they are, and you should get the same times via MQL5 API.

You may look at examples in the algotrading book, if you don't like the documentation.

MQL5 Book: Trading automation / Financial instruments and Market Watch / Schedules of trading and quoting sessions
MQL5 Book: Trading automation / Financial instruments and Market Watch / Schedules of trading and quoting sessions
  • www.mql5.com
A little later, in further chapters, we will discuss the MQL5 API functions that allow us to automate trading operations. But first, we should...
 
Stanislav Korotky #:
You can open symbol specification in GUI and look there if sessions are specified. Normaly they are, and you should get the same times via MQL5 API.

I did that and confirmed: both my brokers (actually their base, XP, is the same) don't give that information :(

Funny fact is that I did some research on Google (and IA) on how to handle this problem and I found another Brazilian trader reporting the same SymbolInfoSessionTrade/Quote problem ^^ I'm going to report that to the broker and hope it will change, but in the middle time, I'm going to study the alternatives that I found, including some similar to the link you provided. Since I found other posts (mainly from MQL4) reporting the same kind of doubt, whatever solution I found, I'll bring it here.