In [322]:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import plotly.graph_objs as go
import plotly.plotly as py
sns.set_style('whitegrid')
import cufflinks as cf
import datetime
import quandl
from pandas_datareader import data, wb

from scipy import stats
%matplotlib inline
In [323]:
py.sign_in("dattatele","93reCjIosFgiul4JuaIb")
In [324]:
# Widget related imports
from ipywidgets import interactive
from IPython.display import Audio, display
import ipywidgets as widgets
from IPython.display import display, clear_output, Javascript
from traitlets import Unicode

# nbconvert related imports
from nbconvert import get_export_names, export_by_name
from nbconvert.writers import FilesWriter
from nbformat import read, NO_CONVERT
from nbconvert.utils.exceptions import ConversionException
In [325]:
import pandas_datareader as web
In [326]:
notebook_name = widgets.Text()
In [327]:
js = """IPython.notebook.kernel.widget_manager.get_model('%s').then(function(model) {
      model.set('value', IPython.notebook.notebook_name);
    model.save();
});
""" % notebook_name.model_id
display(Javascript(data=js))
In [328]:
filename = notebook_name.value
filename
Out[328]:
'JPM_&_COF_Financial_analysis.ipynb'
In [329]:
exporter_names = widgets.Dropdown(options=get_export_names(), value='html')
export_button = widgets.Button(description="Export")
download_link = widgets.HTML(visible=False)
In [330]:
quandl.ApiConfig.api_key = 'ygw7cuU2fx8t7pgxAtcm'
In [331]:
cof = quandl.get_table('WIKI/PRICES', ticker = 'COF', date = { 'gte': '2007-08-07', 'lte': '2017-08-07' })
In [332]:
cof['date'] = pd.to_datetime(cof['date'])
In [333]:
cof.set_index('date',inplace=True)
In [334]:
cof.head()
Out[334]:
ticker open high low close volume ex-dividend split_ratio adj_open adj_high adj_low adj_close adj_volume
date
2007-08-07 COF 69.17 71.54 68.49 70.61 5236700.0 0.000000 1.0 58.642829 60.652132 58.066320 59.863671 5236700.0
2007-08-08 COF 70.61 73.79 70.23 71.59 6241200.0 0.026667 1.0 59.885970 62.583002 59.563684 60.717131 6241200.0
2007-08-09 COF 69.09 71.44 67.81 68.00 7182100.0 0.000000 1.0 58.596823 60.589913 57.511226 57.672369 7182100.0
2007-08-10 COF 67.09 69.33 66.30 69.10 5143800.0 0.000000 1.0 56.900577 58.800373 56.230560 58.605305 5143800.0
2007-08-13 COF 70.11 70.79 68.10 68.47 3552400.0 0.000000 1.0 59.461909 60.038633 57.757182 58.070987 3552400.0
In [335]:
jpm = quandl.get_table('WIKI/PRICES', ticker = ['JPM'], date = { 'gte': '2007-08-07', 'lte': '2017-08-07' })
In [336]:
jpm['date'] = pd.to_datetime(jpm['date'])
In [337]:
jpm.set_index('date',inplace=True)
In [338]:
jpm.head()
Out[338]:
ticker open high low close volume ex-dividend split_ratio adj_open adj_high adj_low adj_close adj_volume
date
2007-08-07 JPM 44.99 46.05 44.15 45.34 30556500.0 0.0 1.0 35.320354 36.152529 34.660894 35.595129 30556500.0
2007-08-08 JPM 45.75 47.23 45.27 46.51 27447200.0 0.0 1.0 35.917008 37.078913 35.540174 36.513662 27447200.0
2007-08-09 JPM 45.04 45.94 44.17 44.17 39278200.0 0.0 1.0 35.359607 36.066172 34.676596 34.676596 39278200.0
2007-08-10 JPM 43.36 44.80 42.51 44.25 32549000.0 0.0 1.0 34.040688 35.171190 33.373377 34.739401 32549000.0
2007-08-13 JPM 45.23 45.43 43.68 43.83 21357600.0 0.0 1.0 35.508771 35.665785 34.291911 34.409671 21357600.0
In [339]:
tickers = ['JPM', 'COF']
In [340]:
bank_stocks = pd.concat([cof, jpm],axis=1,keys=tickers)
In [341]:
bank_stocks.head()
Out[341]:
JPM ... COF
ticker open high low close volume ex-dividend split_ratio adj_open adj_high ... low close volume ex-dividend split_ratio adj_open adj_high adj_low adj_close adj_volume
date
2007-08-07 COF 69.17 71.54 68.49 70.61 5236700.0 0.000000 1.0 58.642829 60.652132 ... 44.15 45.34 30556500.0 0.0 1.0 35.320354 36.152529 34.660894 35.595129 30556500.0
2007-08-08 COF 70.61 73.79 70.23 71.59 6241200.0 0.026667 1.0 59.885970 62.583002 ... 45.27 46.51 27447200.0 0.0 1.0 35.917008 37.078913 35.540174 36.513662 27447200.0
2007-08-09 COF 69.09 71.44 67.81 68.00 7182100.0 0.000000 1.0 58.596823 60.589913 ... 44.17 44.17 39278200.0 0.0 1.0 35.359607 36.066172 34.676596 34.676596 39278200.0
2007-08-10 COF 67.09 69.33 66.30 69.10 5143800.0 0.000000 1.0 56.900577 58.800373 ... 42.51 44.25 32549000.0 0.0 1.0 34.040688 35.171190 33.373377 34.739401 32549000.0
2007-08-13 COF 70.11 70.79 68.10 68.47 3552400.0 0.000000 1.0 59.461909 60.038633 ... 43.68 43.83 21357600.0 0.0 1.0 35.508771 35.665785 34.291911 34.409671 21357600.0

5 rows × 26 columns

In [342]:
bank_stocks.columns.names = ['Bank Ticker','Stock Info']
In [343]:
bank_stocks.head()
Out[343]:
Bank Ticker JPM ... COF
Stock Info ticker open high low close volume ex-dividend split_ratio adj_open adj_high ... low close volume ex-dividend split_ratio adj_open adj_high adj_low adj_close adj_volume
date
2007-08-07 COF 69.17 71.54 68.49 70.61 5236700.0 0.000000 1.0 58.642829 60.652132 ... 44.15 45.34 30556500.0 0.0 1.0 35.320354 36.152529 34.660894 35.595129 30556500.0
2007-08-08 COF 70.61 73.79 70.23 71.59 6241200.0 0.026667 1.0 59.885970 62.583002 ... 45.27 46.51 27447200.0 0.0 1.0 35.917008 37.078913 35.540174 36.513662 27447200.0
2007-08-09 COF 69.09 71.44 67.81 68.00 7182100.0 0.000000 1.0 58.596823 60.589913 ... 44.17 44.17 39278200.0 0.0 1.0 35.359607 36.066172 34.676596 34.676596 39278200.0
2007-08-10 COF 67.09 69.33 66.30 69.10 5143800.0 0.000000 1.0 56.900577 58.800373 ... 42.51 44.25 32549000.0 0.0 1.0 34.040688 35.171190 33.373377 34.739401 32549000.0
2007-08-13 COF 70.11 70.79 68.10 68.47 3552400.0 0.000000 1.0 59.461909 60.038633 ... 43.68 43.83 21357600.0 0.0 1.0 35.508771 35.665785 34.291911 34.409671 21357600.0

5 rows × 26 columns

In [344]:
bank_stocks.xs(key='close',axis=1,level='Stock Info').max()
Out[344]:
Bank Ticker
JPM    96.12
COF    94.02
dtype: float64
In [345]:
bank_stocks['JPM'].max()
Out[345]:
Stock Info
ticker                 COF
open                 96.21
high                 96.92
low                  94.81
close                96.12
volume         1.14574e+08
ex-dividend            0.4
split_ratio              1
adj_open           95.2817
adj_high           95.9849
adj_low            93.8952
adj_close          95.1926
adj_volume     1.14574e+08
dtype: object
In [346]:
returns = pd.DataFrame()
In [347]:
for tick in tickers:
    returns[tick+' Return'] = bank_stocks[tick]['close'].pct_change()
returns.head()
Out[347]:
JPM Return COF Return
date
2007-08-07 NaN NaN
2007-08-08 0.013879 0.025805
2007-08-09 -0.050147 -0.050312
2007-08-10 0.016176 0.001811
2007-08-13 -0.009117 -0.009492
In [348]:
sns.pairplot(returns[1:],size=3.5)
Out[348]:
<seaborn.axisgrid.PairGrid at 0x29299025a90>
In [349]:
returns.min()
Out[349]:
JPM Return   -0.250420
COF Return   -0.207274
dtype: float64
In [350]:
returns.idxmin()
Out[350]:
JPM Return   2009-04-20
COF Return   2009-01-20
dtype: datetime64[ns]
In [351]:
returns.idxmax()
Out[351]:
JPM Return   2009-04-09
COF Return   2009-01-21
dtype: datetime64[ns]
In [352]:
returns.std()
Out[352]:
JPM Return    0.032124
COF Return    0.027832
dtype: float64
In [353]:
for tick in tickers:
    bank_stocks[tick]['close'].plot(figsize=(16,6),label=tick)
plt.legend(loc=2)
Out[353]:
<matplotlib.legend.Legend at 0x2929a4cf860>
In [354]:
bank_stocks.xs(key='close',axis=1,level='Stock Info').iplot()
Out[354]:
In [355]:
plt.figure(figsize=(16,6))
cof['close'].loc['2008-01-01':'2010-01-01'].rolling(window=30).mean().plot(label='30 Day Avg')
cof['close'].loc['2008-01-01':'2010-01-01'].plot(label='COF CLOSE')
plt.legend()
Out[355]:
<matplotlib.legend.Legend at 0x2929a444f60>
In [356]:
plt.figure(figsize=(16,6))
jpm['close'].loc['2008-01-01':'2010-01-01'].rolling(window=30).mean().plot(label='30 Day Avg')
jpm['close'].loc['2008-01-01':'2010-01-01'].plot(label='JPM CLOSE')
plt.legend()
Out[356]:
<matplotlib.legend.Legend at 0x2929a950f98>
In [357]:
plt.figure(figsize=(16,6))
cof['close'].loc['2016-01-01':'2017-07-07'].rolling(window=30).mean().plot(label='30 Day Avg')
cof['close'].loc['2016-01-01':'2017-07-07'].plot(label='COF CLOSE')
plt.legend()
Out[357]:
<matplotlib.legend.Legend at 0x2929a9d84e0>
In [358]:
plt.figure(figsize=(16,6))
jpm['close'].loc['2016-01-01':'2017-07-07'].rolling(window=30).mean().plot(label='30 Day Avg')
jpm['close'].loc['2016-01-01':'2017-07-07'].plot(label='JPM CLOSE')
plt.legend()
Out[358]:
<matplotlib.legend.Legend at 0x2929a9ebe80>
In [359]:
cof[['open', 'high', 'low', 'close']].loc['2016-01-01':'2017-07-07'].iplot(kind='candle')
Out[359]:
In [360]:
cof['close'].loc['2016-01-01':'2017-07-017'].ta_plot(study='sma',title='Simple Moving Averages')
Out[360]:
In [361]:
cof['close'].loc['2016-01-01':'2017-07-07'].ta_plot(study='boll')
Out[361]:
In [362]:
jpm['close'].loc['2016-01-01':'2017-07-07'].ta_plot(study='boll')
Out[362]:
In [363]:
jpm['close'].resample('M').mean().plot(kind='bar', figsize=(16,6))
Out[363]:
<matplotlib.axes._subplots.AxesSubplot at 0x29296821cf8>
In [364]:
cof['close'].resample('M').mean().plot(kind='bar', figsize=(16,6))
Out[364]:
<matplotlib.axes._subplots.AxesSubplot at 0x2929ada5e10>
In [365]:
bank_stocks[['JPM', 'COF']].expanding().mean().plot(figsize=(16,6))
Out[365]:
<matplotlib.axes._subplots.AxesSubplot at 0x2929c1e1128>
In [366]:
bank_stocks[['JPM', 'COF']].expanding().mean().iplot()
The draw time for this plot will be slow for clients without much RAM.
C:\Anaconda3\lib\site-packages\plotly\api\v1\clientresp.py:40: UserWarning:

Estimated Draw Time Slow

Out[366]:
In [367]:
jpm['First Difference'] = jpm['open'] - jpm['open'].shift(1)
In [368]:
jpm['First Difference'].plot(figsize=(16,6))
Out[368]:
<matplotlib.axes._subplots.AxesSubplot at 0x2929c761630>
In [369]:
cof['First Difference'] = cof['open'] - cof['open'].shift(1)
In [370]:
cof['First Difference'].plot(figsize=(16,6))
Out[370]:
<matplotlib.axes._subplots.AxesSubplot at 0x2929c96f1d0>
In [371]:
# Normalized return - like Cumulative daily return 
for stock_df in (cof,jpm):
    stock_df['Normed Return'] = stock_df['adj_close'] / stock_df.iloc[0]['adj_close']
In [372]:
cof.head()
Out[372]:
ticker open high low close volume ex-dividend split_ratio adj_open adj_high adj_low adj_close adj_volume First Difference Normed Return
date
2007-08-07 COF 69.17 71.54 68.49 70.61 5236700.0 0.000000 1.0 58.642829 60.652132 58.066320 59.863671 5236700.0 NaN 1.000000
2007-08-08 COF 70.61 73.79 70.23 71.59 6241200.0 0.026667 1.0 59.885970 62.583002 59.563684 60.717131 6241200.0 1.44 1.014257
2007-08-09 COF 69.09 71.44 67.81 68.00 7182100.0 0.000000 1.0 58.596823 60.589913 57.511226 57.672369 7182100.0 -1.52 0.963395
2007-08-10 COF 67.09 69.33 66.30 69.10 5143800.0 0.000000 1.0 56.900577 58.800373 56.230560 58.605305 5143800.0 -2.00 0.978979
2007-08-13 COF 70.11 70.79 68.10 68.47 3552400.0 0.000000 1.0 59.461909 60.038633 57.757182 58.070987 3552400.0 3.02 0.970054
In [373]:
cof.tail()
Out[373]:
ticker open high low close volume ex-dividend split_ratio adj_open adj_high adj_low adj_close adj_volume First Difference Normed Return
date
2017-08-01 COF 86.64 86.7300 85.64 86.01 1674120.0 0.0 1.0 86.232234 86.321811 85.236941 85.605199 1674120.0 1.22 1.430002
2017-08-02 COF 85.85 86.0200 85.38 85.71 2696282.0 0.0 1.0 85.445952 85.615152 84.978164 85.306611 2696282.0 -0.79 1.425015
2017-08-03 COF 85.31 85.6300 84.49 84.59 2208385.0 0.4 1.0 85.310000 85.630000 84.490000 84.590000 2208385.0 -0.54 1.413044
2017-08-04 COF 85.33 85.4199 84.26 84.41 2618921.0 0.0 1.0 85.330000 85.419900 84.260000 84.410000 2618921.0 0.02 1.410037
2017-08-07 COF 84.62 85.4200 84.38 85.15 1388253.0 0.0 1.0 84.620000 85.420000 84.380000 85.150000 1388253.0 -0.71 1.422399
In [288]:
jpm.head()
Out[288]:
ticker open high low close volume ex-dividend split_ratio adj_open adj_high adj_low adj_close adj_volume First Difference Normed Return
date
2007-08-07 JPM 44.99 46.05 44.15 45.34 30556500.0 0.0 1.0 35.320354 36.152529 34.660894 35.595129 30556500.0 NaN 1.000000
2007-08-08 JPM 45.75 47.23 45.27 46.51 27447200.0 0.0 1.0 35.917008 37.078913 35.540174 36.513662 27447200.0 0.76 1.025805
2007-08-09 JPM 45.04 45.94 44.17 44.17 39278200.0 0.0 1.0 35.359607 36.066172 34.676596 34.676596 39278200.0 -0.71 0.974195
2007-08-10 JPM 43.36 44.80 42.51 44.25 32549000.0 0.0 1.0 34.040688 35.171190 33.373377 34.739401 32549000.0 -1.68 0.975959
2007-08-13 JPM 45.23 45.43 43.68 43.83 21357600.0 0.0 1.0 35.508771 35.665785 34.291911 34.409671 21357600.0 1.87 0.966696
In [289]:
jpm.tail()
Out[289]:
ticker open high low close volume ex-dividend split_ratio adj_open adj_high adj_low adj_close adj_volume First Difference Normed Return
date
2017-08-01 JPM 92.490 93.14 92.280 93.03 12424667.0 0.0 1.0 92.490 93.14 92.280 93.03 12424667.0 0.980 2.613560
2017-08-02 JPM 92.865 93.21 92.505 93.11 10118266.0 0.0 1.0 92.865 93.21 92.505 93.11 10118266.0 0.375 2.615807
2017-08-03 JPM 92.700 93.13 92.235 92.50 11052753.0 0.0 1.0 92.700 93.13 92.235 92.50 11052753.0 -0.165 2.598670
2017-08-04 JPM 93.500 94.40 93.471 93.66 14292087.0 0.0 1.0 93.500 94.40 93.471 93.66 14292087.0 0.800 2.631259
2017-08-07 JPM 93.890 94.19 93.710 94.02 7917204.0 0.0 1.0 93.890 94.19 93.710 94.02 7917204.0 0.390 2.641373

Capital Assests Pricing Model (CAPM)- describe risk and seperating market return versus portfolio return¶

A portfolio is a set of weighted securities. Returns of portfolio rp(t)=∑i=1nwiri(t)

Weights for each company? wi=CaPi/∑i=1nCaPj Market Cap(number of shares*price)

CAPM equation, ri(t)=birm(t)+αi(t) Like simple linear regeression, y=mx+b

CAPM equation describes the return of some individual stock 'i'. CAPM states that aplha should be expected to be zero. It basically implies that you can not beat the general marke, alpha is random and cannot be predicted. Return of Portfolio, rp(t)=bprm(t)+∑i=1nwiαi(t)
Beta Term - there will be relationship between our portfolio return and the overall market return. CAPM says that the alpha term can not be predicted, we will fundamentally disagree with that model of thinking Create Strategies that allow us to have significant alpha terms, [i.e. beating the barket]

In [290]:
import pandas_datareader as web
In [291]:
start = pd.to_datetime('2007-08-07')
end = pd.to_datetime('2017-08-07')
In [292]:
spy_etf = web.DataReader('SPY', 'google',start,end)
In [293]:
spy_etf.head()
Out[293]:
Open High Low Close Volume
Date
2007-08-07 145.94 149.00 145.23 147.77 63637400
2007-08-08 148.41 150.59 147.34 149.83 28554400
2007-08-09 147.43 149.95 145.29 145.39 25668900
2007-08-10 144.39 146.50 143.12 144.71 26680900
2007-08-13 146.50 146.89 145.02 145.23 51858600
In [294]:
jpm['close'].plot(label='JPM', figsize=(10,8))
cof['close'].plot(label='COF')
spy_etf['Close'].plot(label='SPY Index')
plt.legend()
Out[294]:
<matplotlib.legend.Legend at 0x292989e6400>
In [295]:
jpm['cumulative'] = jpm['close']/jpm['close'].iloc[0]
cof['cumulative'] = cof['close']/cof['close'].iloc[0]
spy_etf['cumulative'] = spy_etf['Close']/spy_etf['Close'].iloc[0]
In [296]:
jpm['cumulative'].plot(label='JPM',figsize = (16,6))
cof['cumulative'].plot(label='COF')
spy_etf['cumulative'].plot(label='SPY')
plt.legend()
Out[296]:
<matplotlib.legend.Legend at 0x29296c9ed30>
In [297]:
jpm['Daily Return'] = jpm['close'].pct_change(1)
cof['Daily Return'] = cof['close'].pct_change(1)
spy_etf['Daily Return'] = spy_etf['Close'].pct_change(1)
In [298]:
plt.scatter(jpm['Daily Return'],cof['Daily Return'],alpha=0.25)
Out[298]:
<matplotlib.collections.PathCollection at 0x29298ff1a20>
In [299]:
beta,alpha,r_value,p_value,std_err = stats.linregress(jpm['Daily Return'].iloc[1:],
                                                     cof['Daily Return'].iloc[1:])
In [300]:
beta
Out[300]:
0.82028916401077046
In [301]:
alpha
Out[301]:
3.7798255601578009e-05
In [302]:
r_value
Out[302]:
0.71068778594709325

This is very useful tool to share and convert the file into different file format. source

In [303]:
file_writer = FilesWriter()

def export(name, nb):
    
    # Get a unique key for the notebook and set it in the resources object.
    notebook_name = name[:name.rfind('.')]
    resources = {}
    resources['unique_key'] = notebook_name
    resources['output_files_dir'] = '%s_files' % notebook_name

    # Try to export
    try:
        output, resources = export_by_name(exporter_names.value, nb)
    except ConversionException as e:
        download_link.value = "<br>Could not export notebook!"
    else:
        write_results = file_writer.write(output, resources, notebook_name=notebook_name)
    
        download_link.value = "<br>Results: <a href='files/{filename}'><i>\"{filename}\"</i></a>".format(filename=write_results)
        download_link.visible = True
        
def handle_export(widget):
    with open(filename, 'r') as f:
        export(filename, read(f, NO_CONVERT))
        
export_button.on_click(handle_export)
In [304]:
display(exporter_names, export_button, download_link)
In [ ]:
 
Skype Backpack