Last active
May 7, 2018 00:14
-
-
Save ksindi/ea0c3b7801d41ac265b8ea93f0230dd8 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
get_ipython().magic('matplotlib inline') | |
import datetime | |
import numpy as np | |
import pandas as pd | |
import seaborn as sns | |
import pandas_datareader.data as web | |
sns.set() | |
# https://stackoverflow.com/questions/39501277/efficient-python-pandas-stock-beta-calculation-on-many-dataframes | |
def roll(df, w): | |
# stack df.values w-times shifted once at each stack | |
roll_array = np.dstack([df.values[i:i+w, :] for i in range(len(df.index) - w + 1)]).T | |
# roll_array is now a 3-D array and can be read into | |
# a pandas panel object | |
panel = pd.Panel(roll_array, | |
items=df.index[w-1:], | |
major_axis=df.columns, | |
minor_axis=pd.Index(range(w), name='roll')) | |
# convert to dataframe and pivot + groupby | |
# is now ready for any action normally performed | |
# on a groupby object | |
return panel.to_frame().unstack().T.groupby(level=0) | |
def beta(df, market=None): | |
# If the market values are not passed, | |
# I'll assume they are located in a column | |
# named 'Market'. If not, this will fail. | |
if market is None: | |
market = df['Market'] | |
df = df.drop('Market', axis=1) | |
X = market.values.reshape(-1, 1) | |
X = np.concatenate([np.ones_like(X), X], axis=1) | |
b = np.linalg.pinv(X.T.dot(X)).dot(X.T).dot(df.values) | |
return pd.Series(b[1], df.columns, name=df.index[-1]) | |
tickers = ['DAL', 'AAL', 'UAL', 'LUV', 'ALK', 'JBLU'] | |
start = datetime.datetime(1990, 1, 1) | |
end = datetime.date.today() | |
data = web.DataReader(['0p00001g7j'] + tickers, 'morningstar', start, end) | |
close = data.Close.unstack().T | |
close.columns = ['Market'] + tickers | |
monthly = close.resample('1M').last() | |
monthly = monthly[['Market', 'AAL', 'DAL']] | |
# calculate beta of 36 months years | |
betas = roll(monthly.pct_change().dropna(), w=36).apply(beta) | |
# clip beta at 2 | |
betas.clip(0, 2).plot(figsize=(12, 8), title='Beta of major airlines') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment