Bug in bar shift for multi-currency EA

 

Hello,

I am developing a multi-currency EA and got a strange bug, which I don't understand. 

So what I am basically doing, is calling iClose(s, tf, shift) one minute after the close of the last H1 bar for a bunch of symbols to determine the past movement. To debug wrong live entries, I print out the iTime() and iClose().  

Only a few symbols are shown here, as you can see about half of the symbols have time1 = 09:00 and the other half time1 = 08:00. 

0 09:01:00.054 DebugEA EURUSD,H1: Checking bar at timeGMT: 2018.01.25 08:01:00

0 09:01:00.055 DebugEA EURUSD,H1: EURUSD | time1: 2018.01.25 09:00:00 | time2: 2018.01.25 08:00:00 | close1: 1.24191 | close2: 1.24358

0 09:01:00.056 DebugEA EURUSD,H1: USDJPY | time1: 2018.01.25 08:00:00 | time2: 2018.01.25 07:00:00 | close1: 108.954 | close2: 108.927

0 09:01:00.057 DebugEA EURUSD,H1: GBPUSD | time1: 2018.01.25 08:00:00 | time2: 2018.01.25 07:00:00 | close1: 1.42922 | close2: 1.42981

0 09:01:00.063 DebugEA EURUSD,H1: EURJPY | time1: 2018.01.25 09:00:00 | time2: 2018.01.25 08:00:00 | close1: 135.392 | close2: 135.492

...

So it seems that even one minute after the close of the bar the data is not yet loaded in MT4 for about half of the symbols. Is there anything one can do to force that data?

If iClose(s, tf, 1) randomly returns shift 1 or 2, one would really have to double check consistency of every single bar data. 

Thank you very much for your input!

 
Roman Lengert:

Hello,

I am developing a multi-currency EA and got a strange bug, which I don't understand. 

So what I am basically doing, is calling iClose(s, tf, shift) one minute after the close of the last H1 bar for a bunch of symbols to determine the past movement. To debug wrong live entries, I print out the iTime() and iClose().  

Only a few symbols are shown here, as you can see about half of the symbols have time1 = 09:00 and the other half time1 = 08:00. 

0 09:01:00.054 DebugEA EURUSD,H1: Checking bar at timeGMT: 2018.01.25 08:01:00

0 09:01:00.055 DebugEA EURUSD,H1: EURUSD | time1: 2018.01.25 09:00:00 | time2: 2018.01.25 08:00:00 | close1: 1.24191 | close2: 1.24358

0 09:01:00.056 DebugEA EURUSD,H1: USDJPY | time1: 2018.01.25 08:00:00 | time2: 2018.01.25 07:00:00 | close1: 108.954 | close2: 108.927

0 09:01:00.057 DebugEA EURUSD,H1: GBPUSD | time1: 2018.01.25 08:00:00 | time2: 2018.01.25 07:00:00 | close1: 1.42922 | close2: 1.42981

0 09:01:00.063 DebugEA EURUSD,H1: EURJPY | time1: 2018.01.25 09:00:00 | time2: 2018.01.25 08:00:00 | close1: 135.392 | close2: 135.492

...

So it seems that even one minute after the close of the bar the data is not yet loaded in MT4 for about half of the symbols. Is there anything one can do to force that data?

If iClose(s, tf, 1) randomly returns shift 1 or 2, one would really have to double check consistency of every single bar data. 

Thank you very much for your input!

That is not a bug

Data (tick) for different symbols does not have to come in the same moment hence you can have completely different bar times for different symbols (not just the current bar). Use time as a criteria when retrieving other symbol bar data (not bar numbers - do it in a similar manner as multi time frame calculations are done)

 
Mladen Rakic:

That is not a bug

Data (tick) for different symbols does not have to come in the same moment hence you can have completely different bar times for different symbols (not just the current bar). Use time as a criteria when retrieving other symbol bar data (not bar numbers - do it in a similar manner as multi time frame calculations are done)


Thanks a lot for your fast reply. 

Hm, sure it does not have to come at the same moment. But one full minute after a new bar I dont see a reason why it should not be available, except maybe during night when there are only few ticks. 

So, would you say it is then safe to use the iBarShift(s, t, TimeCurrent()-3600) as the shift, if I want to have the bar one hour ago? Or maybe even store the closes in an own array?

 
Roman Lengert:

Thanks a lot for your fast reply. 

Hm, sure it does not have to come at the same moment. But one full minute after a new bar I dont see a reason why it should not be available, except maybe during night when there are only few ticks. 

So, would you say it is then safe to use the iBarShift(s, t, TimeCurrent()-3600) as the shift, if I want to have the bar one hour ago? Or maybe even store the closes in an own array?

Why do you think that there is some time limit when a price change must happen?

There is no rule that is saying anything like that. And since there is no such rule, we are forced to use in code what I have described in previous message. Also, imagine this :

  • a missing bar (and that happens all the time)
  • you are trying to access bars before that missing bar
  • what times are you going to get for those bars if you are using bar number without checking the time?

Use time based bar numbers for accessing other symbols data and the times will align

To access data as in your first message, do the following : iClose(s, tf, iBarShift(s, tf, Time[shift])), but do not expect to have same times. It is up to the broker when will the data of "other" symbol be updated

 

I would have expected that the data the terminal gets is always in tick format, and that the bars are calculated based on the ticks. This way, the bar data would always be available from the first tick of the bar (of cause this does not make much sense if you want historic data a long time ago). But I did not know how exaclty MT4 works in this regards.

Thanks for clarification. :)

Not sure what you mean with "do not expect to have same times" though. If I call iBarShift(s, tf, Time[shift]) the time should always be the same, but the shift can differ as I understand it. 

 
Roman Lengert:

I would have expected that the data the terminal gets is always in tick format, and that the bars are calculated based on the ticks. This way, the bar data would always be available from the first tick of the bar (of cause this does not make much sense if you want historic data a long time ago). But I did not know how exaclty MT4 works in this regards.

Thanks for clarification. :)

Not sure what you mean with "do not expect to have same times" though. If I call iBarShift(s, tf, Time[shift]) the time should always be the same, but the shift can differ as I understand it. 

Bar n on one symbol does not have to have same time as bar n on another symbol (regardless of the same time frame - especially on a lower time frames where missing bars are regular)

Hence, if you are aligning only bar numbers with other symbol, you might end up with showing data on a current chart on a wrong time (place)

 
  1. On MT4: Unless the current chart is the specific pair/TF referenced, you must handle 4066/4073 errors.
              Download history in MQL4 EA - MQL4 and MetaTrader 4 - MQL4 programming forum

  2. Do not assume shifts are the same, you must use iBarShift.
 
whroeder1:
  1. On MT4: Unless the current chart is the specific pair/TF referenced, you must handle 4066/4073 errors.
              Download history in MQL4 EA - MQL4 and MetaTrader 4 - MQL4 programming forum

  2. Do not assume shifts are the same, you must use iBarShift.

Thanks, I think I learned that now. :) Still one could ask why a function iClose(...) exists if it is not time consistent, but don't want to start a discussion. 

 
Jonas Müller: Still one could ask why a function iClose(...) exists if it is not time consistent,

IClose, iHigh, etc. are consistent except for bar zero, (the forming one.) You never know what tick was be the last tick, until a new bar starts. IClose(0) is the last received tick (Bid) and will be the close if no more ticks are received for the bar's duration. Same as iHigh, it shows the current highest bar price. That may or not be the final high until the bar closes.

If you look at bar zero, everything is subject to change (except the open price and open time.)

 
whroeder1:

IClose, iHigh, etc. are consistent except for bar zero, (the forming one.) You never know what tick was be the last tick, until a new bar starts. IClose(0) is the last received tick (Bid) and will be the close if no more ticks are received for the bar's duration. Same as iHigh, it shows the current highest bar price. That may or not be the final high until the bar closes.

If you look at bar zero, everything is subject to change (except the open price and open time.)

If iClose(s, t, 1) can have different times even if the bar is already finished for many ticks (as my example above shows) than I would not call it consistent. Still handling so much data is challaging so I know there won't be a perfect solution. Even though I never had this type or problem in other languages like JForex API etc, but there are other problems there, so one has to get used to every system and code accordingly. 

 

Internally the MetaTrader protocol to the quote server is a FIX dialect (google that). It means you have to subscribe/unsubscribe to symbols you want to get quotes for. As an end user you have to select/unselect symbols you are interested in in the "Market Watch" window (the UI for quote subscription managment). Adding a symbol to the "Market Watch" window subscribes, removing it unsubscribes from the quote feed (in reality it's a bit more complicated but for a general understanding this picture is enough).

The process of subscribing/unsubscribing to quotes is what causes the infamous error ERR_HISTORY_WILL_UPDATED. At the time you request bar data with iClose() etc. there are no current quotes in the terminal, only the previous ones which can be hours or even days old. Now this is what you see in your Debug EA. The missing bars are loading but haven't been received the moment you execute your debug statement.

Imagine the consequences if you'd like to always have current quotes. The terminal had to pull quotes for all available symbols and all the time. This would exceed every available bandwidth on the broker side, and on your own side too. That's why you get everywhere the advice to "remove unneeded symbols from the Market Watch window to save resources" (i.e. bandwidth) if you run an EA.

What you'r experiencing is just the way the terminal handles the underlying quote feed, and not a bug.