Very BIZZARE and ILLOGICAL Array behavior... need help!!!

 

I have a 2 dimensional array: TickData[][4];

With each new change in Bid price (skipping ticks with only Ask price changes) the array's size is incremented by 1 using the 'ArrayResize' function, and it's dimensions are populated with the following data:

      TickData[arIndex][0] = MarketInfo(Symbol(),MODE_TIME); // Tick Time
      TickData[arIndex][1] = Bid; // Bid Price
      TickData[arIndex][2] = Ask; // Ask Price
      TickData[arIndex][3] = Volume; // Volume

So far so good.

Now, I built a simple search function which receives Time as input, and searches 'TickData' array for entry with identical time signature, and returns it's index.

There is also a possibility that no EXACT match will be found. In such a case, the first time signature that comes AFTER the searched one is found, and its index is the one returned.

Here is my function:

int IndexByTime(int time=0) {
   // for new bar open time, the first tick that equals or is greater than bar open time
   if (time<1000000000) return(-1); // only accept timestamps as input
   int arSize = ArrayRange(TickData,0);
   // start search from last (most recent) to first, as it's more likely the index will be closer
   // to the last position than the first, thereby saving time.
   bool found = false;
   for(int i=arSize-1;i>=0;i--) {
      // exact match
      if (TickData[i][0]==time) {found = true; break;}
      // if not then first that's greater
      if (TickData[i][0]<time) {found = true; i++; break;}
   }
   if (found==false) return(-1); // not found
   return(i);
}

PROBLEM: As soon an the search function does not have an EXACT match, triggering the second condition,

if (TickData[i][0]<time) {found = true; i++; break;}

if I add this code:

Alert(TickData[i++][0]);

It will return 0!!!

If I add this code:

Alert(TickData[i][0]);

It will return the time signature stored inside that Array entry.

THIS MAKES NO SENSE AT ALL!!! How can the entry which comes AFTER the entry at index 'i' be equal to ZERO?!?!?!

I could understand if it was the entry BEFORE, because then it could be that index 'i' equals to 0, and so there is no data before Array index 0, but I'm calling for the value AFTER.

Please help, as I am frustrated as hell and have exhausted all possibilities! :(

Thanks!

nanquan

 

I also added a separate search function which also searches the TickData array and looks for any entries with ZERO values, in case for some reason TickData array did not update correctly.

It found NO SUCH VALUES. i.e. all Array entries are populated.

So this is a LOGICAL CONTRADICTION!

How can one function say that a certain entry equals to ZERO, while another says that there are NO ENTRIES AT ALL that are equal to zero??? o_O

 
I'm not sure if this is relevant to your problem but it would appear that the first run in the i loop has i as arSize-1, the maximum limit of the array. Then if the <time test succeeds you go i++ and exceed the length of the array.
 
nanquan:


Please help, as I am frustrated as hell and have exhausted all possibilities! :(

Thanks!

nanquan

How have you defined your array ? TickData[][4]; you may need to do TickData[x][4]; x = size of array first dimension
 
RaptorUK:
How have you defined your array ? TickData[][4]; you may need to do TickData[x][4]; x = size of array first dimension
I don't tend to do it myself, but the OP mentioned that he uses ArrayResize every tick. Therefore he can start from a null pointer, defined as he said, and keep reallocating it (which is computationally gruesome, but will work)
 
dabbler:
I don't tend to do it myself, but the OP mentioned that he uses ArrayResize every tick. Therefore he can start from a null pointer, defined as he said, and keep reallocating it (which is computationally gruesome, but will work)
Ah . . missed that.
 

But he didn't post that code so that's probably where the problem is.

in IndexByTime() you use arSize but you didn't post that code

No mind readers here - post ALL the code.

Why are you passing an int to IndexByTime, you want to pass a datetime.

why are you testing the time (Sun, 09 Sep 2001 01:46:40 GMT.) Lower values are still valid.

if (time<1000000000
 
WHRoeder:


Why are you passing an int to IndexByTime, you want to pass a datetime.

Yes, but let's face it, he is also storing the datetime as a double in the TickData array.
 
dabbler:
I'm not sure if this is relevant to your problem but it would appear that the first run in the i loop has i as arSize-1, the maximum limit of the array. Then if the <time test succeeds you go i++ and exceed the length of the array.

Yes, you are correct! I didn't account for that possibility, so when I did my test now I added a check to see if 'i' was equal to 'arSize-1' when this problem was occurring and it was, so i++ did indeed go out of the Array range! Thanks for that!

dabbler:
I don't tend to do it myself, but the OP mentioned that he uses ArrayResize every tick. Therefore he can start from a null pointer, defined as he said, and keep reallocating it (which is computationally gruesome, but will work)

In what way is my method 'computationally gruesome' ? My logic was that the 'TickData' array is ever changing and constantly updates with every new tick. As a result it's impossible to define in advance how big it will be, and so I implemented this method to dynamically increment it's size by 1 with every new tick. Is there a downside to doing it like this? Do you have a better suggestion?

dabbler:
Yes, but let's face it, he is also storing the datetime as a double in the TickData array.

Is there a problem with doing it this way? As I understood it datetime is basically an integer 10 digits long. So if you type cast it to int or double type values, it would still retain the same value for any comparison calculations you wish to do.

Example:

datetime current = Time;
int value1 = current;
double value2 = current;

if (value1==value2) Alert("They are computationally equal!");

The reason I save datetime value as a double is because I wanted to have one Array containing all the values which are important to me, instead of having to split different data types over several different arrays, and then juggling between them when doing any sort of calculations. The end result is the same, and my way is simpler. Unless I'm missing something and there are downsides to doing it this way?


Thanks Again!!!

nanquan

 
nanquan:
several different arrays, and then juggling between them when doing any sort of calculations. The end result is the same, and my way is simpler. Unless I'm missing something and there are downsides to doing it this way?

datetime and int are equivalent (syntax only,) double is not. Mql4 is a 32 bit application. Ints are 32 bits. If doubles are also 32 bits (normally called float) the total digits it can store is 7 decimal digits

1000000000 = Sun, 09 Sep 2001 01:46:40 GMT and 1000001000=Sun, 09 Sep 2001 02:03:20 GMT The accuracy of your timestamps is about 17 minutes. Periods smaller than that will compare equal.

 
WHRoeder:

datetime and int are equivalent, double is not. mql4 is a 32 bit application. ints are 32 bits. if doubles are also 32 bits (normally called float) the total digits it can store is 7 decimal digits

1000000000 = Sun, 09 Sep 2001 01:46:40 GMT and 1000001000=Sun, 09 Sep 2001 02:03:20 GMT The accuracy of your timestamps is about 17 minutes.


I'm a bit confused! Are you saying that double type variables can only store whole numbers that are no bigger than 7 digits?

If I do this:

int number=1000000000;
double number2=number;

Alert(number2);
// ...the result is: 1000000000

So even if you assign a whole number of int or datetime type to a double type variable, that number still retains it's value in logical computations:

if (number==number2) Alert("True!");
// result: "True!"

So I don't get it... :\

It seems that what you're saying is with regards to floating point values, i.e. if double type variable value was this: 0.1000000000, then it would only be accurate up to the 7th digit after the decimal point (i.e. 0.1000000).

But since I am using whole numbers, how is this relevant to my calculations?? Am I missing something here?

Reason: