Matt Cullen-Meyer | May 25, 2020
The following Python script is used to automatically export stock prices for a given company and compute its historical volatility over 12 months. The volatility calculations are especially helpful when compared to the implied volatility of a stock option, which can indicate whether that option is over- or under-valued. The script concludes with instructions on how to visualize the historical distribution of returns with a histogram plot.
You will first need to import the necessary Python libraries for this exercise. The yahoofinancials library automatically exports historical stock prices without requiring you to do any of the web scraping yourself. The datetime import is necessary for setting the start and end dates used in exporting stock prices over a specific time range. The pandas and numpy python libraries are indispensable whenever you're doing data analysis or scientific computing, respectively. Lastly, matplotlib is a plotting library that makes it very easy to create data visualizations in Python, though not necessarily the most elegant option (for that I would recommend bokeh).
from yahoofinancials import YahooFinancials from datetime import date, timedelta import pandas as pd import numpy as np import matplotlib.pyplot as plt
After importing Python libraries, the next step is to export historical stock prices. I will use Apple Inc (AAPL) as an illustrative example here, but you can easily change the stock_symbol to the ticker of your choice. We're interested in historical price volatility over the last twelve months, therefore the start_time is set to 365 days ago. The yahoofinancials library requires dates to be in the format of 'year-month-day', hence the reformatting. Historical stock price data is pulled by 'daily', 'weekly' or 'monthly' time intervals through the yahoofinancials module.
# set stock ticker symbol stock_symbol = 'AAPL' # set date range for historical prices end_time = date.today() start_time = end_time - timedelta(days=365) # reformat date range end = end_time.strftime('%Y-%m-%d') start = start_time.strftime('%Y-%m-%d') # get daily stock prices over date range json_prices = YahooFinancials(stock_symbol ).get_historical_price_data(start, end, 'daily')
Stock prices are returned through yahoofinanicals in the JSON format, which is not particularly conducive to data analysis. For that we will use a pandas DataFrame in Python. The JSON file contains a lot of data, but we're just interested in historical 'prices' for this exercise, specifically the daily price at market 'close' (and of course the trading date, indicated by the 'formatted_date' field). I then sort the prices in descending order to more easily calculate daily stock returns in the next step.
# transform json file to dataframe prices = pd.DataFrame(json_prices[stock_symbol] ['prices'])[['formatted_date', 'close']] # sort dates in descending order prices.sort_index(ascending=False, inplace=True)
Now that the historical stock prices are sorted in descending order, we can next calculate the daily stock returns. This is accomplished by taking the natural log of each day's closing stock price divided by the previous day's closing stock price. The numpy library is then used to calculate the standard deviation of daily price returns. In order to calculate annualized volatility, we multiply the daily standard deviation by the square root of 252, which is the approximate number of trading days in a year.
# calculate daily logarithmic return prices['returns'] = (np.log(prices.close / prices.close.shift(-1))) # calculate daily standard deviation of returns daily_std = np.std(prices.returns) # annualized daily standard deviation std = daily_std * 252 ** 0.5
The only thing left to do at this point is to visualize the distribution of daily stock returns over the past year through a histogram chart. I use the matplotlib library to do this, though it's pretty bare bones in all honesty. I recommend using a library like bokeh if you want to create more stunning visualizations.
# Plot histograms fig, ax = plt.subplots(1, 1, figsize=(7, 5)) n, bins, patches = ax.hist( prices.returns.values, bins=50, alpha=0.65, color='blue') ax.set_xlabel('log return of stock price') ax.set_ylabel('frequency of log return') ax.set_title('Historical Volatility for ' + stock_symbol) # get x and y coordinate limits x_corr = ax.get_xlim() y_corr = ax.get_ylim() # make room for text header = y_corr / 5 y_corr = (y_corr, y_corr + header) ax.set_ylim(y_corr, y_corr) # print historical volatility on plot x = x_corr + (x_corr - x_corr) / 30 y = y_corr - (y_corr - y_corr) / 15 ax.text(x, y , 'Annualized Volatility: ' + str(np.round(std*100, 1))+'%', fontsize=11, fontweight='bold') x = x_corr + (x_corr - x_corr) / 15 y -= (y_corr - y_corr) / 20 # save histogram plot of historical price volatility fig.tight_layout() fig.savefig('historical volatility.png')
No comments yet — be the first to leave one!