problems with metaeditor getting wrong double numbers

 

Hi to all guys , I am new here,

recently while i was trying to code en EA and I noted that almost in any cases when i read values with a sample call  like :

double VolumeStep = MarketInfo(symbol, SYMBOL_VOLUME_STEP); or 

double MinVolume = MarketInfo(symbol, SYMBOL_VOLUME_MIN);

I get a strange value : 0.100000000000000006 instead of 0.01 as i expected

i tried to remove the last char with code like :   VS1 = NormalizeDouble(VolumeStep , 2);  but i still get the same value  0.100000000000000006

also tried to convert tostring with  :

string VS = DoubleToString( VS1  , 2 ); and i get "0.01" then 

VolumeStep = StringToDouble( VS);  and get the same value =  0.100000000000000006


there is someone that can help me to get rid of this problem ?  could it be my machine or the compiler or what else.

I have the last version of metaeditor installed  ( version 5 build 3640 ) 17-03-2023

thanks to all in advance

PS : I read some post about a similar problem but i didn't read any valid solution that solve this strange behaviour.


Documentation on MQL5: Constants, Enumerations and Structures / Environment State / Symbol Properties
Documentation on MQL5: Constants, Enumerations and Structures / Environment State / Symbol Properties
  • www.mql5.com
Symbol Properties - Environment State - Constants, Enumerations and Structures - MQL5 Reference - Reference on algorithmic/automated trading language for MetaTrader 5
 
jossnet: I get a strange value : 0.100000000000000006 instead of 0.01 as i expected

Floating-point has an infinite number of decimals, it's you, not understanding floating-point and that some numbers can't be represented exactly. (like 1/10.)
          Double-precision floating-point format - Wikipedia

See also The == operand. - MQL4 programming forum (2013)

If you want to see the correct number of digits, convert it to a string with the correct/wanted accuracy.
          question about decima of marketinfo() - MQL4 programming forum (2016)

 

Hi William , Tanks for reply.

I don't know if i made something wrong. could be, and that's why i asked your help.

as i said i just made the istruction you suggested , specfically :

string VS = DoubleToString( VS1  , 2 ); and i get "0.01" then 

VolumeStep = StringToDouble( VS);  and get the same value =  0.100000000000000006

but the strange thing is why when I made the istruction 

VS1 = NormalizeDouble(VolumeStep , 2);  after this i still get the same value  0.100000000000000006  ... it's seem that this instruction is ignored 

So at the end if this instruction seem to be ignored how can I check a value returned by  VS1 = NormalizeDouble(VolumeStep , 2);  with a constant like 

if ( VS1 == 0.01 )    .... this turn out is allways false ... isn't it ?


please , dont get me worng,  i talked about strange  behaviour not about someone fault. Im seeking help and appreciate the time you spend assisting us. but i have also about 20 years of programming on my shoulders and i know pretty well what is a double value.

if could be usefull i  currently program in two other envireonment  ( Net.core vith visual code C# language  and  codeblock CPP language. )  and neither of two present similar  behaviour.

thank you if I can count on your help.





 
jossnet #: as i said i just made the istruction you suggested , specfically :

string VS = DoubleToString( VS1  , 2 ); and i get "0.01"”then 

VolumeStep = StringToDouble( VS);  and get the same value =  0.100000000000000006

  1. Of course, you do. VS1 is your VolumeStep
  2. I made no such suggestion. I said, “If you want to see the correct number of digits.”
 
jossnet:

Hi to all guys , I am new here,

recently while i was trying to code en EA and I noted that almost in any cases when i read values with a sample call  like :

double VolumeStep = MarketInfo(symbol, SYMBOL_VOLUME_STEP); or 

double MinVolume = MarketInfo(symbol, SYMBOL_VOLUME_MIN);

I get a strange value : 0.100000000000000006 instead of 0.01 as i expected


See this thread:

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

Actually, the debugger window displays the longest round-trip string, while, Print() and input dialog boxes display the shortest round-trip string. Both are accurate, but the longest-round trip form is confusing and not intuitive.


Bug in MetaEditor Build 3566: Wrong display of double floating point numbers in the debugger window - Double floating point numbers in Dialog boxes and output of FileWrite Functions.
Bug in MetaEditor Build 3566: Wrong display of double floating point numbers in the debugger window - Double floating point numbers in Dialog boxes and output of FileWrite Functions.
  • 2023.01.26
  • www.mql5.com
Wrong display of double floating point numbers in dialog boxes and output of print(), alert(), comment() and filewrite() functions. 9524200000000002 then this means an error, because this string round-trips to the binary   0x3fee7a398201cd61 , which is a different representable fp number
 

Hi  amrali,

I read your post  https://www.mql5.com/en/forum/440534  and i have to say "in a word"  excellent.  this is exactly the problem that I faced.

But also I think that, at least for me ,  it's not a cosmetic quetion  becasue if you see this number in debugger  it signifies that if you apply an arithmetic  operation to this kind of number the digits count to the result.

so , as you said, in other languages that I use ( C# / Cpp ) and relative degugger this problem is not found.

what is still confusing me is that when i apply a function like   NormalizeDouble(VolumeStep , 2);  it seems that nothinig happens to the result. That's not good form me.


now : what is the next step ?  I wold like to finish my EA for my daughter  if any one has some suggestion is appreciate.


amrali
amrali
  • 2023.01.26
  • www.mql5.com
Trader's profile
 
jossnet #: when i apply a function like   NormalizeDouble(VolumeStep , 2);  it seems that nothinig

You used NormalizeDouble, It's use is usually wrong, as it is in your case.

  1. Floating point has an infinite number of decimals, it's you were 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

    See also The == operand. - MQL4 programming forum (2013)

  2. Print out your values to the precision you want with DoubleToString - Conversion Functions - MQL4 Reference.

  3. SL/TP (stops) need to be normalized to tick size (not Point) — code fails on non-currencies.
              On 5Digit Broker Stops are only allowed to be placed on full pip values. How to find out in mql? - MQL4 programming forum (2011)

    And abide by the limits Requirements and Limitations in Making Trades - Appendixes - MQL4 Tutorial and that requires understanding floating point equality Can price != price ? - MQL4 programming forum (2012)

  4. Open price for pending orders need to be adjusted. On Currencies, Point == TickSize, so you will get the same answer, but it won't work on non-currencies. So do it right.
              Trailing Bar Entry EA - MQL4 programming forum (2013)
              Bid/Ask: (No Need) to use NormalizeDouble in OrderSend - MQL4 programming forum (2012)

  5. Lot size must also be adjusted to a multiple of LotStep and check against min and max. If that is not a power of 1/10 then NormalizeDouble is wrong. Do it right.
              (MT4 2013)) (MT5 2022))

  6. MathRound() and NormalizeDouble() are rounding in a different way. Make it explicit.
              MT4:NormalizeDouble - MQL5 programming forum (2017)
              How to Normalize - Expert Advisors and Automated Trading - MQL5 programming forum (2017)

  7. Prices you get from the terminal are already correct (normalized).

  8. PIP, Point, or Tick are all different in general.
              What is a TICK? - MQL4 programming forum (2014)

 
jossnet #:

Hi  amrali,

I read your post  https://www.mql5.com/en/forum/440534  and i have to say "in a word"  excellent.  this is exactly the problem that I faced.

But also I think that, at least for me ,  it's not a cosmetic quetion  becasue if you see this number in debugger  it signifies that if you apply an arithmetic  operation to this kind of number the digits count to the result.

so , as you said, in other languages that I use ( C# / Cpp ) and relative degugger this problem is not found.

what is still confusing me is that when i apply a function like   NormalizeDouble(VolumeStep , 2);  it seems that nothinig happens to the result. That's not good form me.


now : what is the next step ?  I wold like to finish my EA for my daughter  if any one has some suggestion is appreciate.


double VolumeStep = MarketInfo(symbol, SYMBOL_VOLUME_STEP);

Do not round the volume step, it is already rounded. 

To round the lot volume to the symbol's volume step, use:

   // the value of calculated lots
   double lots = xxxxx;  
   
   // round down to symbo's volume step
   double VolumeStep = MarketInfo(symbol, SYMBOL_VOLUME_STEP);
   lots = MathFloor(lots / VolumeStep) * VolumeStep;
 

Hi Guys,

@William : thanks for remind me all this points about normlaization. something i already knew ,but is allways correct to be aware of.
@amrlai  : also thank to you for the correct way of rounding.

a question ? . So you all are saying that even though a value that has been normalized and/or round  ( suppose lots ) has  number of digits like 4.6000000000000005 it doesn't matter when you put an order setting these value 
TradeRequest.volume , TradeRequest.price, TradeRequest.sl,  TradeRequest.tp with numer of digit thats seems wrong in the debugger ?

thank a lot guys 

 
Hi Guys ,

I tried to finish the EA  and I start to test it in account demo. when I launched the EA i get these messages :

2023.03.24 09:27:46.653 Trades '1390720': accepted market sell 78.1 XAUUSD sl: 1988.35 tp: 1928.69
2023.03.24 09:27:46.654 Trades '1390720': market sell 78.1 XAUUSD sl: 1988.35 tp: 1928.69 placed for execution
2023.03.24 09:27:46.749 Trades '1390720': order #237249292 sell 78.1 / 78.1 XAUUSD at market done in 230.905 ms
2023.03.24 09:27:46.750 Trades '1390720': deal #210746204 sell 78.1 XAUUSD at 1986.77 done (based on order #237249292)
2023.03.24 09:27:51.151 Trades '1390720': failed modify #237249292 sell 78.1 XAUUSD sl: 1988.35, tp: 1928.69 -> sl: 1986.27, tp: 1928.69 [Invalid stops]

2023.03.24 09:29:16.461 Trades '1390720': failed market sell 74.1 XAUUSD sl: 1988.35 tp: 1928.69 [No money]

I am not able to read these numbers :   sell 78.1 XAUUSD sl: 1988.35, tp: 1928.69 - 986.27, tp: 1928.69 [Invalid stops]   ...what's does it mean ?

I mean comparing the sl: 1988.35 against   sl: 1986.27  why they are [invalid stops]  ??

could someone give me a sight and point me in the right direction ? 

this is a code snippet  for symbol = "AUXUSD"

int data = CopyRates(symbol, PERIOD_M5, 0, 2, rates);
..
double lastLow = rates[1].low;          // prices
double lastHigh = rates[1].high;        // prices
..
 entryPrice = rates[1].high;
 Ask = SymbolInfoDouble(symbol, SYMBOL_ASK);
..
stopLoss = lastHigh + SymbolInfoDouble(symbol, SYMBOL_TRADE_TICK_SIZE);

..
   for (int i = PositionsTotal() - 1; i >= 0; i--) 
   {
      ulong ticket = PositionGetTicket(i);
      if (PositionGetString(POSITION_SYMBOL) == symbol) 
      {
         double currentPositionStopLoss = PositionGetDouble(POSITION_SL);
         double newPositionStopLoss;
         
         if (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) 
         {
            newPositionStopLoss = PositionGetDouble(POSITION_PRICE_OPEN) + trailingStop * _Point;
            if (newPositionStopLoss > currentPositionStopLoss) {
               trade.PositionModify(ticket, newPositionStopLoss, PositionGetDouble(POSITION_TP));
            }
         } else {
            newPositionStopLoss = PositionGetDouble(POSITION_PRICE_OPEN) - trailingStop * _Point;
            if (newPositionStopLoss < currentPositionStopLoss) {
               trade.PositionModify(ticket, newPositionStopLoss, PositionGetDouble(POSITION_TP));
            }
         }
      }
   }





thanks to all 

Reason: