For this blog, I will demonstrate how to plot Bollinger Bands using Plotly. Bollinger bands contain upper/lower bounds(±2 standard deviations) from the moving average of stock data. I will break down this tutorial blog into three steps:

**Obtain Data**

Use AlphaVantage for IBM historical data**Calculate Moving Averages and Standard Deviation**

Calculate the Moving Average, Upper Band, and Lower Band**Plot with Plotly**

Add layers on top of the candlestick plot

## Obtain Data

For the simplicity of this blog, I will use the demo version of the AlphaVantage API. AlphaVantage offers free API keys for stock data, and set-up is super easy. The demo API call will retrieve 100 data points(100 days from the present) for the IBM stock.

import requests

import json

import numpy as np

import pandas as pd# AlphaVantage Demo IBM API

url = 'https://www.alphavantage.co/query?function=TIME_SERIES_DAILY&symbol=IBM&apikey=demo'

response = requests.get(url)

# Load text to clean json object

json_load = json.loads(response.text)# 'Time Series (Daily)' consists the time stamps for the demo

df = pd.DataFrame(json_load['Time Series (Daily)']).T

# Rename column names & change datetime to pandas datetime

df.reset_index(inplace=True)

df.columns = ['datetime', 'open', 'high', 'low', 'close', 'volume']

df['datetime'] = pd.to_datetime(df['datetime'])

display(df)

## Calculate Moving Average and Standard Deviation

Bollinger Bands include a moving average with upper and lower bounds(±2 standard deviations) away from the running average. The moving average can be calculated using the Pandas helper function rolling with a set WINDOW size. For this blog, I will set WINDOW to 30.

It’s important to note, Bollinger Bands use the population method when calculating standard deviations, and therefore the denominator for the sigma calculation is n and not n -(minus) 1. When using the Pandas helper function, rolling with std, set degrees of freedom(ddof) to 0.

`WINDOW = 30`

df['sma'] = df['close'].rolling(WINDOW).mean()

df['std'] = df['close'].rolling(WINDOW).std(ddof = 0)

display(df)

With a window of 30, the first 29 observations for the moving average and standard deviations should be NULL due to the lack of data points prior to the beginning data points.

After feature engineering the moving averages and standard deviation, I have all I need to plot the Bollinger Bands. The Bollinger Bands consist of the moving average(center), with the upper and lower bounds being ± 2 standard deviations from the running average.

## Plot with Plotly

Plotting with plotly, matplotlib, folium, or other python visualization packages adds layers on a canvas. The code block below may seem overwhelming, but you can view it as a sequential canvas painting. First, create two canvases, one for candlesticks and one for volume. And for each canvas, build plots on top of each other.