For more information on how to read and understand the plots look at:
import numpy as np
from quantopian.research import run_pipeline
from quantopian.pipeline import Pipeline
from quantopian.pipeline.data.builtin import USEquityPricing
from quantopian.pipeline.factors import CustomFactor, Returns, AverageDollarVolume
from quantopian.pipeline.classifiers.morningstar import Sector
from quantopian.pipeline.filters import Q500US
from quantopian.pipeline.filters import StaticAssets
MORNINGSTAR_SECTOR_CODES = {
-1: 'Misc',
101: 'Basic Materials',
102: 'Consumer Cyclical',
103: 'Financial Services',
104: 'Real Estate',
205: 'Consumer Defensive',
206: 'Healthcare',
207: 'Utilities',
308: 'Communication Services',
309: 'Energy',
310: 'Industrials',
311: 'Technology' ,
}
class LowVol(CustomFactor):
inputs = [Returns(window_length=2)]
window_length = 25
def compute(self, today, assets, out, close):
out[:] = -np.nanstd(close, axis=0)
# universe = StaticAssets(symbols(['CVX', 'AAPL'])) # works
universe = StaticAssets(symbols(['CVX'])) # Does not work
pipe_low_vol = Pipeline(
columns={
'LowVol' : LowVol(mask=universe),
'Sector': Sector(mask=universe),
},
screen=universe
)
results = run_pipeline(pipe_low_vol, '2015-06-30', '2016-06-30')
results.head()
assets = results.index.levels[1].unique()
# We need to get a little more pricing data than the
# length of our factor so we can compare forward returns.
# We'll tack on another month in this example.
pricing = get_pricing(assets, start_date='2015-06-30', end_date='2016-07-31', fields='open_price')
pricing.head()
results.head()
results.loc[:,'LowVolRank'] = results.loc[:,'LowVol'].rank(method='dense')
results[ results['LowVolRank'].isin([225.0, 226.0, 227.0])]
type(results['LowVol'].index)
results['LowVol'].index[0]
import alphalens
bins=[-10000,100000]
quantiles=None
factor_data = alphalens.utils.get_clean_factor_and_forward_returns(results['LowVol'],
pricing,
quantiles=quantiles,
bins=bins,
periods=(1,5,10))
# please note long_short=False as we are not running a dollar neutral portfolio
alphalens.tears.create_event_returns_tear_sheet(factor_data, pricing, long_short=False)
# please note long_short=False as we are not running a dollar neutral portfolio
alphalens.tears.create_returns_tear_sheet(factor_data, long_short=False)
Because of bug https://github.com/quantopian/alphalens/commit/bccedc9f743c054b6ee93727accf4f215c2e9ed0 Alphalens crashes if there is only one quantile/bin. So, until Alphalens is updated to the latest version on Q, we have to use the following workaround instead of calling alphalens.tears.create_returns_tear_sheet directly
import alphalens.performance as perf
import alphalens.utils as utils
import alphalens.plotting as plotting
def create_returns_tear_sheet(factor_data, long_short=True, by_group=False):
"""
Creates a tear sheet for returns analysis of a factor.
Parameters
----------
factor_data : pd.DataFrame - MultiIndex
A MultiIndex DataFrame indexed by date (level 0) and asset (level 1),
containing the values for a single alpha factor, forward returns for each period,
The factor quantile/bin that factor value belongs too, and (optionally) the group the
asset belongs to.
long_short : bool
Should this computation happen on a long short portfolio?
by_group : bool
If True, perform calcuations, and display graphs separately for
each group.
"""
factor_returns = perf.factor_returns(factor_data, long_short)
mean_ret_quantile, std_quantile = perf.mean_return_by_quantile(factor_data,
by_group=False,
demeaned=long_short)
mean_compret_quantile = mean_ret_quantile.apply(utils.rate_of_return, axis=0)
mean_ret_quant_daily, std_quant_daily = perf.mean_return_by_quantile(factor_data,
by_date=True,
by_group=False,
demeaned=long_short)
mean_compret_quant_daily = mean_ret_quant_daily.apply(utils.rate_of_return, axis=0)
plotting.plot_quantile_returns_bar(mean_compret_quantile,
by_group=False,
ylim_percentiles=None)
plotting.plot_quantile_returns_violin(mean_compret_quant_daily,
ylim_percentiles=(1, 99))
for p in factor_returns:
plotting.plot_cumulative_returns(factor_returns[p],
period=p)
# plotting.plot_cumulative_returns_by_quantile(mean_ret_quant_daily[p],
# period=p)
create_returns_tear_sheet(factor_data, long_short=False)