Single stock analysis example in pyfolio + Quandl¶
This post describes how I corrected the error when running Single Stock Example from PyFolio.
Yahoo and Google no longer support the API as used by pandas_datareader 0.6.0, so I updated the code to use Quandl API.
To get this to work, make sure that QUANDL_API_KEY
key is set up in your environment. Go to Quandl site, register as a user, then in your user settings, get the API key. In Ubuntu Linux, update ~/.bashrc
to include the following key initialization:
export QUANDL_API_KEY=[your key]
Here's a simple example where we produce a set of plots, called a tear sheet, for a single stock.
Import pyfolio and matplotlib¶
In [1]:
%matplotlib inline
# silence warnings
import warnings
warnings.filterwarnings('ignore')
import pyfolio as pf
In [2]:
import pandas_datareader as pdr
import pandas_datareader.data as web
symbol = 'FB' # or 'AAPL.US'
df = web.DataReader(symbol, 'quandl', '2012-05-22', '2014-05-16')
df.tail()
Out[2]:
Fetch the daily returns for a stock¶
In [3]:
from empyrical.utils import get_utc_timestamp, get_returns_cached, _1_bday_ago, data_path
from pandas_datareader import data as web
from datetime import datetime
import pandas as pd
def get_symbol_returns_from_quandl(symbol, start=None, end=None):
"""
Wrapper for pandas.io.data.get_data_quandl().
Retrieves prices for symbol from quandl and computes returns
based on adjusted closing prices.
Parameters
----------
symbol : str
Symbol name to load, e.g. 'SPY'
start : pandas.Timestamp compatible, optional
Start date of time period to retrieve
end : pandas.Timestamp compatible, optional
End date of time period to retrieve
Returns
-------
pandas.DataFrame
Returns of symbol in requested period.
"""
px = web.get_data_quandl(symbol, start=start, end=end)
rets = px[['AdjClose']]
rets = rets.shift(-1)
rets.iloc[-1]['AdjClose'] = px.tail(1)['AdjOpen']
rets = rets.shift(1) / rets - 1
rets = rets.dropna()
rets.index = rets.index.to_datetime()
rets.index = rets.index.tz_localize("UTC")
rets.columns = [symbol]
return rets
def returns_func(symbol, start=None, end=None):
"""
Gets returns for a symbol.
Queries Quandl Finance. Attempts to cache SPY.
Parameters
----------
symbol : str
Ticker symbol, e.g. APPL.
start : date, optional
Earliest date to fetch data for.
Defaults to earliest date available.
end : date, optional
Latest date to fetch data for.
Defaults to latest date available.
Returns
-------
pd.Series
Daily returns for the symbol.
- See full explanation in tears.create_full_tear_sheet (returns).
"""
if start is None:
start = '1/1/1970'
if end is None:
end = _1_bday_ago()
start = get_utc_timestamp(start)
end = get_utc_timestamp(end)
if symbol == 'SPY':
filepath = data_path('spy.csv')
rets = get_returns_cached(filepath,
get_symbol_returns_from_quandl,
end,
symbol='SPY',
start=start,
end=datetime.now())
try:
rets = rets[rets.index.isin(pd.bdate_range(start, end))]
except Exception as e:
rets = rets[start:end]
else:
rets = get_symbol_returns_from_quandl(symbol, start=start, end=end)
rets.sort_index(inplace=True)
return rets[symbol]
pf.utils.register_return_func(returns_func)
In [4]:
stock_rets = pf.utils.get_symbol_rets('FB', start='2012-05-22', end='2014-05-16')
In [5]:
stock_rets.head()
Out[5]:
In [6]:
benchmark_rets = pf.utils.get_symbol_rets('SPY', start='2012-05-22', end='2014-05-16')
benchmark_rets.head()
Out[6]:
Create a returns tear sheet for the single stock¶
This will show charts and analysis about returns of the single stock.
In [7]:
pf.create_returns_tear_sheet(stock_rets, benchmark_rets=benchmark_rets)