Notebook
In [6]:
import quantopian.optimize as opt
from quantopian.research import run_pipeline
from quantopian.pipeline import Pipeline
from quantopian.pipeline.factors import Latest, CustomFactor
from quantopian.pipeline.domain import US_EQUITIES
from quantopian.pipeline.filters import QTradableStocksUS
from quantopian.pipeline.data.builtin import USEquityPricing
from quantopian.pipeline.classifiers.fundamentals import Sector
from sklearn import preprocessing
from scipy import stats

import quantopian.pipeline.data.factset.estimates as fe
from scipy.stats.mstats import winsorize
from scipy.stats import kurtosis, skew
import alphalens as al
from scipy import stats
import numpy as np
import pandas as pd
In [7]:
universe = QTradableStocksUS()

fq1_eps_cons = fe.PeriodicConsensus.slice('EPS', 'qf', 1)
fq1_eps_cons_up = fq1_eps_cons.up
fq1_eps_cons_down = fq1_eps_cons.down   


def make_factors():
    
        class result(CustomFactor):         
            inputs = [fq1_eps_cons_up,
                      fq1_eps_cons_down]
            window_length = 1
            def compute(self, today, assets, out, up, down):
                
                ratio_1 = up[-1] - down[-1]
                
                out[:] = ratio_1      
       
     
        
        return {
                'result':              (result,1.0),
                }
In [8]:
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 [9]:
factors = make_factors()
    
result = None

for name, (f,w) in factors.iteritems(): #.items() in Python 3.5
        if result  == None:
            result  = w*f(mask=universe)
        else:
            result  += w*f(mask=universe)
In [10]:
pipe = Pipeline(
    columns = {
            'Result' : result,
            'Sector' : Sector()
    },
    domain=US_EQUITIES,
    screen= universe & ~result.isnull() & result.isfinite(),
)

results = run_pipeline(pipe, '2014-04-01', '2017-12-19')

Pipeline Execution Time: 13.04 Seconds
In [11]:
result  = results['Result']
print result.head(30)
2014-04-01 00:00:00+00:00  Equity(2 [ARNC])       3.0
                           Equity(24 [AAPL])    -34.0
                           Equity(31 [ABAX])     -8.0
                           Equity(39 [DDC])       2.0
                           Equity(41 [ARCB])     -9.0
                           Equity(52 [ABM])      -1.0
                           Equity(53 [ABMD])     -1.0
                           Equity(62 [ABT])     -13.0
                           Equity(64 [GOLD])     -7.0
                           Equity(67 [ADSK])    -16.0
                           Equity(69 [ACAT])     -1.0
                           Equity(76 [TAP])      -3.0
                           Equity(84 [ACET])     -2.0
                           Equity(88 [ACI])      -7.0
                           Equity(110 [RAMP])    -1.0
                           Equity(114 [ADBE])    20.0
                           Equity(122 [ADI])     12.0
                           Equity(128 [ADM])     -5.0
                           Equity(154 [AEM])      0.0
                           Equity(161 [AEP])      2.0
                           Equity(166 [AES])     -2.0
                           Equity(168 [AET])     -3.0
                           Equity(185 [AFL])     -2.0
                           Equity(197 [AGCO])   -10.0
                           Equity(205 [AGN])     -9.0
                           Equity(216 [HES])    -10.0
                           Equity(239 [AIG])     -3.0
                           Equity(247 [AIN])      0.0
                           Equity(253 [AIR])     -3.0
                           Equity(266 [AJG])    -10.0
Name: Result, dtype: float64
In [12]:
sectors = results['Sector']
In [13]:
asset_list = results.index.levels[1].unique()
In [14]:
prices = get_pricing(asset_list, start_date='2014-04-01', end_date='2017-12-19', fields='open_price')
In [15]:
periods = (1, 3, 5)
factor_data = al.utils.get_clean_factor_and_forward_returns(factor=result,
                                                            prices=prices,
                                                            groupby=sectors,
                                                            groupby_labels=MORNINGSTAR_SECTOR_CODES,
                                                            periods=periods)
Dropped 0.6% entries from factor data: 0.6% 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!
In [16]:
al.tears.create_full_tear_sheet(factor_data, by_group=True);
Quantiles Statistics
min max mean std count count %
factor_quantile
1 -38.0 -3.0 -11.018557 5.230705 424316 21.885191
2 -7.0 -1.0 -3.545992 1.483249 437140 22.546622
3 -3.0 1.0 -0.797708 0.802568 435568 22.465542
4 0.0 4.0 1.152883 0.835968 305260 15.744571
5 2.0 39.0 6.966851 5.045657 336543 17.358073
Returns Analysis
1D 3D 5D
Ann. alpha 0.042 0.033 0.032
beta -0.015 -0.026 -0.031
Mean Period Wise Return Top Quantile (bps) 2.489 1.937 1.668
Mean Period Wise Return Bottom Quantile (bps) -0.834 -0.622 -0.618
Mean Period Wise Spread (bps) 3.323 2.564 2.294
<matplotlib.figure.Figure at 0x7f471a412910>
Information Analysis
1D 3D 5D
IC Mean 0.011 0.014 0.015
IC Std. 0.062 0.064 0.064
Risk-Adjusted IC 0.185 0.218 0.234
t-stat(IC) 5.655 6.656 7.143
p-value(IC) 0.000 0.000 0.000
IC Skew -0.257 -0.347 -0.184
IC Kurtosis 0.361 0.317 0.166
Turnover Analysis
1D 3D 5D
Quantile 1 Mean Turnover 0.036 0.093 0.141
Quantile 2 Mean Turnover 0.069 0.166 0.242
Quantile 3 Mean Turnover 0.075 0.181 0.264
Quantile 4 Mean Turnover 0.087 0.204 0.291
Quantile 5 Mean Turnover 0.040 0.103 0.155
1D 3D 5D
Mean Factor Rank Autocorrelation 0.979 0.935 0.891
In [ ]:
 
In [ ]:
 
In [ ]: