Algorithmic Trading with Bollinger Bands in Python
An automated way to trade stocks with Bollinger Bands in Python
Disclaimer: This article is strictly for educational purposes and should not be taken as an investment tip.
This is the second article of my algorithmic trading series (view the first article). In the first article, we discussed what algorithmic trading is and learned a stock technical indicator Simple Moving Average (SMA) and how to apply it in python to trade stocks. In this article, we are going to learn a new technical indicator Bollinger Bands and how it can be used to create trading strategies in python. Buckle up your seatbelts for a wonderful ride!
Before that, just a note on what algorithmic trading is. Algorithmic trading is the process of enabling computers to trade stocks under certain conditions or rules. A trade will be performed by the computer automatically when the given condition gets satisfied. Also, these conditions are nothing but trading strategies given to the computers by human traders.
Before moving on, if you want to backtest your trading strategies without any coding, there is a solution for it. It is BacktestZone. It is a platform to backtest any number of trading strategies on different types of tradeable assets for free without coding. You can use the tool right away using the link here: https://www.backtestzone.com/
Before jumping on to explore Bollinger Bands, it is essential to know what Simple Moving Average (SMA) is. Simple Moving Average is nothing but the average price of a stock given a specified period of time. Now, Bollinger Bands are trend lines plotted above and below the SMA of the given stock at a specific standard deviation level. To understand Bollinger Bands better, have a look at the following chart that represents the Bollinger Bands of the Tesla stock calculated with SMA 20
Bollinger Bands are great to observe the volatility of a given stock over a period of time. The volatility of a stock is observed to be lower when the space or distance between the upper and lower band is less. Similarly, when the space or distance between the upper and lower band is more, the stock has a higher level of volatility. While observing the chart, you can observe a trend line named ‘MIDDLE BB 20’ which is nothing but SMA 20 of the Tesla stock. The formula to calculate both upper and lowers bands of stock are as follows:
UPPER_BB = STOCK SMA + SMA STANDARD DEVIATION * 2
LOWER_BB = STOCK SMA - SMA STANDARD DEVIATION * 2
Now that we have an understanding of what Bollinger Bands is, so let’s gain some intuitions on the trading strategy we are going to build using Bollinger Bands.
About the trading strategy: We are going to implement a basic trading strategy using the Bollinger Bands indicator which will shoot a buy signal if the stock price of the previous day is greater than the previous day's lower band and the current stock price is lesser than the current day’s lower band. Similarly, if the stock price of the previous day is lesser than the previous day’s upper band and the current stock price is greater than the current day’s upper band, the strategy will reveal a sell signal. Our Bollinger Bands trading strategy can be represented as follows:
IF PREV_STOCK > PREV_LOWERBB & CUR_STOCK < CUR_LOWER_BB => BUY
IF PREV_STOCK < PREV_UPPERBB & CUR_STOCK > CUR_UPPER_BB => SELL
Now that we have an understanding of our Bollinger Bands trading strategy. So, let’s move ahead to build and implement it in python.
Implementation in Python
We are going to implement the trading strategy which we discussed earlier in python to see how well it works in the real world.
Before coding our trading strategy, it is essential to import the required packages into our python environment. The primary packages are going to be Pandas for data manipulation, Matplotlib for plotting purposes, and NumPy for calculations. The additional packages will be Math for mathematical functions, Requests for pulling stock data from API, and Termcolor for font customization.
We have imported all the required packages into our python environment. Now let’s extract the historical data of Tesla (TSLA) from IEX Cloud. Before moving on, if you don’t know what is IEX Cloud and how to pull data from it, I highly recommend you to view my article on it (click here to view the article). Let’s pull some data!
Extracting data from IEX Cloud
In this step, we are going to pull the historic data of Tesla using an API provided by IEX Cloud.
Code Explanation: First we are defining a function named ‘get_historic_data’ that takes a stock’s ticker (‘symbol’) as the parameter. Inside the function, we are storing the API key and the URL into their respective variables, and then using the ‘GET’ method provided by the Request package, we are extracting the data in a JSON format. Next, we are doing some data manipulation tasks to clean and make the data usable. Finally, we are returning the dataframe. After finished defining the function, we are calling it and stored the data into the ‘tsla’ variable. Now, let’s calculate the Bollinger Bands values out of the extracted data.
Bollinger Bands calculation
This is step is further divided into two parts. The first part is to calculate the SMA values and the second is to calculate the Bollinger Bands.
Calculating SMA values: In this part, we are going to calculate the SMA values of Tesla with the number of periods as 20.
Code Explanation: Firstly, we are defining a function named ‘sma’ that takes the stock prices (‘data’), and the number of periods (‘window’) as the parameters. Inside the function, we are using the ‘rolling’ function provided by the Pandas package to calculate the SMA for the given number of periods. We are storing the calculated values into the ‘sma’ variable and returned it. Next, we are calling the function and calculated SMA values with the number of periods as 20. Now, let’s calculate the Bollinger Bands.
Calculating Bollinger Bands: In this part, we are going to calculate the Bollinger Bands values of Tesla using the SMA values which we have created earlier.
Code Explanation: Firstly, we are defining a function named ‘bb’ that takes the stock prices (‘data’), SMA values (‘sma’), and the number of periods as parameters (‘window’). Inside the function, we are using the ‘rolling’ and the ‘std’ function to calculate the standard deviation of the given stock data and stored the calculated standard deviation values into the ‘std’ variable. Next, we are calculating Bollinger Bands values using their respective formulas, and finally, we are returning the calculated values. We are storing the Bollinger Bands values into our ‘tsla’ dataframe using the created ‘bb’ function.
Plotting Bollinger Bands values
In this step, we are going to plot the calculated Bollinger Bands values to make more sense out of them.
Code Explanation: Using the ‘plot’ function provided by the Matplotlib package, we have plotted the Bollinger Band values along with the ‘close’ prices of Tesla. Now let’s observe the graph. The light blue line represents the ‘close’ prices of Tesla, and the black dotted line represents the lower and upper bands. Similarly, the grey dotted line represents the middle band or the SMA 20 values of Tesla. We can also observe that the spaces between the upper and lower bands are becoming narrow or wider at different times representing the volatility of the stock (
wider == high volatility and vice-versa).
Creating the Trading Strategy
In this step, we are going to implement the discussed Bollinger Bands trading strategy in python.
Code Explanation: First, we are defining a function named ‘implement_bb_strategy’ which takes the stock prices (‘data’), lower band values (‘lower_bb’), and upper band values (‘upper_bb’) as parameters.
Inside the function, we are creating three empty lists (buy_price, sell_price, and bb_signal) in which the values will be appended while creating the trading strategy.
After that, we are implementing the trading strategy through a for-loop. Inside the for-loop, we are passing certain conditions, and if the conditions are satisfied, the respective values will be appended to the empty lists. If the condition to buy the stock gets satisfied, the buying price will be appended to the ‘buy_price’ list, and the signal value will be appended as 1 representing to buy the stock. Similarly, if the condition to sell the stock gets satisfied, the selling price will be appended to the ‘sell_price’ list, and the signal value will be appended as -1 representing to sell the stock.
Finally, we are returning the lists appended with values. Then, we are calling the created function and stored the values into their respective variables. The list doesn’t make any sense unless we plot the values. So, let’s plot the values of the created trading lists.
Plotting the Trading lists
In this step, we are going to plot the created trading lists to make sense out of them.
Code Explanation: We are plotting the Bollinger Bands values along with the buy and sell signals generated by the trading strategy. We can observe that whenever the stock’s close price (light blue line) below the lower band (lower black dotted line), a buy signal is plotted in green color, similarly, whenever the stock’s close price crosses above the upper band (upper black dotted line), a sell signal is plotted in red color.
Now, using the trading signals, let’s create our position on the stock.
Creating our Position
In this step, we are going to create a list that indicates 1 if we hold the stock or 0 if we don’t own or hold the stock.
Code Explanation: First, we are creating an empty list named ‘position’. We are passing two for-loops, one is to generate values for the ‘position’ list to just match the length of the ‘signal’ list. The other for-loop is the one we are using to generate actual position values. Inside the second for-loop, we are iterating over the values of the ‘signal’ list, and the values of the ‘position’ list get appended concerning which condition gets satisfied. The value of the position remains 1 if we hold the stock or remains 0 if we sold or don’t own the stock. Finally, we are doing some data manipulations to combine all the created lists into one dataframe.
From the output being shown, we can see that from row 318–320, our position in the stock has remained 1 (since there isn’t any change in the Bollinger Bands signal) but our position suddenly turned to 0 as we sold the stock when the Bollinger Bands trading signal represents a sell signal (-1).
Now it’s time to do implement some backtesting process!
Before moving on, it is essential to know what backtesting is. Backtesting is the process of seeing how well our trading strategy has performed on the given stock data. In our case, we are going to implement a backtesting process for our Bollinger Bands trading strategy over the Tesla stock data.
Profit gained from the BB strategy by investing $100k in TSLA : 18426.42
Profit percentage of the BB strategy : 18%
Code Explanation: First, we are calculating the returns of the Tesla stock using the ‘diff’ function provided by the NumPy package and we have stored it as a dataframe into the ‘tsla_ret’ variable. Next, we are passing a for-loop to iterate over the values of the ‘tsla_ret’ variable to calculate the returns we gained from our Bollinger Bands trading strategy, and these returns values are appended to the ‘bb_strategy_ret’ list. Next, we are converting the ‘bb_strategy_ret’ list into a dataframe and stored it into the ‘bb_strategy_ret_df’ variable.
Next comes the backtesting process. We are going to backtest our strategy by investing a hundred thousand USD into our trading strategy. So first, we are storing the amount of investment into the ‘investment_value’ variable. After that, we are calculating the number of Tesla stocks we can buy using the investment amount. You can notice that I’ve used the ‘floor’ function provided by the Math package because, while dividing the investment amount by the closing price of Tesla stock, it spits out an output with decimal numbers. The number of stocks should be an integer but not a decimal number. Using the ‘floor’ function, we can cut out the decimals. Remember that the ‘floor’ function is way more complex than the ‘round’ function. Then, we are passing a for-loop to find the investment returns followed by some data manipulations tasks.
Finally, we are printing the total return we got by investing a hundred thousand into our trading strategy and it is revealed that we have made an approximate profit of eighteen thousand and five hundred USD in one year. That’s not bad! Now, let’s compare our returns with SPY ETF (an ETF designed to track the S&P 500 stock market index) returns.
SPY ETF Comparison
This step is optional but it is highly recommended as we can get an idea of how well our trading strategy performs against a benchmark (SPY ETF). In this step, we are going to extract the data of the SPY ETF using the ‘get_historic_data’ function we created and compare the returns we get from the SPY ETF with our Bollinger Bands strategy returns on Tesla.
Benchmark profit by investing $100k : 13270.5
Benchmark Profit percentage : 13%
BB Strategy profit is 5% higher than the Benchmark Profit
Code Explanation: The code used in this step is almost similar to the one used in the previous backtesting step but, instead of investing in Tesla, we are investing in SPY ETF by not implementing any trading strategies. From the output, we can see that our Bollinger Bands trading strategy has outperformed the SPY ETF by 5%. That’s great!
In this article, we learned a new stock technical indicator which is Bollinger Bands and the ways to implement and backtest a Bollinger Bands trading strategy in python. The trading strategy we implemented in this article is a basic one but, there are a lot of trading strategies based on Bollinger Bands to be applied. It is believed that Bollinger Bands are not that good for algorithmic trading but they can be effective with the right trading strategy. There are also several ways to improve this article which are:
- Picking stocks: In this article, we randomly chose Tesla but, it isn’t a wise decision to make in the real world. Instead, Machine Learning algorithms can be applied to pick the right tradable stocks. This step is a really important part of algorithmic trading in the real world and in case, the stocks are randomly chosen, the results would be catastrophic.
- Strategy improvement: As I said before, the trading strategy we used in this article is an elementary-level strategy and it would not perform exceptionally when applied in the real world. So, it is highly recommended to discover more Bollinger Bands strategies and implement them in python.
That’s it! If you forgot to follow any of the coding parts, don’t worry! I’ve provided the full source code of this article at the end. Hope you got some idea on Bollinger Bands out of this article.