Download MetaTrader 5

expert advisor - miscellaneous questions - page 3

To add comments, please log in or register
Track all payments in your profile. It is easy!
honest_knave
Moderator
2192
honest_knave 2016.11.29 00:34  
double LotCalculator(double lots)
  {
   double minlot  = SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MIN),
          maxlot  = SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MAX),
          lotstep = SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_STEP);
   lots = MathFloor(lots/lotstep)*lotstep;
   lots = MathMax(lots,minlot);
   lots = MathMin(lots,maxlot);
   return(NormalizeDouble(lots,2));
  }
Max Enrik
815
Max Enrik 2016.11.29 00:37  
honest_knave:
double LotCalculator(double lots){}

Much appreciate.

I just want to start write that code :)

You saved my more times.

 

Big thanks! 

Max Enrik
815
Max Enrik 2016.11.29 01:50  
I got same message for Lot Size.
I call 'LotCalculator()' in 'OnChartEvent()' so is that not right?
Max Enrik
815
Max Enrik 2016.11.29 04:27  

I am looking for good forum for 'MarketInfo & LotSize' computation.
Who know that type of good forum please share with me. 

Thanks. 

honest_knave
Moderator
2192
honest_knave 2016.11.29 08:31  
Did you by any chance use my code snippet before I edited the last line (NormalizeDouble)? I see there was only 3 minutes from my post until yours, and I edited it almost immediately.
whroeder1
14480
whroeder1 2016.11.29 16:28  
Max Enrik: I am using NormalizeDouble for my EA's. But I worry about 'NormalizeDouble' message, but I see lot size on chart like this: 0.07

So, I need good advice, please.

02:00:00.069 - custom expert EURUSD,H1: | _lotSize - NormalizeDouble: 0.07000000000000001
02:00:00.069 - custom expert EURUSD,H1: | _lotSize - DoubleToString : 0.07
  1. NormalizeDouble returns a double. 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 See also The == operand. - MQL4 forum
  2. Do NOT use NormalizeDouble, EVER. For ANY Reason. It's a kludge, don't use it. It's use is always wrong
honest_knave
Moderator
2192
honest_knave 2016.11.29 18:11  
whroeder1:
  1. Do NOT use NormalizeDouble, EVER. For ANY Reason. It's a kludge, don't use it. It's use is always wrong

I believe you do still need NormalizeDouble().

Here is an example, using your code snippet (same applies to my example using MathFloor):

double NormalizeLots(double lots, string pair=""){
    if (pair == "") pair = Symbol();
    double  lotStep     = MarketInfo(pair, MODE_LOTSTEP),
            minLot      = MarketInfo(pair, MODE_MINLOT);
    lots                = MathRound(lots/lotStep) * lotStep;
    if (lots < minLot) lots = 0;    // or minLot
    return(lots);
}

 Called: 

Print(NormalizeLots(2/3.0));

 Result:

0.7000000000000001

Now code adjusted:

double NormalizeLots(double lots, string pair=""){
    if (pair == "") pair = Symbol();
    double  lotStep     = MarketInfo(pair, MODE_LOTSTEP),
            minLot      = MarketInfo(pair, MODE_MINLOT);
    lots            = MathRound(lots/lotStep) * lotStep;
    if (lots < minLot) lots = 0;    // or minLot
    return(NormalizeDouble(lots,2));
}

Result:

0.7


 

whroeder1
14480
whroeder1 2016.11.29 18:55  

 Result: 0.7000000000000001

What part of "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" was unclear?

NormalizeDouble(0.7, 2) will produce the same exact result (or possibily 0.699999999999999.)

honest_knave
Moderator
2192
honest_knave 2016.11.29 19:02  
whroeder1:

What part of "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" was unclear?

NormalizeDouble(0.7, 2) will produce the same exact result (or possibily 0.699999999999999.)

I am not saying NormalizeDouble() is required for a valid OrderSend. That is why my first code snippet excluded it. Nor am I unclear about the manner in which floating point numbers are represented.

I edited the snippet to include it because I felt it better addressed my understanding of the OP's issue (essentially a display issue, which can be resolved either by using NormalizeDouble() in the "lot normalizer" code, or by using printf or DoubleToStr when the value needs to be displayed).

Maybe I have misunderstood the OP.

02:00:00.069 - custom expert EURUSD,H1: | _lotSize - NormalizeDouble: 0.07000000000000001
02:00:00.069 - custom expert EURUSD,H1: | _lotSize - DoubleToString : 0.07

(edited to remove unnecessary terseness) 

Marco vd Heijden
Moderator
4685
Marco vd Heijden 2016.11.29 21:15  
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//--- get minimum stop level
   double minstoplevel=MarketInfo(Symbol(),MODE_STOPLEVEL);
   Print("Minimum Stop Level=",minstoplevel," points");
   double price=Ask;
//--- calculated SL and TP prices must be normalized
   double stoploss=NormalizeDouble(Bid-minstoplevel*Point,Digits);
   double takeprofit=NormalizeDouble(Bid+minstoplevel*Point,Digits);
//--- place market order to buy 1 lot
   int ticket=OrderSend(Symbol(),OP_BUY,1,price,3,stoploss,takeprofit,"My order",16384,0,clrGreen);
   if(ticket<0)
     {
      Print("OrderSend failed with error #",GetLastError());
     }
   else
      Print("OrderSend placed successfully");
//---
  }

This might be confusing to people because the MQL4 documentation uses NormalizeDouble() function in most of the examples.

It even goes as far as warning that unnormalized price can not be applied:

Note

At opening of a market order (OP_SELL or OP_BUY), only the latest prices of Bid (for selling) or Ask (for buying) can be used as open price. If operation is performed with a security differing from the current one, the MarketInfo() function must be used with MODE_BID or MODE_ASK parameter for the latest quotes for this security to be obtained.

Calculated or unnormalized price cannot be applied. If there has not been the requested open price in the price thread or it has not been normalized according to the amount of digits after decimal point, the error 129 (ERR_INVALID_PRICE) will be generated. If the requested open price is fully out of date, the error 138 (ERR_REQUOTE) will be generated independently on the slippage parameter. If the requested price is out of date, but present in the thread, the order will be opened at the current price and only if the current price lies within the range of price+-slippage.

 

And even in some of the better books on MQL they use it quite heavily.

It might depends on it's application a display issue is less dramatic then order or modification failures.

Personally i always upconvert to whole integer values so i rarely deal with it.

12345678910...36
To add comments, please log in or register