Notebook
In [43]:
from quantopian.pipeline import Pipeline
from quantopian.research import run_pipeline
from quantopian.pipeline.data.builtin import USEquityPricing
from quantopian.pipeline import CustomFactor
from quantopian.pipeline.filters import StaticAssets

import numpy as np
import alphalens

#import anything else as need be
In [2]:
#Momentum Custom Factor

class Momentum(CustomFactor):
    def compute(self, today, asset_ids, out, values):
        out[:] = values[-1] / values[0]
In [44]:
def make_pipeline():
    
    portfolio = (StaticAssets(symbols([
        'SPY',
        'VEU',
        'TLT',
    ])))
    #put alpha to test here
    moment = Momentum(inputs = [USEquityPricing.close], mask=portfolio, window_length = 252)
    
    #specify any filters here into universe. Make sure alphas have .notnull() in universe.
    universe = (moment.notnull())
    
    #Use print statements to make sure the BETTER one is ranked HIGHER. Eg Rank 150 is BETTER than rank 149.
    #first do it without ranking them, so you can ensure raw numbers make sense.
    testingFactor = moment.rank(method='average', 
                    ascending=True,
                    mask = universe)
    
    #Seperate into the desired quantiles, top X%, whatever you want here.
    longs = testingFactor.top(1)
    
    #if long and short strategy, specify which sections you would long/short. Returns a pipeline object.
    pipe = Pipeline(columns = {'testingFactor':testingFactor,
                              'Momentum': moment,
                              'long': longs},
                   screen = universe)
    
    return pipe
In [49]:
#Makes a dataframe with the given universe, ranked by the testing factor.
results = run_pipeline(make_pipeline(), start_date = '2008-04-01', end_date = '2009-01-01')

#print the results to make sure it fuckin worked. Print once without rankings to verify.
results
Out[49]:
Momentum long testingFactor
2008-04-01 00:00:00+00:00 Equity(8554 [SPY]) 0.947638 False 1.0
Equity(23921 [TLT]) 1.085342 True 3.0
Equity(33486 [VEU]) 1.020675 False 2.0
2008-04-02 00:00:00+00:00 Equity(8554 [SPY]) 0.980130 False 1.0
Equity(23921 [TLT]) 1.066409 True 3.0
Equity(33486 [VEU]) 1.046020 False 2.0
2008-04-03 00:00:00+00:00 Equity(8554 [SPY]) 0.969716 False 1.0
Equity(23921 [TLT]) 1.069781 True 3.0
Equity(33486 [VEU]) 1.036028 False 2.0
2008-04-04 00:00:00+00:00 Equity(8554 [SPY]) 0.969832 False 1.0
Equity(23921 [TLT]) 1.071072 True 3.0
Equity(33486 [VEU]) 1.033581 False 2.0
2008-04-07 00:00:00+00:00 Equity(8554 [SPY]) 0.967810 False 1.0
Equity(23921 [TLT]) 1.084789 True 3.0
Equity(33486 [VEU]) 1.032520 False 2.0
2008-04-08 00:00:00+00:00 Equity(8554 [SPY]) 0.967369 False 1.0
Equity(23921 [TLT]) 1.086009 True 3.0
Equity(33486 [VEU]) 1.035648 False 2.0
2008-04-09 00:00:00+00:00 Equity(8554 [SPY]) 0.960744 False 1.0
Equity(23921 [TLT]) 1.079721 True 3.0
Equity(33486 [VEU]) 1.023145 False 2.0
2008-04-10 00:00:00+00:00 Equity(8554 [SPY]) 0.959639 False 1.0
Equity(23921 [TLT]) 1.090649 True 3.0
Equity(33486 [VEU]) 1.017900 False 2.0
2008-04-11 00:00:00+00:00 Equity(8554 [SPY]) 0.957479 False 1.0
Equity(23921 [TLT]) 1.087310 True 3.0
Equity(33486 [VEU]) 1.014123 False 2.0
2008-04-14 00:00:00+00:00 Equity(8554 [SPY]) 0.935448 False 1.0
Equity(23921 [TLT]) 1.098140 True 3.0
Equity(33486 [VEU]) 0.995250 False 2.0
... ... ... ... ...
2008-12-18 00:00:00+00:00 Equity(8554 [SPY]) 0.638226 False 2.0
Equity(23921 [TLT]) 1.285822 True 3.0
Equity(33486 [VEU]) 0.575387 False 1.0
2008-12-19 00:00:00+00:00 Equity(8554 [SPY]) 0.621300 False 2.0
Equity(23921 [TLT]) 1.315843 True 3.0
Equity(33486 [VEU]) 0.557133 False 1.0
2008-12-22 00:00:00+00:00 Equity(8554 [SPY]) 0.610808 False 2.0
Equity(23921 [TLT]) 1.336880 True 3.0
Equity(33486 [VEU]) 0.540476 False 1.0
2008-12-23 00:00:00+00:00 Equity(8554 [SPY]) 0.595791 False 2.0
Equity(23921 [TLT]) 1.332625 True 3.0
Equity(33486 [VEU]) 0.533989 False 1.0
2008-12-24 00:00:00+00:00 Equity(8554 [SPY]) 0.590407 False 2.0
Equity(23921 [TLT]) 1.342014 True 3.0
Equity(33486 [VEU]) 0.527764 False 1.0
2008-12-26 00:00:00+00:00 Equity(8554 [SPY]) 0.601434 False 2.0
Equity(23921 [TLT]) 1.330895 True 3.0
Equity(33486 [VEU]) 0.541146 False 1.0
2008-12-29 00:00:00+00:00 Equity(8554 [SPY]) 0.604713 False 2.0
Equity(23921 [TLT]) 1.317161 True 3.0
Equity(33486 [VEU]) 0.535862 False 1.0
2008-12-30 00:00:00+00:00 Equity(8554 [SPY]) 0.607701 False 2.0
Equity(23921 [TLT]) 1.304877 True 3.0
Equity(33486 [VEU]) 0.541917 False 1.0
2008-12-31 00:00:00+00:00 Equity(8554 [SPY]) 0.629802 False 2.0
Equity(23921 [TLT]) 1.297775 True 3.0
Equity(33486 [VEU]) 0.560387 False 1.0
2009-01-02 00:00:00+00:00 Equity(8554 [SPY]) 0.639694 False 2.0
Equity(23921 [TLT]) 1.273546 True 3.0
Equity(33486 [VEU]) 0.566918 False 1.0

579 rows × 3 columns

In [50]:
#Gets each unique stock ticker and puts it in assets
assets = results.index.levels[1].unique()

#gets pricing data. Needs a month before and after. Dunno why.
pricing = get_pricing(assets, start_date='2008-03-01', end_date='2009-02-01', fields='open_price')
In [51]:
#Look up documentation to see how to customize this. This all organizes info so alphalens can get to work.
factor_data = alphalens.utils.get_clean_factor_and_forward_returns(factor = results['testingFactor'],  
                                                                   prices = pricing,  
                                                                   quantiles =3,
                                                                   periods = (30,60))

# Runs alphalens
alphalens.tears.create_full_tear_sheet(factor_data)
Dropped 21.2% entries from factor data: 21.2% in forward returns computation and 0.0% in binning phase (set max_loss=0 to see potentially suppressed Exceptions).
max_loss is 35.0%, not exceeded: OK!
Quantiles Statistics
min max mean std count count %
factor_quantile
1 1.0 1.0 1.0 0.0 152 33.333333
2 2.0 2.0 2.0 0.0 152 33.333333
3 3.0 3.0 3.0 0.0 152 33.333333
Returns Analysis
30D 60D
Ann. alpha 0.131 0.249
beta -0.714 -0.642
Mean Period Wise Return Top Quantile (bps) 753.080 791.951
Mean Period Wise Return Bottom Quantile (bps) -328.781 -333.310
Mean Period Wise Spread (bps) 1081.861 1120.174
<matplotlib.figure.Figure at 0x7f1c66360cd0>
Information Analysis
30D 60D
IC Mean 0.411 0.612
IC Std. 0.604 0.321
Risk-Adjusted IC 0.681 1.904
t-stat(IC) 8.396 23.470
p-value(IC) 0.000 0.000
IC Skew -0.833 -1.440
IC Kurtosis -0.585 5.683
Turnover Analysis
30D 60D
Quantile 1 Mean Turnover 0.246 0.620
Quantile 2 Mean Turnover 0.287 0.652
Quantile 3 Mean Turnover 0.041 0.043
30D 60D
Mean Factor Rank Autocorrelation 0.857 0.663