Is EA faster than MT4 internal series array Open[]?

 
GENERAL DESCRIPTION:

In my EA I have an array called 'TickData' which saves incoming Bid price changes and Time with each incoming tick (skipping changes in Ask prices only).

I made a search function for this array, which receives a 'timestamp' value as input, and finds the first index inside the 'TickData' array which corresponds with that 'timestamp'.

If no exact match is found, it looks for the closest match which is *larger* than the 'timestamp' value. The function then returns the Bid price at that index.

To test it's accuracy, I went ahead and used Time[0] as it's input, essentially to give me the Open[0] price of current bar, but using data from TickData array only.

THE RESULT:

The result between my function, and the price of Open[0] is identical 99% of the time!

Occasionally there is a difference of 1 point between them, but that's because my function is more accurate, calculating the first *actual* incoming tick after Bar Open time, while the value of Open[0] is automatically set to the last known price of previous tick at the formation of a new bar, in the event that no price changes occurred at bar open time.

PROBLEM:

On very rare occasions, I noticed that the difference between Bid price returned by my function and the one returned by Open[0] series array is quite large (20+ pts. difference). Once a new bar started to form however this would sort itself out.

I could not explain this very substantial CHANGE, and so I added in a code in my function to Alert me when a difference is larger than 20 pts. and output the Time/Bid of the index in 'TickData' which was found by my search function, along with the previous index, and the value of Time[0]/Open[0] of the bar.

Here are the results (format: TIMESTAMP-PRICE):

Alert: Index before: 1330359299-1.34081 Bar Open Time/Value: 1330359300-1.34048 Index from: 1330359300-1.34082

In essence at the exact same moment it time (of 1330359300), 'TickData' array recorded one price, but internal series array Open[0] recorded a TOTALLY different one!

As a result, there was a big mismatch between the Bid price returned by my function compared to Open[0].

I looked at the M1 timeframe from the time this started to happen (i.e. bar open time), and there was indeed a *relatively* large spike in price:



Apparently it corresponded with the moment of bar open time. This is why it's so rare.

What I don't understand is, why my EA missed this change and didn't record it? i.e. the earliest Bid price info it had for time 1330359300 was 1.34082, and yet the internal series Array Open[0] recorded the price 1.34048 at that exact moment, which also happens to represent a big jump in price!

QUESTIONS:

If several VERY FAST changes happened in that 1 second at time index of 1330359300, could it be that the EA was FASTER, and so it actually managed to capture the change in price which came just slightly before but in that same second compared to the price recorded by Open[0]? i.e. it actually DID capture the change recorded by Open[0] only it came after the first change it had recorded for that second?

Alternatively, between time 1330359299 and 1330359300, the changes were SO FAST, that the EA missed that price spike entirely because it was still performing calculations for the tick at price 1.34082! However that seems unlikely because there's a whole second difference there (plenty of time for the EA), and so if the price recorder by Open[0] was the first price change for the moment of 1330359300, then EA should have captured it first!

However, because of the continuity of 1.34081-1.34082, from one second to the next, inside 'TickData' array I think the first explanation is more probable, unless in between there was a price spike of over 30 pts. (to 1.34048) and then it just happened to drop back down to exactly 1 point above the previous price before the spike.

Since I am unable to precisely test this, as I did not include in my debug code the output of ALL 'TickData' entries for that second, and any changes now will just reset the EA, I can only speculate at this point, and would like some feedback!

Is Open[0] slower and LESS accurate than EA in capturing multiple prices changes in timespan of 1 second or less?

Thanks for reading!!! :)

nanquan
 
nanquan:

Alternatively, between time 1330359299 and 1330359300, the changes were SO FAST, that the EA missed that price spike entirely because it was still performing calculations for the tick at price 1.34082! However that seems unlikely because there's a whole second difference there (plenty of time for the EA), and so if the price recorder by Open[0] was the first price change for the moment of 1330359300, then EA should have captured it first!

It's much more likely that the EA is slow rather than the terminal being slow. The terminal is running a simple task which is well established. The EA is not fully tested. I give the EA a much higher chance of being the problem!

In the other thread you asked how I would handle the "gruesome" ArrayResize thing. I never actually answered although I did start formulating a response. The thing is that any time an ArrayResize happens the delay is quite badly defined. Thinking of this from a data structure point of view, I don't believe that MQL4 double arrays can be linked lists. New data has to be contiguous in order to make memory addressing simple. That forces a memory copy at some point when a new contiguous memory block is allocated. How long will this take? Well how big are the arrays? If you are logging tick data for days the arrays could start to get quite big.

To get an idea you could write a little script to measure it. Store the start time. Allocate a 100,000 element double array and fill with the index for each position ( bigArray[3]= 3 etc ) Increment the array size by 1000 elements in a loop say 100 times ( no need to fill the new elements). Store the end time. Print end time - start time. If the start and end times differ by more than a few seconds that may be your problem.

 

Well here is the script test code ...

double bigArray[1000000];

int init(){
   Comment( "start");
   for( int n=0; n<1000000; n++ )
      bigArray[n] = n;
}

int start(){
   
   Comment("");
   
   datetime start = TimeCurrent();
   for( int n=0; n<1000; n++ )
      ArrayResize(bigArray, 1000000 + n*1000);
   
   datetime end = TimeCurrent();
   Comment( "Duration was " + (end-start) + " seconds" ); 
   Print( "Duration was " + (end-start) + " seconds" ); 
   
   return(0);
}

It takes 17 seconds on my machine. I withdraw my objections to the ArrayResize. I guess they are using a low level hardware DMA transfer so it is blindly fast (17ms)

 

Hey dabbler,

Thank you for your input, and also for taking the time to read my long post :]

I ran your code several times, and it took about 4 seconds every time to complete on my machine (Core i5 @ 4GHz, 4GB RAM @ 1.6GHz).

So with that said, do you still think that the EA missed the ticks that Open[0] caught and not the other way around? To be honest I still tend to believe that my theory is correct, since it does seem very unlikely that there was a sharp change in price which my EA *didn't* catch, but then the next price in that same second which it *did* catch was exactly 1 pt. above the price it caught before for the previous second. It's harder to believe that there was such a spike in the price, then a few milliseconds later returned to the original price within a margin of 1 pt.

Of course this is still just speculation. To test this I altered my debug code to also output the Time/Bid of several ticks ahead in the Array, so if and when this happens again I'll be able to know if the EA catches these sharp price jumps or not.

I also think it's more likely, because Open[0] is not triggered by incoming ticks. It's trigger is the time of formation of a new bar. So it could be that at the exact millisecond at which Open[0] was triggered, a new tick was already incoming (i.e. "tick in progress"), which the EA caught, and then immediately after there was another tick with the price jump, and that's the one that Open[0] caught (and the EA as well).

What do you think?

Anyway I'll update on the result as soon as I have something! :)

nanquan

 

Okay, I have some updates with regards to this situation! Apparently it's even stranger than I thought!

First of all this happens only when there are disruptions in the data provided by the trading server. i.e. you will have a gap of several minutes with no incoming data, and then the next bar's Open price will suddenly jump drastically, because it's much farther ahead time wise. I contacted my broker about this, and this is caused due to overloads and disruptions on the DEMO server, since all demo accounts are setup on just one server. With LIVE accounts this will never happen since they span across multiple servers etc.

Regardless, this still poses a big question from a technical standpoint:


As you can see, there is a gap in data of approximately 17 minutes, from 15:23 to 15:40. The Open[] value of the bar right after the gap is 1.34146.

Here is the debug information from the TickData array:

2012.02.28 17:45:03     NEXUS-1 EURUSD,M15: Alert:
Index before: 1330442999-1.33978
Bar Open Time/Value: 1330443000-1.34146 <-- Time of 1330443000 is open time of new bar after the price gap, with Open[] value of 1.34146
Index from: 1330443000-1.33980 
1330443001-1.33983
1330443002-1.33987
1330443002-1.33994
1330443003-1.34003
1330443003-1.34000
1330443004-1.34001
1330443005-1.33999 <-- How can it be that 5 seconds later into that bar, the price recorded by EA internal 'TickData' array is 1.33999, when 'Low' value for that WHOLE bar is 1.34132 ?!?!?!?!?!?!?

As you can see, at the time of 1330443000 (new bar open time), Open[] price value is 1.34146.

At that same time, the value captured by internal 'TickData' array for time 1330443000 is 1.33980.

Now, even if EA had missed the "jump" in price that was recorded by Open[] at time of 1330443000, it should have still recorded the correct price right after the one it missed.

In other words, if we look at the attached chart image, we can see that after new bar opened at time of 1330443000, the price never went lower than 1.34132!

And yet, if we look at the data from internal EA 'TickData' array, the values recorded after the time of 1330443000, are still values which are nearer the price of the previous bar before the GAP.

So this makes no sense at all! How can it be that at time of 1330443005 (i.e. 5 whole seconds after the NEW bar Open time), the price recorded by 'TickData' array is 1.33999, when from looking at the chart data, after the time of 1330443000 the price never dipped below 1.34132!!!

Any ideas for a possible explanation? O_o


Thanks,

nanquan

 
nanquan:

Any ideas for a possible explanation?

Not really. I would still trust the terminal more than the EA though, for the reasons previously mentioned. So, what could be wrong with the EA? Well data corruption by invalid pointers would be a good one but that would typically give a wrong value in a particular location, a wildly wrong value, or even a NAN (not a number) when dealing with doubles. No, I've got nothing. Sorry.
 

Thanks for giving it a shot anyway, dabbler! If you think of anything please feel free to reply here:

https://forum.mql4.com/46568

As I've opened a new topic about this question now that I know what's happening!

Reason: