Hello! I believe that this topic has been discussed. Kindly advise where to find the answer.
I would like to convert doubles(price) to integers, work with them, and then convert them back to prices before using them in a OrderSend() / OrderModify() functions.
I used this functions:
and then:
But Still if Ask/Bid prices somtimes are 0.1234000000000001, when I converted to integer it will be 12340, but when I change back to double it will be again 0.1234000000000001
I have tried this approach with coverting the price to string, split the string , and then converted back:
Still not working. Still when change back to double, it will still be 0.123400000000001.
Kindly advise why?
I think that maybe you don't fully understand how floating point numbers are stored. Even if you convert them into Integers for easier manipulation and then later back into floating point, you can not get around the limitations of floating point numbers not being able to store every single number exactly. It is after all a limited discreet binary representation of real world numbers (see next post).
Also, there is no need to use "MathPow(10,_Digits)". Just use "_Point".
int PriceToPoints( double price ) { return (int) round( price / _Point ); }; double PointsToPrice( int points ) { return points * _Point; };
Forum on trading, automated trading systems and testing trading strategies
MathRound fails for one particular number
Fernando Carreiro, 2018.01.01 22:08
He means that the value "0.69" cannot be exactly represented given the way a floating point number works (based on binary and not decimal representation) - hence, why the value gets represented as "0.68999999..." (see below).
You can never really "normalize" it and it is the main reason why both @whroeder1 and myself contest the use of the NormalizeDouble() function. It should in the very least be renamed to something like "RoundDigits()" because it is more of a "rounding" function and does not "normalize" in any way or fashion.
https://www.h-schmidt.net/FloatConverter/IEEE754.html
EDIT: Please note that the above images are for examples of representation in the 4-byte "float", and not the 8-byte "double" which offers more precision but still cannot represent the value "0.69" exactly due to the "binary" nature of the format.
EDIT2: For future readers that have difficulty understanding (or accepting) this concept, of decimal values not having an exact representation with a "float" or a "double", here is an article worth reading:
Also, instead of points, try to use "tick size" instead, as that will make prices always align properly with the symbol's pricing levels.
Forum on trading, automated trading systems and testing trading strategies
Fernando Carreiro, 2022.06.02 01:14
Here are two examples from AMP Global (Europe):
- Micro E-mini S&P 500 (Futures): point size = 0.01, tick size = 0.25, tick value = $1.25
- EURO STOXX Banks (Stock Index): point size = 0.01, tick size = 0.05, tick value = €2.50
Forum on trading, automated trading systems and testing trading strategies
Fernando Carreiro, 2017.09.23 00:41
Just as a side note.
Initially, when I started with MQL, I would manipulate prices as "doubles". Nowadays, especially in the more complex EA's, I manipulate prices as "ints". At the very first opportunity, I convert a price into ticks:
int priceTicks = (int) round( price / tickSize );From then on, all my calculations and manipulations are done with "ints". Not only is it more memory compact and much faster, but comparisons are much easier to handle. Doing a "priceA == priceB" for "doubles" is quite problematic, but not for "ints" because it gives exact matches. Not to mention, that in this way prices, stop sizes, etc. are ALWAYS aligned.
Then, just before I have to place or modify an order, I then convert it back:
priceTicks * tickSizeEDIT: I do the same for volume/lots by using the broker's Lot-Step.
NormalizeDouble((int)(value/tickSize)*tickSize,_Digits);
Samuel Manoel De Souza #: this shall work
NormalizeDouble((int)(value/tickSize)*tickSize,_Digits);
- Type-casting a floating point to an integer will result in truncation which causes an incorrect value to be obtained. For example let say that (value/ticksize) gives a result of 12344.999, which will result in 12344 instead of the correct 12345. So, always use rounding before type-casting, as mentioned in the documentation.
"As a result of converting floating point values to integer type, the fractional part is always deleted. If you want to round off a float to the nearest whole number (which in many cases is more useful), you should use MathRound()."
- There is no need for using "NormalizeDouble" after converting back. The price is already properly aligned in the previous steps. No further rounding or normalisation is required.
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use
Hello! I believe that this topic has been discussed. Kindly advise where to find the answer.
I would like to convert doubles(price) to integers, work with them, and then convert them back to prices before using them in a OrderSend() / OrderModify() functions.
I used this functions:
and then:
But Still if Ask/Bid prices somtimes are 0.1234000000000001, when I converted to integer it will be 12340, but when I change back to double it will be again 0.1234000000000001
I have tried this approach with coverting the price to string, split the string , and then converted back:
Still not working. Still when change back to double, it will still be 0.123400000000001.
Kindly advise why?