As an Amazon Associate I earn from qualifying purchases.

In the last post, we looked at how you can dynamically load strategies into your trader. Today, I will show you how to dynamically calculate the lot size your algorithmic trading bot. The position size of a trade will depend on a percentage of risk, you are willing to take on your account balance. E.g. if your risk percentage is 1% and you have a \$5000 account then the maximum amount of money you can lose in one trade is \$50.

Contents

## Calculate the value of one pip

To start, you will need to install a new library called `forex-python`. You can install this using the command below or by going here. Forex Python is a Free Foreign exchange rates and currency conversion which we will be using to calculate the value of a pip.

``pip install forex-python``

After this has been installed, go to your `constants.py` file and import this new library as follows:

``````import talib as ta
from forex_python.converter import CurrencyRates``````

Next, let’s add a method to our `constants.py` file to calculate the pip value. We need to calculate the size of one pip for a given instrument. You can call this new method `get_pip_value` and it should take arguments of `symbol` and `account_currency`:

``def get_pip_value(symbol, account_currency):``

Now we need to split up our symbol into 2 currencies. I.e if we passed “EURUSD” as a symbol then we need to split it up as “EUR” and “USD”:

``````def get_pip_value(symbol, account_currency):
symbol_1 = symbol[0:3]
symbol_2 = symbol[3:6]``````

Finally, using the CurrencyRates module lets calculate the value of one pip and convert it to our local currency. More information on how the `convert` method works can be found here:

``````def get_pip_value(symbol, account_currency):
symbol_1 = symbol[0:3]
symbol_2 = symbol[3:6]
c = CurrencyRates()
return c.convert(symbol_2, account_currency, c.convert(symbol_1, symbol_2, 1))``````

Let’s have a look at your `trader.py` file again. You will be adding a new method called `calc_position_size` which takes the following arguments: `symbol, strategy`.

``def calc_position_size(symbol, strategy):``

To calculate a percentage of your balance you are willing to risk you need to actually know the current balance of your account. Retrieve this by using the `acount_info` method from the MT5 API. More information on this can be found here. Call this method and assign it to a variable named `account`. Also, add a print statement to say that you are calculating the position size for a given symbol.

``````def calc_position_size(symbol, strategy):
print("Calculating position size for: ", symbol)
account = mt5.account_info()``````

With this done, create a new variable named `balance` and get the balance from `account`:

``    balance = float(account.balance)``

Now, we need to calculate the pip value of the symbol. This is done by calling the method created earlier in `constants.py`. Remember, you will need to pass in the symbol and account currency for this method. Assign this to a new variable called `pip_value`:

``    pip_value = constants.getPipValue(symbol, strategy['account_currency'])``

Don’t worry about referencing `account_currency` in your strategy. You will be adding this entry to your strategy json file later. You will now need to calculate the lot size based of your account balance. To calculate the lot size use the following equation:

Lot size = (balance * risk) / pip value * stop loss

Your python code should look like the following:

``lot_size = (float(balance) * (float(strategy["risk"])/100)) / (pip_value * strategy["stopLoss"])``

Finally, round the value to 2 decimal places (as MT5 only accepts lot sizes rounded to 2 decimal places) and return:

``````    lot_size = round(lot_size, 2)
return lot_size``````

Let’s go back to the `check_trades` methods created earlier. In that method, find where you are opening a position (`open_position`…) and above this method call add the following line:

``                lot_size = calc_position_size(pair, strategy)``

In your `open_position` call, replace the current lot size with the one from the variable created above:

``                open_position(pair, "BUY", lot_size, float (strategy['takeProfit']), float(strategy['stopLoss']))``

## Adding new properties to the strategy json file

You will remember that we references 2 new properties from the strategy in this post called `account_currency` and `risk`. These properties do not exist in our strategy yet. Let’s fix that!

Go to your `strategy.json` file and add the `account_currency` property to the top of the file. In my case, I will add USD as my account currency:

``````{
"account_currency" : "USD",
"strategy_name": "myStrategy",``````

After `strategy_name` define your risk as a percentage value. E.g. 2 = 2%:

``````{
"account_currency" : "USD",
"strategy_name": "myStrategy",
"pairs": [
"EURUSD",
"GBPUSD"
],
"risk" : 2,``````

## Testing the code

Now let’s test our code. For this test I will simply run the trader and wait for a trade to open. The lot size should be dynamically calculated based on my account balance and risk.

``````C:\Users\conor\Documents\blog files>python trader.py strategy
Trading bot started with strategy: strategy
Connected: Connecting to MT5 Client
Connected: Connecting to MT5 Client
Connected: Connecting to MT5 Client
Connected: Connecting to MT5 Client
Connected: Connecting to MT5 Client
Connected: Connecting to MT5 Client
Connected: Connecting to MT5 Client
Calculating position size for:  EURUSD
Order successfully placed!``````

As you can see above, the trader ran and opened a position on EURUSD with a calculated lot size of 5.53.

If you are interested in learning more about algo trading and trading systems, I highly recommend reading this book. I have taken some of my own trading ideas and strategies from this book. It also provided me a great insight into effective back testing. Check it out here.

That’s all for now! Check back on Monday to see how you can send trading alerts to your phone via slack! As always, if you have any questions or comments please feel free to post them below. Additionally, if you run into any issues please let me know.

### 4 thoughts on “Dynamically calculate lot size for your algorithmic trading bot”

1. Hi, first i want to tell you that your tutorial is awesome, Congrats !

I have a problem, maybe I did something wrong but the lot size doesn’t seems to be accurate. I compare my result with this site : https://www.myfxbook.com/fr/forex-calculators/position-size

for instance :
I have a account with 100 000 EUR, with a risk of 1% and a 5 pips SL. I trade on AUDUSD.
The program give me a lot size equal to 31.33 , on the other hand the site give me a lot size equal to 24.24. Do you have the same problem ?

On an other subject, do you think you will implement the backtest of the trading robot in your tutorial ?

Anyway, thanks again for this incredible tutorial !
regards,
Thibault

1. Thanks! Is “account_currency” in strategy.json set to “EUR”? Also, yes this should be coming out within the next few weeks 🙂

1. I don’t use the json part, because I want to create a strategy using price action so i really need to code all my strat,
but anyway my two function looks like that (almost the same as yours) :

def get_pip_value(symbol : str, account_currency : str) -> CurrencyRates:
symbol_1 = symbol[0:3]
symbol_2 = symbol[3:6]
c = CurrencyRates()
return c.convert(symbol_2, account_currency, c.convert(symbol_1, symbol_2, 1))

def calc_position_size(symbol : str, account_currency : str, risk : float, sl : int) -> float:
account = mt5.account_info()
balance = float(account.balance)
pip_value = get_pip_value(symbol, account_currency)
lot_size = (balance * (risk / 100)) / (pip_value * sl)
lot_size = round(lot_size, 2)
return lot_size

for instance, if I took the same example from my first comment:
When i call calc_position_size, I set symbol to “AUDUSD”, account_currency to “EUR”, risk to 1 and sl to 50.

1. I think i have understand why i had this problem. It was because c.converter is not very precise (and not negligible at all).

In my function I have the last_row_lot_all_pair argument which is the information of the last 1 minute candle of the needed pair, so we have a lot of precision with this. I post my function below if you want to see, but now i have the exact same result than myfxbook.

def calc_position_size(symbol : str, account_currency : str, risk : float, sl : int, last_row_lot_all_pair: dict) -> float:
ACCOUNT = mt5.account_info()
BALANCE = ACCOUNT.balance
CURRENCY_2 = symbol[3:6]
SYMBOL_TO_CONVERT = account_currency + CURRENCY_2
close_candle_symbol_to_convert = float(last_row_lot_all_pair[SYMBOL_TO_CONVERT][“close”])
if CURRENCY_2 == “JPY” :
JPY_CONVERTER_PIPS = 100
close_candle_symbol_to_convert = close_candle_symbol_to_convert/JPY_CONVERTER_PIPS
SL_PIPS = sl/10
PERCENTAGE_CONVERTER = 0.01
RISK_PERCENTAGE = risk*PERCENTAGE_CONVERTER
PIP_VALUE = ((BALANCE*RISK_PERCENTAGE)/SL_PIPS)
STANDARD_LOT = 1
PRICE_STANDART_LOT = 10
MINI_LOT = 0.1
PRICE_MINI_LOT = 1
MICRO_LOT = 0.01
PRICE_MICRO_LOT = 0.1
if PIP_VALUE < PRICE_MINI_LOT :
lot_size = (PIP_VALUE/(PRICE_MICRO_LOT/close_candle_symbol_to_convert))*MICRO_LOT
elif PIP_VALUE < PRICE_STANDART_LOT :
lot_size = (PIP_VALUE/(PRICE_MINI_LOT/close_candle_symbol_to_convert))*MINI_LOT
else :
lot_size = (PIP_VALUE/(PRICE_STANDART_LOT/close_candle_symbol_to_convert))*STANDARD_LOT
lot_size = round(lot_size,2)
return lot_size

Holler Box