calculating Lots size

 

Hi,

I'm new, but learning lots

I have searched, but none of the solutions worked for me. Here is what I wrote for it, but the result sometimes results in not enough money? Any specific flaw in my logic? I realize I am not including a risk here, but just want to make sure I am on the right track first. Thank you!


double getLots(double entry, double stoploss) {
   double l = Lots;
   double accountTotal = AccountBalance() *  AccountLeverage();
   double qty = accountTotal / entry;
   double risk = MathAbs(entry - sl) / entry; // not used yet
   l = NormalizeDouble( lot / 100000, 2); // As 100,000 qty is equal 1.0 Lot
   double minLot = MarketInfo(Symbol(), MODE_MINLOT);  
   if (l < minLot) {
      l = minLot;
   }
   return l;
}
 
Never risk more than a small percentage of your trading funds, certainly less than 2% per trade, 6% total.

Risk depends on your initial stop loss, lot size, and the value of the pair. It does not depend on margin and leverage. No SL means you have infinite risk.

  1. You place the stop where it needs to be — where the reason for the trade is no longer valid. E.g. trading a support bounce the stop goes below the support.
  2. AccountBalance * percent/100 = RISK = OrderLots * (|OrderOpenPrice - OrderStopLoss| * DeltaPerLot + CommissionPerLot) (Note OOP-OSL includes the spread, and DeltaPerLot is usually around $10/pip but it takes account of the exchange rates of the pair vs. your account currency.)
  3. Do NOT use TickValue by itself - DeltaPerLot and verify that MODE_TICKVALUE is returning a value in your deposit currency, as promised by the documentation, or whether it is returning a value in the instrument's base currency.
              MODE_TICKVALUE is not reliable on non-fx instruments with many brokers - MQL4 programming forum 2017.10.10
              Is there an universal solution for Tick value? - Currency Pairs - General - MQL5 programming forum 2018.02.11
              Lot value calculation off by a factor of 100 - MQL5 programming forum 2019.07.19
  4. You must normalize lots properly and check against min and max.
  5. You must also check FreeMargin to avoid stop out

Most pairs are worth about $10 per PIP. A $5 risk with a (very small) 5 PIP SL is $5/$10/5 or 0.1 Lots maximum.

 
leroadrunner:

Hi,

I'm new, but learning lots

I have searched, but none of the solutions worked for me. Here is what I wrote for it, but the result sometimes results in not enough money? Any specific flaw in my logic? I realize I am not including a risk here, but just want to make sure I am on the right track first. Thank you!


It is very likely that you are running into the issue of Maximum Leverage. Unfortunately your AccountLeverage grabs the value set for your account, but depending on the pair you are trading the value could be limited, and MT4 does not account for this. You would need to find out what Maximum Leverage amounts are in place for your Account Currency and use that value rather than AccountLeverage.

For example:

double getLots(double entry, double stoploss) {
   double l = Lots;
   double accountTotal = AccountBalance() *  GetLeverage()
   double qty = accountTotal / entry;
   double risk = MathAbs(entry - sl) / entry; // not used yet
   l = NormalizeDouble( lot / 100000, 2); // As 100,000 qty is equal 1.0 Lot
   double minLot = MarketInfo(Symbol(), MODE_MINLOT);  
   if (l < minLot) {
      l = minLot;
   }
   return l;
}

double GetLeverage() {
   double   acctLeverage   =  AccountLeverage();
   double   maxLeverage    =  acctLeverage;
   
   if(AccountCurrency() == "CAD") {
      if(Symbol() == "TRYJPY" || Symbol() == "ZARJPY") {
         maxLeverage =  3.4;
      }
      
      if(Symbol() == "CHFZAR" || Symbol() == "EURTRY" || Symbol() == "EURZAR" || Symbol() == "GBPZAR") {
         maxLeverage =  3.6;
      }
      
      if (Symbol() == "USDCNH" || Symbol() == "USDINR" || Symbol() == "USDTHB" || Symbol() == "USDTRY" || Symbol() == "USDZAR") {
         maxLeverage =  3.7;
      }
      
      if(Symbol() == "SGDHKD") {
         maxLeverage =  5;
      }
      
      if(Symbol() == "HKDJPY" || Symbol() == "SGDJPY") {
         maxLeverage = 7.1;
      }
      
      if(Symbol() == "AUDHKD" || Symbol() == "AUDSGD" || Symbol() == "CHFHKD" || Symbol() == "EURCZK" || Symbol() == "EURDKK" ||
         Symbol() == "EURHKD" || Symbol() == "EURHUF" || Symbol() == "EURPLN" || Symbol() == "EURSGD" || Symbol() == "GBPHKD" ||
         Symbol() == "GBPPLN" || Symbol() == "GBPSGD" || Symbol() == "NZDHKD" || Symbol() == "NZDSGD" || Symbol() == "SGDCHF") {
         maxLeverage =  7.7;
      }
      
      if(Symbol() == "USDCZK" || Symbol() == "USDDKK" || Symbol() == "USDHKD" || Symbol() == "USDHUF" || Symbol() == "USDPLN" ||
      Symbol() == "USDSAR" || Symbol() == "USDSGD") {
         maxLeverage =  8.2;
      }
      
      if(Symbol() == "CADHKD" || Symbol() == "CADSGD") {
         maxLeverage =  10;
      }
      
      if(Symbol() == "USDMXN") {
         maxLeverage =  12.5;
      }
      
      if(Symbol() == "AUDJPY" || Symbol() == "CHFJPY" || Symbol() == "EURJPY" || Symbol() == "GBPJPY" || Symbol() == "NZDJPY") {
         maxLeverage =  14.3;
      }
      
      if(Symbol() == "USDJPY") {
         maxLeverage =  16.1;
      }
      
      if(Symbol() == "AUDCHF" || Symbol() == "AUDNZD" || Symbol() == "EURAUD" || Symbol() == "EURCHF" || Symbol() == "EURGBP" ||
         Symbol() == "EURNOK" || Symbol() == "EURNZD" || Symbol() == "EURSEK" || Symbol() == "GBPAUD" || Symbol() == "GBPCHF" ||
         Symbol() == "GBPNZD" || Symbol() == "NZDCHF") {
         maxLeverage =  16.7;
      }
      
      if(Symbol() == "AUDUSD" || Symbol() == "EURUSD" || Symbol() == "GBPUSD" || Symbol() == "NZDUSD" || Symbol() == "USDCHF" ||
      Symbol() == "USDNOK" || Symbol() == "USDSEK") {
         maxLeverage =  19.2;
      }
      
      if(Symbol() == "GBPCAD") {
         maxLeverage =  20;
      }
      
      if(Symbol() == "CADJPY") {
         maxLeverage =  25;
      }
      
      if(Symbol() == "AUDCAD" || Symbol() == "CADCHF" || Symbol() == "EURCAD" || Symbol() == "NZDCAD") {
         maxLeverage =  33.3;
      }
      
      if(Symbol() == "USDCAD") {
         maxLeverage =  45.5;
      }
   }
   
   if(AccountCurrency() == "EUR" || AccountCurrency() == "GBP") {
      if(Symbol() == "CHFZAR" || Symbol() == "EURCZK" || Symbol() == "EURHUF" || Symbol() == "EURPLN" ||
         Symbol() == "EURTRY" || Symbol() == "EURZAR" || Symbol() == "GBPPLN" || Symbol() == "GBPZAR" ||
         Symbol() == "TRYJPY" || Symbol() == "USDCNH" || Symbol() == "USDCZK" || Symbol() == "USDHUF" ||
         Symbol() == "USDINR" || Symbol() == "USDMXN" || Symbol() == "USDPLN" || Symbol() == "USDSAR" ||
         Symbol() == "USDTHB" || Symbol() == "USDTRY" || Symbol() == "USDZAR") {
         maxLeverage =  20;
      }
      
      if(Symbol() == "AUDHKD" || Symbol() == "AUDSGD" || Symbol() == "CADHKD" || Symbol() == "CADSGD" ||
         Symbol() == "CHFHKD" || Symbol() == "EURHKD" || Symbol() == "EURSGD" || Symbol() == "GBPHKD" ||
         Symbol() == "GBPSGD" || Symbol() == "HKDJPY" || Symbol() == "NZDHKD" || Symbol() == "NZDSGD" ||
         Symbol() == "SGDCHF" || Symbol() == "SGDHKD" || Symbol() == "SGDJPY" || Symbol() == "USDHKD" ||
         Symbol() == "USDSGD" || Symbol() == "ZARJPY") {
         maxLeverage =  50;
      }
      
      if(Symbol() == "AUDCAD" || Symbol() == "AUDCHF" || Symbol() == "AUDJPY" || Symbol() == "AUDNZD" ||
         Symbol() == "AUDUSD" || Symbol() == "CADCHF" || Symbol() == "CADJPY" || Symbol() == "CHFJPY" ||
         Symbol() == "EURAUD" || Symbol() == "EURCAD" || Symbol() == "EURCHF" || Symbol() == "EURDKK" ||
         Symbol() == "EURGBP" || Symbol() == "EURJPY" || Symbol() == "EURNOK" || Symbol() == "EURNZD" ||
         Symbol() == "EURSEK" || Symbol() == "EURUSD" || Symbol() == "GBPAUD" || Symbol() == "GBPCAD" ||
         Symbol() == "GBPCHF" || Symbol() == "GBPJPY" || Symbol() == "GBPNZD" || Symbol() == "GBPUSD" ||
         Symbol() == "NZDCAD" || Symbol() == "NZDCHF" || Symbol() == "NZDJPY" || Symbol() == "NZDUSD" ||
         Symbol() == "USDCAD" || Symbol() == "USDCHF" || Symbol() == "USDDKK" || Symbol() == "USDJPY" ||
         Symbol() == "USDNOK" || Symbol() == "USDSEK") {
         maxLeverage =  100;
      }
   }
   
   if(AccountCurrency() == "USD") {
      if(Symbol() == "USDMXN") {
         maxLeverage =  12.5;
      }
      
      if(Symbol() == "AUDHKD" || Symbol() == "AUDSGD" || Symbol() == "CADHKD" || Symbol() == "CADSGD" || Symbol() == "CHFHKD" ||
         Symbol() == "CHFZAR" || Symbol() == "EURCZK" || Symbol() == "EURGBP" || Symbol() == "EURHKD" || Symbol() == "EURHUF" ||
         Symbol() == "EURPLN" || Symbol() == "EURSGD" || Symbol() == "EURTRY" || Symbol() == "EURZAR" || Symbol() == "GBPAUD" ||
         Symbol() == "GBPCAD" || Symbol() == "GBPCHF" || Symbol() == "GBPHKD" || Symbol() == "GBPJPY" || Symbol() == "GBPNZD" ||
         Symbol() == "GBPPLN" || Symbol() == "GBPSGD" || Symbol() == "GBPUSD" || Symbol() == "GBPZAR" || Symbol() == "HKDJPY" ||
         Symbol() == "NZDHKD" || Symbol() == "NZDSGD" || Symbol() == "SGDCHF" || Symbol() == "SGDHKD" || Symbol() == "SGDJPY" ||
         Symbol() == "TRYJPY" || Symbol() == "USDCNH" || Symbol() == "USDCZK" || Symbol() == "USDHKD" || Symbol() == "USDHUF" ||
         Symbol() == "USDPLN" || Symbol() == "USDSAR" || Symbol() == "USDSGD" || Symbol() == "USDTHB" || Symbol() == "USDTRY" ||
         Symbol() == "USDZAR" || Symbol() == "ZARJPY") {
         maxLeverage =  20;
      }
      
      if (Symbol() == "AUDJPY" || Symbol() == "CADJPY" || Symbol() == "CHFJPY" || Symbol() == "EURJPY" || Symbol() == "NZDJPY" ||
         Symbol() == "USDJPY") {
         maxLeverage =  25;
      }
      
      if(Symbol() == "AUDCAD" || Symbol() == "AUDCHF" || Symbol() == "AUDNZD" || Symbol() == "AUDUSD" || Symbol() == "CADCHF" ||
         Symbol() == "EURAUD" || Symbol() == "EURCHF" || Symbol() == "EURNOK" || Symbol() == "EURNZD" || Symbol() == "EURSEK" ||
         Symbol() == "NZDCAD" || Symbol() == "NZDCHF" || Symbol() == "NZDUSD" || Symbol() == "USDCHF" || Symbol() == "USDNOK" ||
         Symbol() == "USDSEK") {
         maxLeverage =  33.3;
      }
      
      if(Symbol() == "EURCAD" || Symbol() == "EURDKK" || Symbol() == "EURUSD" || Symbol() == "USDCAD" || Symbol() == "USDDKK") {
         maxLeverage =  50;
      }
   }
   
   if(acctLeverage > maxLeverage) {
      acctLeverage   =  maxLeverage;
   }
   
   return(acctLeverage);
}
 

If you are worried about margin and leverage, you are not controlling your risk.

Never risk more than a small percentage of your trading funds, certainly less than 2% per trade, 6% total.

Risk depends on your initial stop loss, lot size, and the value of the pair. It does not depend on margin and leverage. No SL means you have infinite risk.

  1. You place the stop where it needs to be — where the reason for the trade is no longer valid. E.g. trading a support bounce the stop goes below the support.
  2. AccountBalance * percent/100 = RISK = OrderLots * (|OrderOpenPrice - OrderStopLoss| * DeltaPerLot + CommissionPerLot) (Note OOP-OSL includes the spread, and DeltaPerLot is usually around $10/pip but it takes account of the exchange rates of the pair vs. your account currency.)
  3. Do NOT use TickValue by itself - DeltaPerLot and verify that MODE_TICKVALUE is returning a value in your deposit currency, as promised by the documentation, or whether it is returning a value in the instrument's base currency.
              MODE_TICKVALUE is not reliable on non-fx instruments with many brokers - MQL4 programming forum 2017.10.10
              Is there an universal solution for Tick value? - Currency Pairs - General - MQL5 programming forum 2018.02.11
              Lot value calculation off by a factor of 100 - MQL5 programming forum 2019.07.19
  4. You must normalize lots properly and check against min and max.
  5. You must also check FreeMargin to avoid stop out

Most pairs are worth about $10 per PIP. A $5 risk with a (very small) 5 PIP SL is $5/$10/5 or 0.1 Lots maximum.

 
William Roeder:

If you are worried about margin and leverage, you are not controlling your risk.

Never risk more than a small percentage of your trading funds, certainly less than 2% per trade, 6% total.

Risk depends on your initial stop loss, lot size, and the value of the pair. It does not depend on margin and leverage. No SL means you have infinite risk.

  1. You place the stop where it needs to be — where the reason for the trade is no longer valid. E.g. trading a support bounce the stop goes below the support.
  2. AccountBalance * percent/100 = RISK = OrderLots * (|OrderOpenPrice - OrderStopLoss| * DeltaPerLot + CommissionPerLot) (Note OOP-OSL includes the spread, and DeltaPerLot is usually around $10/pip but it takes account of the exchange rates of the pair vs. your account currency.)
  3. Do NOT use TickValue by itself - DeltaPerLot and verify that MODE_TICKVALUE is returning a value in your deposit currency, as promised by the documentation, or whether it is returning a value in the instrument's base currency.
              MODE_TICKVALUE is not reliable on non-fx instruments with many brokers - MQL4 programming forum 2017.10.10
              Is there an universal solution for Tick value? - Currency Pairs - General - MQL5 programming forum 2018.02.11
              Lot value calculation off by a factor of 100 - MQL5 programming forum 2019.07.19
  4. You must normalize lots properly and check against min and max.
  5. You must also check FreeMargin to avoid stop out

Most pairs are worth about $10 per PIP. A $5 risk with a (very small) 5 PIP SL is $5/$10/5 or 0.1 Lots maximum.

If you are following proper money management and risking 1% of your account balance on a trade, you still need to know how much margin is required to enter the position.

For example, if you have a $1,000 account and risk $10 on a trade with a SL of 10 pips it would be 0.10 lots which requires $624.47 of margin on my account, so we are good to enter the trade while risking only 1%.

If instead the SL is 5 pips it would be 0.20 lots which requires $1,248.93 which is not possible because we do not have enough margin available.

In both scenarios we are risking the same amount, just 1% of our account but one trade is not possible to take. So calculating the margin needed is necessary, and not necessarily a reflection on poor money management by the trader, as your double post asserts.

I trade with a very tight SL, so a trade may require a great deal of free margin while risking very little capital.

@leroadrunner did not specify anywhere how much of their account they were risking, so I believe it is more accurate to assume they are being caught of guard by a leverage amount less than what they expect for certain pairs. But they can correct me if I am wrong.

Proper money management is always sound advice however, so thanks for the reminder.

 

As I said, I was not inlcuing the risk currently, just learning to see if my calculations are ok.

As pointed out, I will read about DeltaPerLot. Thanks

I did not realized that each pair had its own Leverage, is there a way dynamically to determine it instead of hardcoding?

 
leroadrunner:

As I said, I was not inlcuing the risk currently, just learning to see if my calculations are ok.

As pointed out, I will read about DeltaPerLot. Thanks

I did not realized that each pair had its own Leverage, is there a way dynamically to determine it instead of hardcoding?

No. As I said in my post, MT4 has overlooked or chosen to ignore the new restrictions that are beng put in place around the globe, so there is no is no built in way to determine the real leverage. The code I provided is what I use, and as I said it does the job.

 
Frederick Langemark:

No. As I said in my post, MT4 has overlooked or chosen to ignore the new restrictions that are beating put in place around the globe, so there is no is no built in way to determine the real leverage. The code I provided is what I use, and as I said it does the job.

Thank you Frederick!


So, where do you find the source of those Leverage per pair?

 
Frederick Langemark:

No. As I said in my post, MT4 has overlooked or chosen to ignore the new restrictions that are beating put in place around the globe, so there is no is no built in way to determine the real leverage. The code I provided is what I use, and as I said it does the job.

MT4 is more than 15 years old software, not sure what you are talking about ?

Anyway, it's perfectly possible to determine by code the real leverage, though of course there is not a direct function to get it.

 
Alain Verleyen:

MT4 is more than 15 years old software, not sure what you are talking about ?

Anyway, it's perfectly possible to determine by code the real leverage, though of course there is not a direct function to get it.

I'm simply talking about the fact when you use any of the built in methods for determining the Margin required, MT4 may return invalid information because of the much newer than 15 year old restrictions. Without you manually inputting the leverage for each pair that your broker uses, there is no way to get an accurate calculation.

If you know a better way, please enlighten us because I have seen this question asked all over the place and the code I am using is the best I have come up with.

Say the maximum leverage on my account is 50, every calculation I use assumes 50 but for some pairs here in the US the maximum allowed is 12.5 which makes all the MQL4 methods I am aware of pretty useless without coding my own check.

 
leroadrunner:

Thank you Frederick!


So, where do you find the source of those Leverage per pair?

My Broker has the numbers published on their website, but the restrictions vary by county. I'm sure your Broker either has the values listed on their website, or would provide them to you.

Reason: