NormalizeDouble not "working"

 

Hi this is my first post in this incredible forum and today I need help with something that I believe is rather simple but is turning a pain in the a**.

So my problem is that the function NormalizeDouble(value,digits)=  [value: a certain price, and digits= _Digits]   is returning me numbers that violate the round-up i am trying to obtain

E.G. sometimes the function will return a value EURUSD 1.20205 other times it will return 1.1954400000001 and others 1.1954(i guess this one last is because 0 isn't counted after the 4).


Does anyone know how to fix this error because the expert advisor I am develpoing works fine except that when it has to send a pending order (I have set it to not send more than one for the same price e.g. there can not be two pending orders at EURUSD 1.19955) but the problem that it does and when i check ti tells me that a pendning was sent at EURUSD 1.19544 and another one at 1.1954400000001 which is rounded by the terminal to 1.19544 and therefore i have two pending which is exactly what i do not want.

PS: Thanks a lot for the help in advance and please excuse my English(not my mother tongue :) )

 
AWer1001:

Hi this is my first post in this incredible forum and today I need help with something that I believe is rather simple but is turning a pain in the a**.

So my problem is that the function NormalizeDouble(value,digits)=  [value: a certain price, and digits= _Digits]   is returning me numbers that violate the round-up i am trying to obtain

E.G. sometimes the function will return a value EURUSD 1.20205 other times it will return 1.1954400000001 and others 1.1954(i guess this one last is because 0 isn't counted after the 4).


Does anyone know how to fix this error because the expert advisor I am develpoing works fine except that when it has to send a pending order (I have set it to not send more than one for the same price e.g. there can not be two pending orders at EURUSD 1.19955) but the problem that it does and when i check ti tells me that a pendning was sent at EURUSD 1.19544 and another one at 1.1954400000001 which is rounded by the terminal to 1.19544 and therefore i have two pending which is exactly what i do not want.

PS: Thanks a lot for the help in advance and please excuse my English(not my mother tongue :) )


This thread will answer your question

https://www.mql5.com/en/forum/136997

How to compare doubles ?
How to compare doubles ?
  • 2014.06.10
  • www.mql5.com
To compare 1.36 with 1.36 i need to use if(CompareDoubles(x , y)){ // the same } But how to compare like this ? if ( 1.36 >= 1.36 ){...
 
AWer1001: EURUSD 1.20205 other times it will return 1.1954400000001
  1. Floating point has infinite number of decimals, it's your not understanding floating point and that some numbers can't be represented exactly. (like 1/10.)
              Double-precision floating-point format - Wikipedia, the free encyclopedia
  2. Print out your values to the precision you want. Do NOT use NormalizeDouble, EVER. For ANY Reason. It's a kludge, don't use it. It's use is always wrong
 

Thanks a lot for the links I will check them meanwhile this is the eror i get:


ERROR


So how can i fix it once and for all I will read the articles above but maybe you can tell me.


Thanks in advance

 
AWer1001:

Thanks a lot for the links I will check them meanwhile this is the eror i get:




So how can i fix it once and for all I will read the articles above but maybe you can tell me.


Thanks in advance


If you do not care about the why, but only quick fix, try https://www.mql5.com/en/job/new 

 

I do care please do not understand me wrong I did fix somehow the error before the three numbers where all like the first so i read the articles and stuff and solved it partially but i still have that error with the price


---

Thanks a lot for the help I was able to solve it with your help and a friend who just spotted that i wasnt saving _Digits for price and this  Double-precision floating-point format - Wikipedia, the free encyclopedia helped a lot. You can erase this post if you will again thanks for all help Enrique Dangeroux and
whroeder1

 
AWer1001: I do care please do not understand me wrong I did fix somehow the error before the three numbers where all like the first so i read the articles and stuff and solved it partially but i still have that error with the price

In short, NormalizeDouble() does nothing useful at all, and what does solve the problem is making sure the price is a aligned to the symbol's tick size.

For example, if the tick size is 0.00025 then all prices must be multiples of that, so a price like 1.34035 would be invalid, and the only valid prices closest to that would either be 1.34050 or 1.34025, with the later being the closest/better choice (rounding).

double normalised_price = round( price / tick_size ) * tick_size;
 
Fernando Carreiro:

In short, NormalizeDouble() does nothing useful at all, and what does solve the problem is making sure the price is a aligned to the symbol's tick size.

For example, if the tick size is 0.00025 then all prices must be multiples of that, so a price like 1.34035 would be invalid, and the only valid prices closest to that would either be 1.34050 or 1.34025, with the later being the closest/better choice (rounding).

Agree, but for most symbols, tick size is a multiple of 0.00001, and normalizing it to symbol's digits will work fine.
 
Mohammad Hossein Sadeghi:
Agree, but for most symbols, tick size is a multiple of 0.00001, and normalizing it to symbol's digits will work fine.
"just fine" still does note make it correct. Doing it properly as above guarantees it will work for ALL symbols and not just some.

Take pride in your coding and do it properly!
 
Fernando Carreiro:
"just fine" still does note make it correct. Doing it properly as above guarantees it will work for ALL symbols and not just some.

Take pride in your coding and do it properly!
Thanks for advice, I'll take it and thank you for sharing.
 
double NormPrice(double price)
{
   double tickSize=MarketInfo(Symbol(),MODE_TICKSIZE);
   price=NormalizeDouble(MathRound(price/tickSize)*tickSize,Digits);
   return price;
}