How do you solve the problem of invalid volume?

 

Hi, everyone,

I am developing expert advisor.

But there is an "invalid volume" problem in my coding.

Below is the method I learn and think at mql5 articles.


//+------------------------------------------------------------------+
//| Check the correctness of the order volume                        |
//+------------------------------------------------------------------+
bool CheckVolumeValue(double volume,string &description)
  {
//--- minimal allowed volume for trade operations
   double min_volume=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MIN);
   if(volume<min_volume)
     {
      description=StringFormat("Volume is less than the minimal allowed SYMBOL_VOLUME_MIN=%.2f",min_volume);
      return(false);
     }

//--- maximal allowed volume of trade operations
   double max_volume=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MAX);
   if(volume>max_volume)
     {
      description=StringFormat("Volume is greater than the maximal allowed SYMBOL_VOLUME_MAX=%.2f",max_volume);
      return(false);
     }

//--- get minimal step of volume changing
   double volume_step=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_STEP);

   int ratio=(int)MathRound(volume/volume_step);
   if(MathAbs(ratio*volume_step-volume)>0.0000001)
     {
      description=StringFormat("Volume is not a multiple of the minimal step SYMBOL_VOLUME_STEP=%.2f, the closest correct volume is %.2f",
                               volume_step,ratio*volume_step);
      return(false);
     }
   description="Correct volume value";
   return(true);
  }


I am going to put above code into "on Init" function of my expert advisor.

Lot size of order at my expert advisor is 0.1 and volume is 0.01.

Is it right?

Please help me.

Thanks to everyone.

 
Chang Suk Chung:

Hi, everyone,

I am developing expert advisor.

But there is an "invalid volume" problem in my coding.

Below is the method I learn and think at mql5 articles.



I am going to put above code into "on Init" function of my expert advisor.

Lot size of order at my expert advisor is 0.1 and volume is 0.01.

Is it right?

Please help me.

Thanks to everyone.

This function should be called just before sending an order. And you have to use it properly (checking returned value, if false volume is not good).
 
Alain Verleyen:
This function should be called just before sending an order. And you have to use it properly (checking returned value, if false volume is not good).

Thanks very much.
 

Always normalize the lot size to double with the same broker lot format.

Never go lower than minimum, or over maximum allowed lot size.

I always use such code ...

int init(){
   
   MinLot = MarketInfo(Symbol(),MODE_MINLOT);
   MaxLot = MarketInfo(Symbol(),MODE_MAXLOT);
   if(MinLot == 0.001) LotDigits = 3;
   if(MinLot == 0.01)  LotDigits = 2;
   if(MinLot == 0.1)   LotDigits = 1;
   
   return(0);
}

 ...
 ...
 ...

double GetLotSize(){    
   double Lot;
   Lot = (AccountBalance()*Risk*0.01)/1000;
   if (Lot>=MaxLot) Lot = MaxLot;
   if (Lot<MinLot) Lot = MinLot;
   Lot = NormalizeDouble(Lot,LotDigits);
      
   if(!UseMM) Lot = Lots;
   return(Lot);
}   
...
 
Osama Shaban: Always normalize the lot size to double with the same broker lot format.
   Lot = NormalizeDouble(Lot,LotDigits);
Do NOT use NormalizeDouble, EVER. For ANY Reason. It's a kludge, don't use it. It's use is always wrong
 
whroeder1:
Do NOT use NormalizeDouble, EVER. For ANY Reason. It's a kludge, don't use it. It's use is always wrong


I'm sorry, Not convinced as I'm using it for ages in forex (currencies) with no problems at all.

I'm talking here about the lot size normalization.

For price formulas, I use DIGITS instead.

My question, As you said, "It's always wrong" ... Then, why when I use

"#property strict" in my code, I got no errors or warnings and my code works smooth.

Can you give an example to make things more clear please? 

 
Osama Shaban:


I'm sorry, Not convinced as I'm using it for ages in forex (currencies) with no problems at all.

I'm talking here about the lot size normalization.

For price formulas, I use DIGITS instead.

My question, As you said, "It's always wrong" ... Then, why when I use

"#property strict" in my code, I got no errors or warnings and my code works smooth.

Can you give an example to make things more clear please? 

Your way to normalize volume is incorrect, even if it runs most of the time for you. The problem is not using NormalizeDouble() which is just a rounding function. The problem is you need to have a multiple of lot step  (or volume step).

The code provided by the OP is correct, he was just knowing how to us it. (This code comes from a Metaquotes article).

Only and simple correct way to normalize volume is :

         double lotStep=SymbolInfoDouble(symbol,SYMBOL_VOLUME_STEP);
         volume=MathFloor(volume/lotStep)*lotStep;
MathFloor() could be replaced by MathRound() or MathCeil(), or even NormalizeDouble() . The principle is the same.
 

Please confirm the full use of the code for both MT5 and MT4


Thanks

 
Osama Shaban:

Always normalize the lot size to double with the same broker lot format.

Never go lower than minimum, or over maximum allowed lot size.

I always use such code ...

...
int init(){
   
   MinLot = MarketInfo(Symbol(),MODE_MINLOT);
   MaxLot = MarketInfo(Symbol(),MODE_MAXLOT);
   if(MinLot == 0.001) LotDigits = 3;
   if(MinLot == 0.01)  LotDigits = 2;
   if(MinLot == 0.1)   LotDigits = 1;
   
   return(0);
}

 ...
 ...
 ...

double GetLotSize(){    
   double Lot;
   Lot = (AccountBalance()*Risk*0.01)/1000;
   if (Lot>=MaxLot) Lot = MaxLot;
   if (Lot<MinLot) Lot = MinLot;
   Lot = NormalizeDouble(Lot,LotDigits);
      
   if(!UseMM) Lot = Lots;
   return(Lot);
}   


Is this code for MT4 or MT5
 
Chang Suk Chung: I am going to put above code into "on Init" function of my expert advisor.

Uriel Melliphant:
int init(){
   
   MinLot = MarketInfo(Symbol(),MODE_MINLOT);
   MaxLot = MarketInfo(Symbol(),MODE_MAXLOT);
Don't try to use any price or server related functions in OnInit (or on load,) as there may be no connection/chart yet:
  1. Terminal starts.
  2. Indicators/EAs are loaded. Static and globally declared variables are initialized. (Do not depend on a specific order.)
  3. OnInit is called.
  4. For indicators OnCalculate is called with any existing history.
  5. Human may have to enter password, connection to server begins.
  6. New history is received, OnCalculate called again.
  7. New tick is received, OnCalculate/OnTick is called. Now TickValue, TimeCurrent, account information and prices are valid.
 
whroeder1:
Don't try to use any price or server related functions in OnInit (or on load,) as there may be no connection/chart yet:
  1. Terminal starts.
  2. Indicators/EAs are loaded. Static and globally declared variables are initialized. (Do not depend on a specific order.)
  3. OnInit is called.
  4. For indicators OnCalculate is called with any existing history.
  5. Human may have to enter password, connection to server begins.
  6. New history is received, OnCalculate called again.
  7. New tick is received, OnCalculate/OnTick is called. Now TickValue, TimeCurrent, account information and prices are valid.

whroeder1


Please tell us about something that works....


The piece of code you include doesnt

Reason: