Trading online has become one of the moat popular investment in the current world today. The likes of cryptocurrency and forex being the leading area. Due to this popularity, programmers have emerged trying to come with in which the trading process can be automated for more profits.
In this tutorial, we are to look at how one can start off his/her journey in programming a trading bot.
As stated in the introduction, a trading bot is simply a robot in form of a software that automates the trading process. It uses past data to give out expected outcomes that look down to the past data patterns. From these past patterns, it generates patterns expected in future.
The main prerequisite for this tutorial is the basic knowledge of python and its algorithms. For the matter of testing, we will use QUANTCONNECT which uses lean engine to integrate your code with the trading site. That means you don't actually require an offline editor since the site provides its own editor.
With your prerequisites and requirements ready, you can now code along for a practical understanding. Go to www.quantconnect.com and sign up to setup your coding environment. You can also use an offline editor and upload the code later for testing.
Let's get started...
We are going the develop it stepwise. Follow the steps below;
- Create a new Algorithm
From the options on the left side of the page, click Create new Algorithm as shown in the photo below, you will be taken to the editor with with a class generated automatically.

For my case, here is the class generated
class GeekyBlueSeahorse(QCAlgorithm):
def Initialize(self):
def OnData(self, data):
- Import required Library In this case, we will only require one library i.e. numpy.
Import at the top as follows;
import numpy as np
- Initialize required variables
Under the initialize method, we will initialize several parameters;
- Initialize cash for the purpose of the backtest(we call it the strategy cash) which would be used on a real account.
- Set the start and end date for the backtest. The code is as follows;
self.SetStartDate(2015, 3, 26) # Set Start Date
self.SetEndDate(2021, 9, 25) # Set End Date
self.SetCash(100000) # Set Strategy Cash-
Still under the initialize method, we will;
-
Use AddEquity function to monitor the resolution of the intended data.
-
Initialize the amount of days we will look back to determine our break point.
- Set limits for the lookback i.e a lower and an upper limit
In this case, we will use a daily resolution.
-
self.symbol = self.AddEquity("SPY", Resolution.Daily).Symbol
self.lookback = 20
self.ceiling, self.floor = 30, 10
- The last thing to initialize is the stop loss extent.
self.initialStopRisk = 0.98
self.trailingStopRisk = 0.9The first variable determines how close our stop loss will be to the security price meaning that it will allow a 2% loss before it gets hit.
The second variable indicates how close our trading stop will follow the assets' price. This means that it will trail the price for 10% which is quite big but it gives more room for price flexibility.
We will define the onData method to create a plot of the price of the securities. This gives a benchmark to compare our algorithm performance.
def OnData(self, data):
self.Plot("Data Chart", self.symbol, self.Securities[self.symbol].Close)
This will also determine the closing price.
The next step will be to create the method that will do all the trading for us which will be called after every market open. We will call it EveryMarketOpen for simplicity.
def EveryMarketOpen(self):For this, we will have to initialize one more function in the initialize method. This the Schedule.On function which takes three parameters
-
The first specifies on which day the method is called.
-
The second specifies at which time the method is called
-
The last specifies which method is called, in this case it's EveryMarketOpen method.
Add this to the initialize method;
self.Schedule.On(self.DateRules.EveryDay(self.symbol), \
self.TimeRules.AfterMarketOpen(self.symbol, 20), \
Action(self.EveryMarketOpen))First, we will determine the lookback length for our breakout.
Within a utility of 30 days we will compare the current value today with the same value yesterday.
This will help determine the length of the lookback window.
-
Call the History function to get data for the last 31 days or you prefered number of days.
-
This is where we use the numpy library to calculate the standard deviation for the two days.
-
We will list all the highest and lowest prices within a specified range, for this case, 30days
The following code falls under this EveryMarketOpen method to perform all the comparisons required to give a result;
def EveryMarketOpen(self):
close = self.History(self.symbol, 31, Resolution.Daily)["close"]
todayvol = np.std(close[1:31])
yesterdayvol = np.std(close[0:30])
deltavol = (todayvol - yesterdayvol) / (todayvol)
self.lookback = round(self.lookback * (1 + deltavol))
if self.lookback > self.ceiling:
self.lookback = self.ceiling
elif self.lookback < self.floor:
self.lookback = self.floor
self.high = self.History(self.symbol, self.lookback, Resolution.Minute)["high"]
if not self.Securities(self.Symbol).Invested and \
self.Securities(self.symbol).Close >= max(self.high[:-1]):
self.SetHoldings(self.symbol, 1)
self.breakoutlvl = max(selt.high[:-1])
self.highestPrice = self.breakoutlvl
if self.Securities(self.Symbol).Invested:
if not self.Transactions.GetOpenOrders(self.symbol):
self.StopMarketTicket = self.StopMarketOrder(self.symbol, \
-self.Portfolio[self.symbol].Quantity, \
self.initialStopRisk * self.breakoutlvl)
if not self.Securities(self.Symbol).Close > self.highestPrice and \
self.initialStopRisk * self.breakoutlvl < self.Securities[self.symbol].Close * self.trailingStopRisk:
self.highestPrice = self.Securities[self.symbol].Close
updateFields = UpdateOrderFields()
updateFields.stopPrice = self.Securities[self.symbol] * self.trailingStopRisk
self.stopMarketTicket.Update(updateFields)Lastly, print the new stock price to the console, to check the new order price every time they get updated. We cannot use the normal print function but instead use the self.Debug fuction which is quant equivalent to print. Finalize by plotting the stop price of our position onto the data chart we created earlier. This allows us to view where our stop price is compared to the securities trading price.
self.Debug(updateFields.stopPrice)
self.Plot("Data Chart", "Stop Price", self.stopMarketTicket.Get(OrderField.StopPrice))
Below is how the complete code looks like.
import numpy as np
class GeekyBlueSeahorse(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2015, 3, 26) # Set Start Date
self.SetEndDate(2021, 9, 25)
self.SetCash(100000) # Set Strategy Cash
self.symbol = self.AddEquity("SPY", Resolution.Daily).Symbol
self.lookback = 20
self.ceiling, self.floor = 30, 10
self.initialStopRisk = 0.98
self.trailingStopRisk = 0.9
self.Schedule.On(self.DateRules.EveryDay(self.symbol), \
self.TimeRules.AfterMarketOpen(self.symbol, 20), \
Action(self.EveryMarketOpen))
def OnData(self, data):
self.Plot("Data Chart", self.symbol, self.Securities[self.symbol].Close)
def EveryMarketOpen(self):
close = self.History(self.symbol, 31, Resolution.Daily)["close"]
todayvol = np.std(close[1:31])
yesterdayvol = np.std(close[0:30])
deltavol = (todayvol - yesterdayvol) / (todayvol)
self.lookback = round(self.lookback * (1 + deltavol))
if self.lookback > self.ceiling:
self.lookback = self.ceiling
elif self.lookback < self.floor:
self.lookback = self.floor
self.high = self.History(self.symbol, self.lookback, Resolution.Minute)["high"]
if not self.Securities(self.Symbol).Invested and \
self.Securities(self.symbol).Close >= max(self.high[:-1]):
self.SetHoldings(self.symbol, 1)
self.breakoutlvl = max(selt.high[:-1])
self.highestPrice = self.breakoutlvl
if self.Securities(self.Symbol).Invested:
if not self.Transactions.GetOpenOrders(self.symbol):
self.StopMarketTicket = self.StopMarketOrder(self.symbol, \
-self.Portfolio[self.symbol].Quantity, \
self.initialStopRisk * self.breakoutlvl)
if not self.Securities(self.Symbol).Close > self.highestPrice and \
self.initialStopRisk * self.breakoutlvl < self.Securities[self.symbol].Close * self.trailingStopRisk:
self.highestPrice = self.Securities[self.symbol].Close
updateFields = UpdateOrderFields()
updateFields.stopPrice = self.Securities[self.symbol] * self.trailingStopRisk
self.stopMarketTicket.Update(updateFields)
self.Debug(updateFields.stopPrice)
self.Plot("Data Chart", "Stop Price", self.stopMarketTicket.Get(OrderField.StopPrice))
For more explanations or inconviniences, you can refer to this video for more understanding.
A back test is performed to evaluate the performance of the algorithm.
It integrates the code with your brokerage site to get results as if it was an actual trading practice.
You can see the picture below;
According to the values you entered, you should get your results in a similar interface like the one shown in the photo below.
Here are some of the key merits of this algorithmic trading;
- Saves on time since a trader does not need to sit there all day doing the trade.
This allows one to work on other things while earning at the same time.
- Higher accuracy expected since the bot compares and consider a large volume of data before coming up with a prediction.
This is an added bonus since a trader cannot go through a data of upto or maybe more than a year.
- Increased trading time - Most probably, the bot can trade for 24hrs in a day without getting tired.
This means that if it's accuracy is higher enough, then the profits made are higher that human guided trading.
Besides giving better results, some people are still against this type of trading. This is the one Main reason;
Systemic Risk
Sometimes, there occur linkages between financial markets. As a result, algorithms operating under those markets transmit rapid shocks from one market to another thus triggering a systematic risk. These systematic risks bring about huge losses, which is considered a great risk.
Due to such risk, people prefer to trade on their own rather than depending on the software.
With the growing E-economy, e-trading has become one of the biggest contributors. Giving a verdict on whether to use an automated software(Trading bot) or not is always a personal decision.
This article sets a journey for those who are interested in developing their own algorithm for trading rather than using the ready-made.

