ea work fine for all pairs exept on YEN pairs - page 5

 

I wanted to add something to this conversation, since I recently learned that I was wrong about the use of NormalizeDouble. I originally discovered the error in my ways when user Amrali pointed out some errors in my CDouble library. As it turns out, the typically recommended algorithm for rounding to tick-size using the MathRound function produces errors.

double error_prone_result = tick_size * round(price / tick_size);

This is what amrali pointed out... 

These errors always occur at edge numbers which terminate in 5 (like 1.12345). 

For example CDouble::RoundToStep(1.700605, 0.00001) returns 1.70060, instead of the correct result 1.70061

The equation round(number / point) * point, should be corrected to round(number * power) / power, where both point and power are derived from the number of decimal digits you would like to round to.

Because the value of 1 point which is supposed = 0.00001, is actually encoded as 0.0000100000000000000008180305391403130954586231382563710 as a 64-bits double-precision floating point. This causes the final result from you rounding method, round(number / point) * point,  to drift from the correct result by 1 point (0.00001), very often.

In addition, in order to do a proper 'arithmetic' rounding (Midpoint Rounding away from zero), a good method is to add or subtract a half-epsilon as a correction. (This will offset any half-to-even rounding that has been applied by the processor, as mandated by the IEEE-754 specs, particularly at the midpoint edge cases).

The mql's NormalizeDouble() function handles all those issues correctly, you should use it to do proper 'arithmetic' rounding.

So what that means to everyone in this thread (whether you want to hate NormalizeDouble or not) is that if you are rounding to tick-size then you need to be using NormalizeDouble in your rounding methods. 


double rounded_tick = tick_size * NormalizeDouble(price / tick_size, 0);


PS Don't kill the messenger. 

Reason: