Notebook

Alphalens + Quantopian | How To

For more information on how to read and understand the plots look at:

In [1]:
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
In [2]:
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' ,    
}

Define our factor

In [3]:
class LowVol(CustomFactor):
    inputs = [Returns(window_length=2)]
    window_length = 25
    
    def compute(self, today, assets, out, close):
        out[:] = -np.nanstd(close, axis=0)

Define our universe

In [4]:
universe = Q500US()

Create the Pipeline

In [5]:
pipe_low_vol = Pipeline(
    columns={
        'LowVol' : LowVol(mask=universe),
        'Sector': Sector(mask=universe),
    },
    screen=universe
)

Run the Pipeline

In [6]:
results = run_pipeline(pipe_low_vol, '2015-06-30', '2016-06-30')
In [7]:
results.head()
Out[7]:
LowVol Sector
2015-06-30 00:00:00+00:00 Equity(2 [ARNC]) -0.008829 101
Equity(24 [AAPL]) -0.008808 311
Equity(62 [ABT]) -0.009697 206
Equity(67 [ADSK]) -0.013364 311
Equity(76 [TAP]) -0.012557 205

Get pricing

In [8]:
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')
In [9]:
pricing.head()
Out[9]:
Equity(2 [ARNC]) Equity(24 [AAPL]) Equity(62 [ABT]) Equity(67 [ADSK]) Equity(76 [TAP]) Equity(114 [ADBE]) Equity(122 [ADI]) Equity(128 [ADM]) Equity(161 [AEP]) Equity(166 [AES]) ... Equity(47777 [CFG]) Equity(47779 [CYBR]) Equity(47888 [FCAU]) Equity(48317 [JUNO]) Equity(48384 [QRVO]) Equity(49141 [CPGX]) Equity(49209 [BXLT]) Equity(49229 [KHC]) Equity(49242 [PYPL]) Equity(49506 [HPE])
2015-06-30 00:00:00+00:00 11.296 123.050 48.089 51.09 69.898 82.19 62.445 47.403 51.030 12.596 ... 26.724 62.86 9.834 59.330 80.00 28.023 NaN NaN NaN NaN
2015-07-01 00:00:00+00:00 11.050 124.354 47.982 50.59 69.025 81.57 63.163 47.248 51.078 12.682 ... 27.038 64.00 9.689 53.945 81.25 28.737 NaN NaN NaN NaN
2015-07-02 00:00:00+00:00 10.941 123.893 48.370 50.43 68.711 81.19 62.678 47.355 51.579 12.653 ... 26.940 62.54 9.512 54.750 80.72 27.300 NaN NaN NaN NaN
2015-07-06 00:00:00+00:00 10.803 122.433 47.613 50.41 68.083 80.02 61.970 46.714 52.128 12.624 ... 26.449 58.91 9.131 53.520 80.33 28.893 30.622 68.389 NaN NaN
2015-07-07 00:00:00+00:00 10.813 123.364 48.526 51.35 68.073 80.77 61.601 46.666 52.813 12.605 ... 26.527 57.86 9.157 54.270 80.29 30.154 31.516 71.019 NaN NaN

5 rows × 583 columns

Use Alphalens to create a factor tear sheet

In [11]:
import alphalens

factor_data = alphalens.utils.get_clean_factor_and_forward_returns(results['LowVol'],
                                                                   pricing,
                                                                   quantiles=5,
                                                                   groupby=results['Sector'],
                                                                   periods=(1,5,10))

alphalens.tears.create_full_tear_sheet(factor_data)
Quantiles Statistics
min max mean std count count %
factor_quantile
1 -0.464020 -0.016364 -0.038044 0.018451 25371 20.064692
2 -0.037706 -0.012226 -0.021462 0.004322 25263 19.979280
3 -0.027612 -0.010385 -0.016784 0.003419 25206 19.934201
4 -0.022187 -0.007915 -0.013717 0.002997 25263 19.979280
5 -0.017743 -0.000457 -0.010173 0.002897 25343 20.042548
Returns Analysis
1 5 10
Ann. alpha 0.040 0.017 0.013
beta -0.505 -0.593 -0.611
Mean Period Wise Return Top Quantile (bps) 4.858 22.922 37.614
Mean Period Wise Return Bottom Quantile (bps) -4.514 -18.501 -25.814
Mean Period Wise Spread (bps) 9.383 8.571 6.610
Information Analysis
1 5 10
IC Mean 0.028 0.054 0.056
IC Std. 0.259 0.267 0.267
t-stat(IC) 1.732 3.233 3.340
p-value(IC) 0.085 0.001 0.001
IC Skew 0.092 -0.237 -0.370
IC Kurtosis -0.711 -0.734 -0.843
Ann. IR 1.725 3.220 3.327
Turnover Analysis
1 5 10
Quantile 1 Mean Turnover 0.042 0.124 0.198
Quantile 2 Mean Turnover 0.102 0.285 0.424
Quantile 3 Mean Turnover 0.141 0.370 0.515
Quantile 4 Mean Turnover 0.140 0.362 0.502
Quantile 5 Mean Turnover 0.067 0.188 0.285
1 5 10
Mean Factor Rank Autocorrelation 0.987 0.933 0.868
<matplotlib.figure.Figure at 0x7f1811105350>