Limit volume

 
Hello everyone

I am having problems with limiting the volume of lots, I would like to know if you can help me please, this is the code to obtain the lot to invest:

double GetLots ()
   {
    double lots = 0;
    if (MM)
      {
       lots = NormalizeDouble (AccountFreeMargin () * Risk / 100 / 1000.0,2);
      }
    else lots = NormalizeDouble (lot, Digits);
    return (lots);
   }

MM = Money Management.

What I need is to limit the minimum volume and the maximum volume.


I would greatly appreciate your help.

 
lots = NormalizeDouble (lot, Digits);

Why are you normalizing to Digits? I don't believe that there is a lot size with more than 2 digits.

 
Angel Antonio Martinez Velasquez:
Hello everyone

I am having problems with limiting the volume of lots, I would like to know if you can help me please, this is the code to obtain the lot to invest:

MM = Money Management.

What I need is to limit the minimum volume and the maximum volume.


I would greatly appreciate your help.

double GetLots ()
   {
    double lots = 0;
    if (MM)
      {
       lots = NormalizeDouble (AccountFreeMargin () * Risk / 100 / 1000.0,2);
      }
    else lots = NormalizeDouble (lot, Digits);
    ///
    if(lots<MarketInfo(_Symbol,MODE_MINLOT)) { lots = MarketInfo(_Symbol,MODE_MINLOT); } else if(lots>MarketInfo(_Symbol,MODE_MAXLOT)) { lots = MarketInfo(_Symbol,MODE_MAXLOT); }
    ///
    return (lots);
   }
 
Icham Aidibe:

You committing the same mistake as the OP. You should never adjust the volume based on Digits, but instead use the Lot Step for that.

Angel Antonio Martinez Velasquez

I am having problems with limiting the volume of lots, I would like to know if you can help me please, this is the code to obtain the lot to invest:

MM = Money Management.

What I need is to limit the minimum volume and the maximum volume.

I would greatly appreciate your help.

The following post is a very old and the code is also very old (MQL4, not MQL5), but it can give you an idea of what you should be doing:

Forum on trading, automated trading systems and testing trading strategies

Need moneymanagement LOT size formula based on SL and Account Risk!

Fernando Carreiro, 2014.01.09 02:37

OK guys! This code was written by me and it is what I use in my own EA's. It is quite complex because, besides the Risk% and StopLoss, it also takes into account the Margin Risk% as well as correct the Lot Size based on Minimum, Maximum and Step Size. It also always uses the minimum value of Current Balance and Equity instead of just using one of them. I feel it is safer that way.

Please note, however, that it does not use the spread in the calculation, because I calculate that separately when calculating the StopLoss to be used. The below function, thus uses a relative stop loss size. In my EA's the argument dblStopLossPips is calculated beforehand depending on various factors such as the strategy, spread, ATR, etc.; so the final value passed on to the dblLotsRisk() function is already a final value in order to calculate the Lot size to be used.

// Function to Determine Tick Point Value in Account Currency
   double dblTickValue( string strSymbol )
   {
      return( MarketInfo( strSymbol, MODE_TICKVALUE ) );
   }     

// Function to Determine Pip Point Value in Account Currency
   double dblPipValue( string strSymbol )
   {
      double dblCalcPipValue = dblTickValue( strSymbol );
      switch ( MarketInfo( strSymbol, MODE_DIGITS ) )
      {
         case 3:
         case 5:
            dblCalcPipValue *= 10;
            break;
      }
      return( dblCalcPipValue );
   }    

// Calculate Lot Size based on Maximum Risk & Margin
   double dblLotsRisk( string strSymbol, double dblStopLossPips,
                       double dblRiskMaxPercent, double dblMarginMaxPercent )
   {
      double
         dblValueAccount  = MathMin( AccountEquity(), AccountBalance() ),
         dblValueRisk     = dblValueAccount     * dblRiskMaxPercent   / 100.0,
         dblValueMargin   = AccountFreeMargin() * dblMarginMaxPercent / 100.0,
         dblLossOrder     = dblStopLossPips * dblPipValue( strSymbol ),
         dblMarginOrder   = MarketInfo( strSymbol, MODE_MARGINREQUIRED ),
         dblCalcLotMin    = MarketInfo( strSymbol, MODE_MINLOT         ),
         dblCalcLotMax    = MarketInfo( strSymbol, MODE_MAXLOT         ),
         dblCalcLotStep   = MarketInfo( strSymbol, MODE_LOTSTEP        ),
         dblCalcLotLoss   = MathRound( dblValueRisk   / dblLossOrder   / dblCalcLotStep ) * dblCalcLotStep,
         dblCalcLotMargin = MathRound( dblValueMargin / dblMarginOrder / dblCalcLotStep ) * dblCalcLotStep,
         dblCalcLot       = MathMin( dblCalcLotLoss, dblCalcLotMargin );
                
         if ( dblCalcLot < dblCalcLotMin ) dblCalcLot = dblCalcLotMin;
         if ( dblCalcLot > dblCalcLotMax ) dblCalcLot = dblCalcLotMax;

         return ( dblCalcLot );
   }
PS! I altered and simplified the code here a bit in this post as apposed to the original post in the reference thread, so as to make it easier for you to understand it.
 
Fernando Carreiro:

You committing the same mistake as the OP. You should never adjust the volume based on Digits, but instead use the Lot Step for that.

The following post is a very old and the code is also very old, but it can give you an idea of what you should be doing:

PS! I altered and simplified the code here a bit in this post as apposed to the original post in the reference thread, so as to make it easier for you to understand it.

Dear,

this : 

 dblCalcLotMin    = MarketInfo( strSymbol, MODE_MINLOT         ),
 dblCalcLotMax    = MarketInfo( strSymbol, MODE_MAXLOT         ),  
.... 
 if ( dblCalcLot < dblCalcLotMin ) dblCalcLot = dblCalcLotMin;
 if ( dblCalcLot > dblCalcLotMax ) dblCalcLot = dblCalcLotMax;

is the same as this :

 if(lots<MarketInfo(_Symbol,MODE_MINLOT)) { lots = MarketInfo(_Symbol,MODE_MINLOT); } else if(lots>MarketInfo(_Symbol,MODE_MAXLOT)) { lots = MarketInfo(_Symbol,MODE_MAXLOT); }

You just bored and wanna chat, right ?

 
Icham Aidibe:

Dear,

this : 

is the same as this :

You just bored and wanna chat, right ?

No, I was being serious and I was talking about the following line in your code:

else lots = NormalizeDouble (lot, Digits);

For which @Keith Watford also mentioned in his post #1 just before yours.

Also, you should not be normalising to two digits either:

lots = NormalizeDouble (AccountFreeMargin () * Risk / 100 / 1000.0,2);

You should be adjusting to the Lot Step!

MarketInfo(       _Symbol, MODE_LOTSTEP       ) // MQL4
SymbolInfoDouble( _Symbol, SYMBOL_VOLUME_STEP ) // MQL5
 
Fernando Carreiro:

No, I was being serious and I was talking about the following line in your code:

For which @Keith Watford also mentioned in his post #1 just before yours.

Also, you should not be normalising to two digits either:

You should be adjusting to the Lot Step!

My bad, it seems I answered to the question. 

Angel Antonio Martinez Velasquez:
Hello everyone

I am having problems with limiting the volume of lots, I would like to know if you can help me please, this is the code to obtain the lot to invest:

MM = Money Management.

What I need is to limit the minimum volume and the maximum volume.


I would greatly appreciate your help.

But take note also of Fernando & Keith post, there's a bug in MT4 with volume normalization you'll meet for sure.

 

...quick plug for the CDouble library. You can just use the RoundToLots function. 


lots = CDouble::RoundToLots(lots);
This ensures that the number is rounded down to the lot step and conforms to the min/max volume. 
 
Keith Watford:

Why are you normalizing to Digits? 

Hi, thanks for answering my question. What should be the correct way to do it?

 
Angel Antonio Martinez Velasquez: Hi, thanks for answering my question. What should be the correct way to do it?

That has already been answered in the several posts thereafter, including a full example of code for money management, as well as explanations about why the volume needs to be rounded to the Lot Step and an alternative using @nicholi shen's CDouble library.

Did you not read those posts?

 
Icham Aidibe:

Many thanks Icham!


It was what I needed.

Reason: