# Creating a strategy for your algorithmic trading bot – Part 2

As an Amazon Associate I earn from qualifying purchases.

Today, we will be continue creating a strategy for your algorithmic trading bot.

By now, you should have 3 new files created from the last post. `strategy.py` that loads in your strategy, `myStrategy.json` that contains your strategy and a `constants.py` file that stores all the moving average functions for ta-lib. Today, we will be exploring how to dynamically apply this strategy to our trader. Let’s get started!

Contents

Let’s go back to the main code add imports for the new python files that you have created. Add `strategy` and `constants` and `sys` to your list of imports:

``````import MetaTrader5 as mt5
from datetime import datetime, timedelta
import pandas as pd
import pytz
import schedule
import talib as ta
import time
import strategy
import constants
import sys``````

After adding the imports, modify the get_data method to include a new argument called strategy:

``def get_data(time_frame, strategy):``

On the next line where pairs are defined, replace this with `strategy['pairs']`. This means that all of our trading pairs will come from the strategy. This is important as you probably will want to trade different pairs with different strategies:

``````def get_data(time_frame, strategy):
pairs = strategy['pairs']``````

Add the same `strategy` parameter to the `check_trades` method as follows:

``def check_trades(time_frame, pair_data, strategy):``

With this done, delete the 2 lines that are calculating SMA and EMA. We will be replacing this with something more dynamic:

``````        data['SMA'] = ta.SMA(data['close'], 10)
data['EMA'] = ta.EMA(data['close'], 50)``````

First of all, let’s get our defined moving averages from the strategy dictionary. Under the method signature for `check_trades` add the following:

``    moving_averages = strategy['movingAverages']``

Here is a reminder of what the moving averages were defined as from the last post:

``````	"movingAverages": {
"SMA": {
"val": 10,
"aboveBelow": "below"
},
"EMA": {
"val": 50,
"aboveBelow": "above"
}
}``````

Now, you will want to get the corresponding moving average function based on your strategy dictionary. This is done by using a for loop, looping over the keys in `movingAverages` and matching them with the `movingAverageFunctions` dictionary created in `constants`

``````        for m in moving_averages :
ma_func = constants.movingAveragesFunctions[m]``````

You will also need to extract the value from the current moving average as this is used by the moving average function:

``            val = moving_averages [m]['val']``

The last step is to run the function with the `close` price and the `val` and add it to the data frame. You will add the moving averages to the dataframe by the key from the `moving_averages` dictionary:

``            data[m] = maFunc(close, val)``

The beginning of your `check_trades` method should look like the following:

``````def check_trades(time_frame, pair_data, strategy):
moving_averages = strategy['movingAverages']
for pair, data in pair_data.items():
for m in moving_averages:
ma_func = constants.movingAveragesFunctions[m]
val = moving_averages [m]['val']
data[m] = ma_func(data['close'], val)``````

This code will get all the moving averages you want to calculate specified in the strategy, calculate them using the stored functions in `constants` and then add the results to the `data` dataframe with key as the column name.

## Implementing the strategy stop loss and take profit

Now that we have re-implemented our strategy for entering trades dynamically let’s see how we can add our stop loss and take profits dynamically.

Find the following line in your code:

``open_position(pair, "BUY", 1, 300, 100)``

300 is the current take profit and 100 is the current stop loss. You need to replace these values with the values from your strategy dictionary and make them a float:

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

The last step for creating a strategy for your algorithmic trading bot, is to load the strategy dynamically – You will be passing the strategy file as an argument to the script. But first, let’s implement some code that will take this argument and set it to a variable named `current_strategy`. You will be using` sys.argv[1]` to capture the input parameter.

Find the main entry point to your script. If you have been following this series, this is at the bottom of your `trader.py` file:

``````if __name__ == '__main__':

Start by using `sys.argv[1]` to capture the strategy file name and assign it to a variable named `current_strategy` then add some print statements to the beginning of the program to let you know what strategy is currently being run with the trader:

``````if __name__ == '__main__':
current_strategy = sys.argv[1]
print("Trading bot started with strategy: ", current_strategy)``````

From `strategy.py` you can now load the json file using the `load_strategy` method defined earlier:

``````if __name__ == '__main__':
current_strategy = sys.argv[1]
print("Trading bot started with strategy: ", current_strategy)

Now pass this into the `live_trading` method:

``````if __name__ == '__main__':
current_strategy = sys.argv[1]
print("Trading bot started with strategy: ", current_strategy)

Add an argument called `strategy` to the `live_trading` method and in the schedule code, pass this argument after `mt5.TIMEFRAME_M15`.

``````def live_trading(strategy):

Finally, add the same `strategy` argument to `run_trader` and pass this argument into the `get_data` and `check_trades` calls:

## Testing the code

Let’s try running our updated code passing in the strategy created from the previous post. As you can see below the trader ran with the strategy ‘strategy’ and also managed to find 2 trades and open them!

``````> python trader.py strategy
Trading bot started with strategy: strategy
Connected: Connecting to MT5 Client
EURUSD found!
Order successfully placed!
GBPUSD found!
Order successfully placed!``````

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 Friday to see how you can dynamically calculate your position size of a trade based on risk tolerance and account size! 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.

### 3 thoughts on “Creating a strategy for your algorithmic trading bot – Part 2”

1. I’m having an issue when I try to run it. After it “gets the data” and proceeds to check the data, it does nothing and loops back. It doesn’t open any trades.

from datetime import datetime, timedelta
import pandas as pd
import pytz
import schedule
import talib as ta
import time
import strategy
import constants
import sys

def connect(account):
account = int(account)
mt5.initialize()

if authorized:
print(“Connected: Connecting to MT5 Client”)
else:
print(“Failed to connect at account #{}, error code: {}”
.format(account, mt5.last_error()))

def open_position(pair, order_type, size, tp_distance=None, stop_distance=None):
symbol_info = mt5.symbol_info(pair)
if symbol_info is None:
return

if not symbol_info.visible:
print(pair, “is not visible, trying to switch on”)
if not mt5.symbol_select(pair, True):
print(“symbol_select({}}) failed, exit”,pair)
return
print(pair, “found!”)

point = symbol_info.point

if(stop_distance):
sl = price – (stop_distance * point)
if(tp_distance):
tp = price + (tp_distance * point)

if(order_type == “SELL”):
order = mt5.ORDER_TYPE_SELL
price = mt5.symbol_info_tick(pair).bid
if(stopDistance):
sl = price + (stop_distance * point)
if(tpDistance):
tp = price – (tp_distance * point)

request = {
“symbol”: pair,
“volume”: float(size),
“type”: order,
“price”: price,
“sl”: sl,
“tp”: tp,
“magic”: 234000,
“comment”: “”,
“type_time”: mt5.ORDER_TIME_GTC,
“type_filling”: mt5.ORDER_FILLING_IOC,
}

result = mt5.order_send(request)

print(“Failed to send order :(“)
else:
print (“Order successfully placed!”)

def positions_get(symbol=None):
if(symbol is None):
res = mt5.positions_get()
else:
res = mt5.positions_get(symbol=symbol)

if(res is not None and res != ()):
df = pd.DataFrame(list(res),columns=res[0]._asdict().keys())
df[‘time’] = pd.to_datetime(df[‘time’], unit=’s’)
return df

return pd.DataFrame()

def close_position(deal_id):
open_positions = positions_get()
open_positions = open_positions[open_positions[‘ticket’] == deal_id]
order_type = open_positions[“type”][0]
symbol = open_positions[‘symbol’][0]
volume = open_positions[‘volume’][0]

order_type = mt5.ORDER_TYPE_SELL
price = mt5.symbol_info_tick(symbol).bid
else:

close_request={
“symbol”: symbol,
“volume”: float(volume),
“type”: order_type,
“position”: deal_id,
“price”: price,
“magic”: 234000,
“type_time”: mt5.ORDER_TIME_GTC,
“type_filling”: mt5.ORDER_FILLING_IOC,
}

result = mt5.order_send(close_request)

print(“Failed to close order :(“)
else:
print (“Order successfully closed!”)

def close_positon_by_symbol(symbol):
open_positions = positions_get(symbol)
open_positions[‘ticket’].apply(lambda x: close_position(x))

def get_data(time_frame, strategy):
print(“Getting data now…”)
pairs = strategy[‘pairs’]
pair_data = dict()
for pair in pairs:
utc_from = datetime(2021, 1, 1, tzinfo=pytz.timezone(‘Europe/London’))
date_to = datetime.now().astimezone(pytz.timezone(‘Europe/London’))
date_to = datetime(date_to.year, date_to.month, date_to.day, hour=date_to.hour, minute=date_to.minute)
rates = mt5.copy_rates_range(pair, time_frame, utc_from, date_to)
rates_frame = pd.DataFrame(rates)
rates_frame[‘time’] = pd.to_datetime(rates_frame[‘time’], unit=’s’)
rates_frame.drop(rates_frame.tail(1).index, inplace = True)
pair_data[pair] = rates_frame
print(pair_data[pair])
return pair_data

moving_averages = strategy[‘movingAverages’]
for pair, data in pair_data.items():
for m in moving_averages:
ma_func = constants.movingAveragesFunctions[m]
val = moving_averages [m][‘val’]
data[m] = ma_func(data[‘close’], val)

last_row = data.tail(1)
open_positions = positions_get(pair)
#open_positions = positions_get()
#current_dt = datetime.now().astimezone(pytz.timezone(‘Europe/London’))
#for index, position in open_positions.iterrows():
# Check to see if the trade has exceeded the time limit
#deal_id = position[‘ticket’]
#if(current_dt – trade_open_dt >= timedelta(hours = 2)):

for index, last in last_row.iterrows():
#Exit strategy
if(last[‘close’] last[‘SMA’]):
close_positon_by_symbol(pair)

#Entry strategy
#if(last[‘close’] > last[‘EMA’] and last[‘close’] < last['SMA']):
open_position(pair, "BUY", 1, float (strategy['takeProfit']), float(strategy['stopLoss']))

connect(12345678)
pair_data = get_data(time_frame, strategy)

while True:
schedule.run_pending()
time.sleep(1)

if __name__ == '__main__':
#print(sys.argv)
#current_strategy = sys.argv[1]
print("C:\Python\Python39\Scripts\strategies\MyStrategy.json")
current_strategy = "MyStrategy"
print("Trading bot started with strategy: ", current_strategy)