does the platform round numbers or truncate them?

 
Not sure if this is the right place for this, I'm scripting an EA with multiple calculations and  I notice a lot of discrepancies between my manual calculations and the figure MT5 returns (in history, trades, etc). I'm wondering if the scripts truncate numbers at every calculation, round them at every calculation, or do all the calculations and return a rounded number?
 
rhooman23: Not sure if this is the right place for this, I'm scripting an EA with multiple calculations and  I notice a lot of discrepancies between my manual calculations and the figure MT5 returns (in history, trades, etc). I'm wondering if the scripts truncate numbers at every calculation, round them at every calculation, or do all the calculations and return a rounded number?

The answer is "none of the above"!

You need to first learn how floating point numbers are stored and manipulated. You also need to learn about how integer division can affect your calculations.

If you use the function NormalizeDouble, you need to be wary of how it actually works, and most of the time it is actually prejudicial and should NOT be used.

 

Also, please read the following ... MQL5 manual: Programming fundamentals / Built-in data types / Floating-point numbers

Forum on trading, automated trading systems and testing trading strategies

why is 1.85 is round up to 1.9 and 1.95 is round down to 1.9 ?

Fernando Carreiro, 2023.09.27 21:27

Because the exact values 1.85 and 1.95 cannot be represented in double floating point precision, because it is binary and not decimal.

It will become:

  • 1.8500000000000000888178419700125232338905334472656250
  • 1.9499999999999999555910790149937383830547332763671875

So, from the above two values, can you see why one will round up and the other will round down to 1.9?

Indecently 1.9 is actually expressed as 1.899999999999999911182158029987476766109466552734375

For reference: https://www.exploringbinary.com/floating-point-converter/

Forum on trading, automated trading systems and testing trading strategies

why return many decimal ?? also after normalize double?

Fernando Carreiro, 2023.09.11 13:43

It is not an exclusive MQL problem. It is the same for ALL programming languages that use floating point.

You can see that by the links I provided and I quote from one of them ...

"The questions came from the context of a variety languages: Java, C++, C#, Python, Javascript, awk, Perl, Objective-C, and PHP. "

Forum on trading, automated trading systems and testing trading strategies

Do I have to NormalizeDouble Everything ?

Fernando Carreiro, 2023.07.05 06:20

As already explained, floating point numbers are represented in binary form, not in decimal form. It is impossible to limit the number of "decimal" digits internally.

All you can do is approximate it, which is what NormaliseDouble already does, but you can never get to an exact decimal place because it is binary, not decimal.

Forum on trading, automated trading systems and testing trading strategies

Implicit or explicit decimals

Fernando Carreiro, 2023.08.13 22:11

Answering questions as one — all the "double" numbers are floating point and have no fixed number of decimal digits.

You will have to learn this by following the links and researching how binary floating point numbers work.

If you don't learn this, then you will always be handicapped in your coding.

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:

Why 0.1 Does Not Exist In Floating-Point

Many new programmers become aware of binary floating-point after seeing their programs give odd results: “Why does my program print 0.10000000000000001 when I enter 0.1?”; “Why does 0.3 + 0.6 = 0.89999999999999991?”; “Why does 6 * 0.1 not equal 0.6?” Questions like these are asked every day, on online forums like stackoverflow.com.

The answer is that most decimals have infinite representations in binary. Take 0.1 for example. It’s one of the simplest decimals you can think of, and yet it looks so complicated in binary:


Decimal 0.1 In Binary ( To 1369 Places

The bits go on forever; no matter how many of those bits you store in a computer, you will never end up with the binary equivalent of decimal 0.1.

... Read the rest of the article at: http://www.exploringbinary.com/why-0-point-1-does-not-exist-in-floating-point/

 

Also read about integer division ...

Forum on trading, automated trading systems and testing trading strategies

Rare code issue

Fernando Carreiro, 2021.07.23 22:20

Please understand that dividing by 100 or dividing by 100.0 will give totally different results.

In the former, 100 is considered an Integer literal constant and so it will carry out integer division which will truncate the decimal values.

In the latter, 100.0 will be considered a floating-point literal constant and it will carry out floating-point division which will keep the decimal values.

This is the principal behind the problems you are having. So, to prevent this, either use a floating-point literal constant or typecast the variable into a (double).

Example:

Print( "90   / 100   = ", 90   / 100   );
Print( "90   / 100.0 = ", 90   / 100.0 );
Print( "90.0 / 100   = ", 90.0 / 100   );
Print( "90.0 / 100.0 = ", 90.0 / 100.0 );
2021.07.23 21:26:57.060 TestCopy EURUSD,H1: 90   / 100   = 0
2021.07.23 21:26:57.060 TestCopy EURUSD,H1: 90   / 100.0 = 0.9
2021.07.23 21:26:57.060 TestCopy EURUSD,H1: 90.0 / 100   = 0.9
2021.07.23 21:26:57.060 TestCopy EURUSD,H1: 90.0 / 100.0 = 0.9

Forum on trading, automated trading systems and testing trading strategies

MT4 forcing doubles into int

Fernando Carreiro, 2022.03.23 17:53

Typecast them into floating point — Typecasting - Data Types - Language Basics - MQL4 Reference

double Average = (double) Bars /          Found;
double Average =          Bars / (double) Found;
double Average = (double) Bars / (double) Found;
 

Also learn about how quote prices should be aligned to the tick size and not use NormalizeDouble for this ...

Forum on trading, automated trading systems and testing trading strategies

Symbol Point Value

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

Symbol Point Value

Fernando Carreiro, 2022.05.18 21:05

double
   dbTickSize   = SymbolInfoDouble( _Symbol, SYMBOL_TRADE_TICK_SIZE  ), // Tick size
   dbTickValue  = SymbolInfoDouble( _Symbol, SYMBOL_TRADE_TICK_VALUE ), // Tick value
   dbPointSize  = SymbolInfoDouble( _Symbol, SYMBOL_POINT ),            // Point size
   dbPointValue = dbTickValue * dbPointSize / dbTickSize;               // Point value

Remember, it's best to use tick size and tick value in your calculations, instead of point size and its value.

Forum on trading, automated trading systems and testing trading strategies

Tick size vs Point(), can be a little tricky in Multicurrency EA

Fernando Carreiro, 2022.03.09 12:11

Tick Size and Point Size can be very different especially on stocks and other symbols besides forex.

Always use Tick Size to adjust and align your prices, not the point size. In essence, make sure that your price quotes, are properly aligned to the Tick size (see following examples).

...
double tickSize = SymbolInfoDouble( _Symbol, SYMBOL_TRADE_TICK_SIZE );
...
double normalised_price = round( price / tick_size ) * tick_size;
...
// Or use a function
double Round2Ticksize( double price )
{
   double tick_size = SymbolInfoDouble( _Symbol, SYMBOL_TRADE_TICK_SIZE );
   return( round( price / tick_size ) * tick_size );
};