One of the most important rules when trading forex or any other instrument is Risk Management! Risk Management involves a set of rules to keep your account safe from unexpected events and “unlucky” times, it makes the difference between a good trader and an amateur. In saying that you must consider to learn how to calculate the position size with MQL4 code.

### Considering the Position Size

One of the most popular rules of risk management is to invest on each trade only a small percentage of your entire account, this is to prevent your account to be blown up in case of a strike of losing trades. For example, if your position size is 25% of your account each trade with a strike of 4 losing trades you are left with almost nothing, if you had used only the 2.5%, after a strike of 4 losing trades you would still have more than 90% of your balance available. Of course if the trades were winners the profit would have been higher, but we believe Risk Management is more important.

In this article we go straight to an indicator that can do all this for you.

No Downloads foundIt is beyond the scope of this article to explain what is the optimal percentage of balance to trade, also because it really depends on your strategy and trading style, our focus here is to show you how to calculate the position size with MQL4 code.

First, the theory, how do you calculate the position size?

Assume you want to risk only 1% of your balance on each trade, in this example your account is 10.000$, this means your risk for individual trade is 100$

You also know that for this trade you want a stop loss 20 pips away from the open price and, assuming this trade is on EURUSD, every pip for a standard lot size has a value of 10$, meaning 20 pips are valued 200$ (for more about pip value read What is a PIP (and a PIPETTE) in Forex Trading?)

Since you want to risk 100$ and have a stop loss 20 pips away (200$ for 1 standard lot) then your position size will be 0.5 standard lots

So, to sum up, to calculate the position size you need:

- Balance of your account
- Percentage of risk for the single trade
- Stop loss, in pip in this case
- Pip value

### How to Calculate the Position Size in MQL4

MetaTrader once again comes in our help with some native functions that will make it easy to calculate the position:

- AccountBalance() returns the available balance for the account
- MarketInfo(Symbol(),MODE_TICKVALUE) returns the value of a tick for the current pair

Now, this may be tricky, as we saw in the article about PIP Normalization, brokers can show the exchange rates with 4 or 5 decimals (2 or 3 for the JPY), if the broker is using 5 decimals (3 for JPY) then MarketInfo(Symbol(),MODE_TICKVALUE) is the value of a pipette instead of a pip. If this is the case to calculate the correct amount we will need to take into consideration the number of decimals in the exchange rate.

We can see some code to see how to calculate the position size, we will test it on a simple Expert Advisor, the balance of the account is 9.999.53$ and we set 1% risk and 20 pips stop loss.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | #property copyright "Luca Spinello" #property link "https://mql4tradingautomation.com" #property version "1.00" #property strict //Percentage of available balance to risk in each individual trade extern double MaxRiskPerTrade=1; //% of balance to risk in one trade extern int StopLoss=20; //Stop Loss in pips //We define the function to calculate the position size and return the lot to order //Only parameter the Stop Loss, it will return a double double CalculateLotSize(double SL){ //Calculate the size of the position size double LotSize=0; //We get the value of a tick double nTickValue=MarketInfo(Symbol(),MODE_TICKVALUE); //If the digits are 3 or 5 we normalize multiplying by 10 if(Digits==3 || Digits==5){ nTickValue=nTickValue*10; } //We apply the formula to calculate the position size and assign the value to the variable LotSize=(AccountBalance()*MaxRiskPerTrade/100)/(SL*nTickValue); return LotSize; } int OnInit() { return(INIT_SUCCEEDED); } void OnDeinit(const int reason) { } void OnTick() { //We print the position size in lots Print("Position size in lots? ",CalculateLotSize(StopLoss)); } |

The result of the script is

As you can see the position size is 0.4999765, this can create some problem when submitting orders as MetaTrader can accept only orders rounded to its minimal incremental lot size, in other words, you can submit an order for 1 lot but an order for 1.00005 lots will not be accepted.

We can find out what is the minimal increment for the orders with the function MarketInfo(Symbol(),MODE_LOTSTEP), usually this value is 0.01 which is equivalent to a micro lot. Using this function and some other maths we can round the number and match the accepted increment. We will add this line to the code

1 | LotSize=MathRound(LotSize/MarketInfo(Symbol(),MODE_LOTSTEP))*MarketInfo(Symbol(),MODE_LOTSTEP); |

Basically what we do is divide the found position size by the accepted increment and round the number and then multiply for the accepted increment, in the above example:

So if we use the following code we will avoid errors with the position size while ordering

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | #property copyright "Luca Spinello" #property link "https://mql4tradingautomation.com" #property version "1.00" #property strict //Percentage of available balance to risk in each individual trade extern double MaxRiskPerTrade=1; //% of balance to risk in one trade extern int StopLoss=20; //Stop Loss in pips //We define the function to calculate the position size and return the lot to order //Only parameter the Stop Loss, it will return a double double CalculateLotSize(double SL){ //Calculate the size of the position size double LotSize=0; //We get the value of a tick double nTickValue=MarketInfo(Symbol(),MODE_TICKVALUE); //If the digits are 3 or 5 we normalize multiplying by 10 if(Digits==3 || Digits==5){ nTickValue=nTickValue*10; } //We apply the formula to calculate the position size and assign the value to the variable LotSize=(AccountBalance()*MaxRiskPerTrade/100)/(SL*nTickValue); LotSize=MathRound(LotSize/MarketInfo(Symbol(),MODE_LOTSTEP))*MarketInfo(Symbol(),MODE_LOTSTEP); return LotSize; } int OnInit() { return(INIT_SUCCEEDED); } void OnDeinit(const int reason) { } void OnTick() { //We print the position size in lots Print("Position size in lots? ",CalculateLotSize(StopLoss)); } |

And the result will be

This function is very handy as with only two parameters is able to calculate the position size meeting your risk management strategy, furthermore, in the example above the Stop Loss was set to a static value, however in some strategies the Stop Loss may be variable and in that case this function would be still working as the calculated lot size is function also of the stop loss. Also, the function is suitable for all currency pairs as the tick value is known directly by MetaTrader considering your account currency and the currency you are applying the function to.

No Downloads foundIn this article we go straight to an indicator that can do all this for you.

Always remember to adopt Risk Management measures, they will make you a better trader!

Please leave a comment if you have any feedback or doubt and remember to like us on Social Media!

Great article and explanation. Good job.

Thank you, appreciate the feedback

Luca

Dear Luca,

Great and thanks for the code.

I’m looking for a way to use Account Equity instead of Balance.

KR,

Richard

There is an inbuilt function to have the account equity if you code, AccountEquity()

If you use the tool, instead, you can change the parameter for the calculation base from Balance to Equity

Nice job, just an advice, you’re defining as integer the StopLoss extern variable and using a double argument on the CalculateLotSize(double SL) function, you should change the SL argument type to int; same functionality but without warning alerts!

Thank you, good one!

Hi Luca,

Thanks I found it.

KR,

Richard

It’s the same formula i use but i think there is something missimg: you have to exchange the amount depending on the account currency. What do you think about that?

Using Market Infor TICK_VALUE that will take care of it, it automatically does the conversion in the account currency

Hi Luca, thanks for the absolutely clear explanation and very nice code too. I have just one question that I am sure it is also covered with this method but would like to double check with you. I have an account founded in USD and some of the pairs I trade are using a BASE cuurency and a DEPOSIT currency different than the USD. For example GBPCHF where the BASE currency is GBP and the DEPOSIT currency (sometimes called the TERMS currency) is the CHF.

So my question is: the AccountBalance() function will show how many USD I have available, but the lot size calculation is based on the deposit currency (CHF in my example), so shouldn’t we first convert our AccountBalance to the DEPOSIT currency first? In my example I would have to first convert my Balance to CHF:

double AcctBal=AccountBalance() * MarketInfo(“USDCHF”,MODE_ASK);

LotSize=(AccBal*MaxRiskPerTrade/100)/(SL*nTickValue) ;

How can we convert our Account Balance to every DEPOSIT currency we trade with?

Hi Roberto,

The method keeps into consideration this, in fact, the Tick Value returned by the broker is in you account currency, so basically it already converts it depending on the pair you are in

Hope this helps

Hi Luca,

Thanks! That was exactly what I was needing. In other words, I don’t need to do anything else but to use the method provided.

Kind Regards

Roberto