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>