Notebook
In [1]:
import numpy as np
from quantopian.research import run_pipeline
from quantopian.pipeline import Pipeline
from quantopian.pipeline.data import Fundamentals
from quantopian.pipeline.data.builtin import USEquityPricing
from quantopian.pipeline.factors import CustomFactor
from quantopian.pipeline.classifiers.fundamentals import Sector  
from quantopian.pipeline.filters import QTradableStocksUS
from time import time
from sklearn import preprocessing
from scipy.stats.mstats import winsorize
from quantopian.pipeline.data import factset
In [2]:
import alphalens as al
In [3]:
WIN_LIMIT = 0.0
In [4]:
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' ,    
}
In [5]:
def make_factors():
                
        class Altman_Z(CustomFactor):
            inputs=[factset.Fundamentals.zscore_qf]
            window_length = 1
            def compute(self, today, assets, out, zscore_qf):
                out[:] = preprocess(-zscore_qf[-1])
                                                                                             
        return {
            'Altman_Z':               Altman_Z,
        }
In [6]:
def preprocess(a):
    
    a = np.nan_to_num(a - np.nanmean(a))
    
    a = winsorize(a, limits=[WIN_LIMIT,WIN_LIMIT])

    return preprocessing.scale(a)
In [7]:
universe = QTradableStocksUS()

factors = make_factors()

combined_alpha = None

for name, f in factors.iteritems():
        if combined_alpha == None:
            combined_alpha = f(mask=universe)
        else:
            combined_alpha = combined_alpha+f(mask=universe)

pipe = Pipeline(
    columns = {
            'CombinedAlpha' : combined_alpha,
            'Sector' : Sector()
    },
    screen=universe
)

start_timer = time()
results = run_pipeline(pipe, '2010-01-01', '2017-10-19',chunksize=252)
end_timer = time()
results.fillna(value=0);

print "Time to run pipeline %.2f secs" % (end_timer - start_timer)
Time to run pipeline 46.70 secs
In [8]:
my_factor = results['CombinedAlpha']
sectors = results['Sector']
asset_list = results.index.levels[1].unique()
prices = get_pricing(asset_list, start_date='2010-01-01', end_date='2017-10-19', fields='open_price')
periods = (1,3,5,10,21)

factor_data = al.utils.get_clean_factor_and_forward_returns(factor=my_factor,
                                                            prices=prices,
                                                            groupby=sectors,
                                                            groupby_labels=MORNINGSTAR_SECTOR_CODES,
                                                            periods=periods,
                                                            quantiles = 5)
Dropped 6.6% entries from factor data: 1.2% in forward returns computation and 5.4% in binning phase (set max_loss=0 to see potentially suppressed Exceptions).
max_loss is 35.0%, not exceeded: OK!
In [9]:
mean_return_by_q_daily, std_err_by_q_daily = al.performance.mean_return_by_quantile(factor_data,
                                                                                    by_date=True)
mean_return_by_q, std_err_by_q = al.performance.mean_return_by_quantile(factor_data,
                                                                        by_group=False)
ic = al.performance.factor_information_coefficient(factor_data)
In [10]:
al.tears.create_information_tear_sheet(factor_data)
Information Analysis
1D 3D 5D 10D 21D
IC Mean -0.007 -0.009 -0.010 -0.011 -0.011
IC Std. 0.079 0.081 0.081 0.083 0.080
Risk-Adjusted IC -0.094 -0.112 -0.122 -0.131 -0.142
t-stat(IC) -4.035 -4.809 -5.246 -5.601 -6.078
p-value(IC) 0.000 0.000 0.000 0.000 0.000
IC Skew 0.008 0.044 0.006 0.050 -0.255
IC Kurtosis 0.262 0.082 0.011 0.272 0.231
<matplotlib.figure.Figure at 0x7f5aae524990>
In [11]:
al.tears.create_full_tear_sheet(factor_data, by_group=True);
Quantiles Statistics
min max mean std count count %
factor_quantile
1.0 -4.447618e+01 8.793658e-17 -0.816424 1.763625 842563 23.236688
2.0 -1.267223e-01 4.188688e-02 -0.003593 0.014410 708419 19.537187
3.0 5.631313e-07 2.761170e-01 0.121520 0.063399 624618 17.226075
4.0 8.563077e-02 5.101315e-01 0.304392 0.076150 724835 19.989917
5.0 1.332030e-01 1.070595e+01 0.542721 0.450744 725568 20.010132
Returns Analysis
1D 3D 5D 10D 21D
Ann. alpha 0.021 0.020 0.018 0.019 0.015
beta -0.034 -0.020 -0.003 0.015 0.028
Mean Period Wise Return Top Quantile (bps) -1.482 -1.247 -1.193 -1.123 -1.013
Mean Period Wise Return Bottom Quantile (bps) 0.565 0.529 0.522 0.467 0.440
Mean Period Wise Spread (bps) -1.577 -1.336 -1.276 -1.163 -1.021
<matplotlib.figure.Figure at 0x7f5a9fabea50>
Information Analysis
1D 3D 5D 10D 21D
IC Mean -0.007 -0.009 -0.010 -0.011 -0.011
IC Std. 0.079 0.081 0.081 0.083 0.080
Risk-Adjusted IC -0.094 -0.112 -0.122 -0.131 -0.142
t-stat(IC) -4.035 -4.809 -5.246 -5.601 -6.078
p-value(IC) 0.000 0.000 0.000 0.000 0.000
IC Skew 0.008 0.044 0.006 0.050 -0.255
IC Kurtosis 0.262 0.082 0.011 0.272 0.231
Turnover Analysis
10D 1D 21D 3D 5D
Quantile 1 Mean Turnover 0.035 0.005 0.068 0.012 0.019
Quantile 2 Mean Turnover 0.093 0.018 0.158 0.039 0.057
Quantile 3 Mean Turnover 0.053 0.008 0.099 0.020 0.030
Quantile 4 Mean Turnover 0.041 0.006 0.077 0.015 0.023
Quantile 5 Mean Turnover 0.027 0.004 0.050 0.010 0.015
1D 3D 5D 10D 21D
Mean Factor Rank Autocorrelation 0.999 0.998 0.996 0.993 0.986
In [ ]: