Notebook

International Factor Research - Alphalens Example

In [1]:
from quantopian.pipeline import Pipeline, CustomFactor
from quantopian.pipeline.data import EquityPricing, factset
from quantopian.pipeline.factors import Returns, SimpleMovingAverage, AverageDollarVolume
from quantopian.pipeline.domain import (
    AT_EQUITIES, # Austria
    AU_EQUITIES, # Australia
    BE_EQUITIES, # Belgium
    CA_EQUITIES, # Canada
    CH_EQUITIES, # Switzerland
    CN_EQUITIES, # China
    DE_EQUITIES, # Germany
    DK_EQUITIES, # Denmark
    ES_EQUITIES, # Spain
    FI_EQUITIES, # Finland
    FR_EQUITIES, # France
    GB_EQUITIES, # Great Britain
    HK_EQUITIES, # Hong Kong
    IE_EQUITIES, # Ireland
    IN_EQUITIES, # India
    IT_EQUITIES, # Italy
    JP_EQUITIES, # Japan
    NL_EQUITIES, # Netherlands
    NO_EQUITIES, # Norway
    NZ_EQUITIES, # New Zealand
    PT_EQUITIES, # Portugal
    SE_EQUITIES, # Sweden
    SG_EQUITIES, # Singapore
    US_EQUITIES, # United States
)
from quantopian.research import run_pipeline
from quantopian.pipeline.filters import Q500US
# from quantopian.pipeline.classifiers.fundamentals import Sector
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

# import talib as ta

The below helper function makes it easier to get Alphalens-formatted factor and returns data given a pipeline factor, a domain, and date bounds.

In [2]:
def evaluate_factor(factor, 
                    domain, 
                    start_date, 
                    end_date,
                    factor_screen=None,
                    quantiles=5,
                    returns_lengths=(1, 5, 10),
                    session = 'Overnight',
                    chunksize = None
                   ):
    """Analyze a Pipeline Factor using Alphalens.
    
    Parameters
    ----------
    factor : quantopian.pipeline.factors.Factor
        Factor producing scores to be evaluated.
    domain : quantopian.pipeline.domain.Domain
        Domain on which the factor should be evaluated.
    start_date : str or pd.Timestamp
        Start date for evaluation period.
    end_date : str or pd.Timestamp
        End date for evaluation period.
    standardize : 
    factor_screen : quantopian.pipeline.filters.Filter, optional
        Filter defining which assets ``factor`` should be evaluated on.
        Default is ``factor.notnull()``.
    quantiles : int, optional
        Number of buckets to use for quantile groups. Default is 5
    returns_lengths : sequence[int]
        Forward-returns horizons to use when evaluating ``factor``. 
        Default is 1-day, 5-day, and 10-day returns.
    session: str
        "Overnight", "Intraday", "Daily"
        
    Returns
    -------
    factor_data : pd.DataFrame
        A (date, asset)-indexed DataFrame with the following columns:
            'factor': float64
                Values produced by ``factor``.
            'factor_quantiles': int64
                Daily quantile label for each
    """
    calendar = domain.calendar

    # Roll input dates to the next trading session.
    start_date = calendar.minute_to_session_label(pd.Timestamp(start_date, tz='UTC'))
    end_date = calendar.minute_to_session_label(pd.Timestamp(end_date, tz='UTC'))
    
    if factor_screen is None:
        factor_screen = factor.notnull()
        
        
    # Run pipeline to get factor values and quantiles.
    factor_pipe = Pipeline(
        {'factor': factor, 
         'factor_quantile': factor.quantiles(quantiles, mask=factor_screen)},
        screen=factor_screen,
        domain=domain,
    )
    # Put chunksize ~252-504 if you run into memory problems 
    factor_results = run_pipeline(factor_pipe, start_date, end_date, chunksize=chunksize)
    
    class Daily(CustomFactor):  
        inputs = [EquityPricing.close]  

        def compute(self, today, assets, out, close):  
            out[:] = close[-1] / close[0] - 1
            
    class Overnight(CustomFactor):  
        inputs = [EquityPricing.close, EquityPricing.open]  

        def compute(self, today, assets, out, close, open):  
            out[:] = np.cumprod(open[1:] / close[:-1], axis=0)[-1] - 1
            
    class Intraday(CustomFactor):  
        inputs = [EquityPricing.close, EquityPricing.open]  

        def compute(self, today, assets, out, close, open):  
            out[:] = np.cumprod(close / open, axis=0)[-1] - 1
    
    column_order = []
    returns_cols = {}
    for length in returns_lengths:
        colname = '{}D'.format(length)
        column_order.append(colname)
        
        # Add 1 because "1-day" returns needs 2 price observations.
        # Not relevant for Intraday.
        # Winsorize returns to handle data gliches
        # Example: get_pricing("BRK_A", start_date='2014-11-03', end_date='2014-11-08')
        # 0.002 * ~500 (companies per day) = 1 (from each side)
        if session == 'Overnight':
            returns_cols[colname] = Overnight(window_length=length + 1).winsorize(.002, .998)
        elif session == "Intraday":
            returns_cols[colname] = Intraday(window_length=length).winsorize(.002, .998)
        elif session == "Daily":
            returns_cols[colname] = Daily(window_length=length + 1).winsorize(.002, .998)
        else:
            raise SystemExit("session should be one of 'Overnight', 'Intraday', 'Daily'")
        

    returns_pipe = Pipeline(returns_cols, domain=domain)
    
    # Compute returns for the period after the factor pipeline, then 
    # shift the results back to align with our factor values.
    returns_start_date = start_date
    returns_end_date = end_date + domain.calendar.day * max(returns_lengths)
    raw_returns = run_pipeline(returns_pipe, returns_start_date, returns_end_date, chunksize=252)
    
    shifted_returns = {}
    for name, length in zip(column_order, returns_lengths):
        # Shift 1-day returns back by a day, 5-day returns back by 5 days, etc.
        raw = raw_returns[name]
        shifted_returns[name] = backshift_returns_series(raw, length)
        
    # Merge backshifted returns into a single frame indexed like our desired output.
    merged_returns = pd.DataFrame(
        data=shifted_returns, 
        index=factor_results.index, 
        columns=column_order,
    )
    
    # Concat factor results and forward returns column-wise.
    merged = pd.concat([factor_results, merged_returns], axis=1)
    merged.index.set_names(['date', 'asset'], inplace=True)

    return merged.dropna(how='any')


def backshift_returns_series(series, N):
    """Shift a multi-indexed series backwards by N observations in the first level.
    
    This can be used to convert backward-looking returns into a forward-returns series.
    """
    ix = series.index
    dates, sids = ix.levels
    date_labels, sid_labels = map(np.array, ix.labels)

    # Output date labels will contain all but the last N dates.
    new_dates = dates[:-N]

    # Output data will remove the first M rows, where M is the index of the
    # last record with one of the first N dates.
    cutoff = date_labels.searchsorted(N)
    new_date_labels = date_labels[cutoff:] - N
    new_sid_labels = sid_labels[cutoff:]
    new_values = series.values[cutoff:]

    assert new_date_labels[0] == 0

    new_index = pd.MultiIndex(
        levels=[new_dates, sids],
        labels=[new_date_labels, new_sid_labels],
        sortorder=1,
        names=ix.names,
    )

    return pd.Series(data=new_values, index=new_index)

Define your factors and filters here:

In [13]:
# Your alpha factor:
# Winsorize it to deal with extreeme outliers

# Example Fundamental Factor:
# log Market Cap
# FactSet fundamentals: https://www.quantopian.com/help/factset_fundamentals

#FIRST Factor
bps_gr_af=factset.Fundamentals.bps_gr_af.latest.log().winsorize(.005,.995)
mkt_val=factset.Fundamentals.mkt_val.latest.log().winsorize(.005,.995)
BE=(bps_gr_af/mkt_val)# Book to market ratio=(book value per share/market value of the firm) >> Value factor <<
BE1=0.0-BE
#SECOND Factor
# entrpr_val_af = factset.Fundamentals.entrpr_val_af.latest.log().winsorize(.005,.995)
total_assets=factset.Fundamentals.assets.latest.log().winsorize(.005,.995)
com_shs_trade_af=factset.Fundamentals.com_shs_trade_af.latest.log().winsorize(.005,.995)
common_share_traded=0.0-com_shs_trade_af
#THIRD Factor  DIVIDEND Yield
# price_secs_af=factset.Fundamentals.price_secs_af.latest.log().winsorize(.005,.995)
# roe_af=factset.Fundamentals.roe_af.latest.log().winsorize(.005,.995)
# roe=0.0-roe_af
MC=factset.Fundamentals.mkt_val_public.latest.log().winsorize(.005,.995)

PE=factset.Fundamentals.pe_af.latest.log().winsorize(.005,.995)
PE1=0.0 -PE


my_factor=BE1.zscore()# +common_share_traded.zscore()#+MC.zscore()#+total_assets.zscore()

# factor = BE1.zscore() +common_share_traded.zscore()+MC.zscore()+total_assets.zscore()#Intraday +overnight inverse
# my_factor=0.0-factor
# my_factor = BE1.zscore() +common_share_traded.zscore()+MC.zscore() #+roe.zscore()# + PE1.zscore()#inverse with Overnight
# y_factor=0.0-factor

# my_factor=0.0 -alpha

#combining factors
# my_factor = PE1.zscore() + MC.zscore()


#1-result: my_factor = BE.zscore() + com_shs_trade_af.zscore()....overnight/intraday
#2-result:pe intraday inverse 1 and 4 quantile
#3-my_factor=factset.Fundamentals.mkt_val_public.latest.log().winsorize(.005,.995) intraday
#4-my_factor = PE1.zscore() + MC.zscore()  Intraday


#my_factor=0.0- eps_diluted
# Example Custom Factors (i.e. Technicals)

# Willam's VIX FIX
# class WVF(CustomFactor):  
#     inputs = [EquityPricing.close, EquityPricing.low]  

#     def compute(self, today, assets, out, close, low):  
#         out[:] = ((np.nanmax(close, axis = 0) - low[-1]) / np.nanmax(close, axis = 0)) * 100

# Overnight Gap (or cumulative overnight returns)
# class Overnight(CustomFactor):  
#     inputs = [EquityPricing.close, EquityPricing.open]  

#     def compute(self, today, assets, out, close, open):  
#         out[:] = np.cumprod(open[1:] / close[:-1], axis=0)[-1] - 1
        
# my_factor = 0.0 - Overnight(window_length = 2)
# non_zero_overnigt = my_factor.percentile_between(0.1, 99.9, mask=(my_factor != 0))

# Create a volume filter that filters for stocks in the top 10% companies based on Average Dollar Volume.
avg_dollar_vol = AverageDollarVolume(window_length = 63)
volume_filter = avg_dollar_vol.percentile_between(90, 100, mask=(avg_dollar_vol > 0))
In [14]:
# Call evaluate_factor on your factor to get Alphalens-formatted data.
al_data = evaluate_factor(
    factor = my_factor, 
    domain = US_EQUITIES, 
    start_date = '2010-01-01', 
    end_date = '2017-11-06', 
    factor_screen = volume_filter & Q500US(), # Remove Q500US() if using non-US market
    session = "Intraday", # Can be "Overnight", "Intraday", "Daily"
    quantiles = 5,
    returns_lengths = (1, 5, 10),
    chunksize = 252    #None # Put chunksize ~252-504 if you run into memory problems
)

Results index reference:

t(0) = index of results

  • Overnight_Returns (1D): From t(-1) close to t(0) open
  • Intraday_Returns (1D): From t(0) open to t(0) close
  • Daily Returns (1D): From t(-1) close to t(0) close
  • Factors should be as of Close of t(-1)
In [15]:
# Import Alphalens and run our factor data through a tear sheet.
from alphalens.tears import create_full_tear_sheet

create_full_tear_sheet(al_data)
Quantiles Statistics
min max mean std count count %
factor_quantile
0 -3.409711 -0.225461 -0.888091 0.541269 136733 20.105517
1 -0.524424 0.216714 -0.141262 0.119606 135656 19.947153
2 -0.137463 0.488263 0.185776 0.114925 135560 19.933037
3 0.183646 0.881660 0.510781 0.126054 135659 19.947594
4 0.556736 3.339415 1.221250 0.520888 136469 20.066698
Returns Analysis
1D 5D 10D
Ann. alpha 0.061 0.060 0.059
beta -0.113 -0.111 -0.096
Mean Period Wise Return Top Quantile (bps) 1.224 1.269 1.285
Mean Period Wise Return Bottom Quantile (bps) -3.315 -3.216 -3.115
Mean Period Wise Spread (bps) 4.540 4.506 4.421
<matplotlib.figure.Figure at 0x7f5331f11fd0>
Information Analysis
1D 5D 10D
IC Mean 0.013 0.021 0.029
IC Std. 0.100 0.096 0.094
Risk-Adjusted IC 0.129 0.216 0.311
t-stat(IC) 5.713 9.580 13.806
p-value(IC) 0.000 0.000 0.000
IC Skew 0.064 0.145 0.066
IC Kurtosis 0.030 -0.010 -0.283

ValueErrorTraceback (most recent call last)
<ipython-input-15-3dba5307e48e> in <module>()
      2 from alphalens.tears import create_full_tear_sheet
      3 
----> 4 create_full_tear_sheet(al_data)

/usr/local/lib/python2.7/dist-packages/alphalens/plotting.pyc in call_w_context(*args, **kwargs)
     43             with plotting_context(), axes_style(), color_palette:
     44                 sns.despine(left=True)
---> 45                 return func(*args, **kwargs)
     46         else:
     47             return func(*args, **kwargs)

/usr/local/lib/python2.7/dist-packages/alphalens/tears.pyc in create_full_tear_sheet(factor_data, long_short, group_neutral, by_group)
    488                                   by_group,
    489                                   set_context=False)
--> 490     create_turnover_tear_sheet(factor_data, set_context=False)
    491 
    492 

/usr/local/lib/python2.7/dist-packages/alphalens/plotting.pyc in call_w_context(*args, **kwargs)
     45                 return func(*args, **kwargs)
     46         else:
---> 47             return func(*args, **kwargs)
     48     return call_w_context
     49 

/usr/local/lib/python2.7/dist-packages/alphalens/tears.pyc in create_turnover_tear_sheet(factor_data, turnover_periods)
    415                        for q in range(1, int(quantile_factor.max()) + 1)],
    416                       axis=1)
--> 417             for p in turnover_periods}
    418 
    419     autocorrelation = pd.concat(

/usr/local/lib/python2.7/dist-packages/alphalens/tears.pyc in <dictcomp>((p,))
    415                        for q in range(1, int(quantile_factor.max()) + 1)],
    416                       axis=1)
--> 417             for p in turnover_periods}
    418 
    419     autocorrelation = pd.concat(

/usr/local/lib/python2.7/dist-packages/alphalens/performance.pyc in quantile_turnover(quantile_factor, quantile, period)
    738         shifted_idx = utils.add_custom_calendar_timedelta(
    739                 quant_name_sets.index, -pd.Timedelta(period),
--> 740                 quantile_factor.index.levels[0].freq)
    741         name_shifted = quant_name_sets.reindex(shifted_idx)
    742         name_shifted.index = quant_name_sets.index

/usr/local/lib/python2.7/dist-packages/alphalens/utils.pyc in add_custom_calendar_timedelta(input, timedelta, freq)
    915     """
    916     if not isinstance(freq, (Day, BusinessDay, CustomBusinessDay)):
--> 917         raise ValueError("freq must be Day, BDay or CustomBusinessDay")
    918     days = timedelta.components.days
    919     offset = timedelta - pd.Timedelta(days=days)

ValueError: freq must be Day, BDay or CustomBusinessDay
In [ ]:
# al_data

Plot Number of companies per day

In [ ]:
companies_per_day = al_data.groupby(pd.Grouper(freq='D', level = 0)).count()
companies_per_day = companies_per_day[(companies_per_day.T != 0).any()]
plt.plot(companies_per_day['factor'])
plt.ylabel('Number of companies per day')
plt.show()

Further linear relationship analysis between factor and 1D returns:

In [ ]:
# sns.regplot(x="factor", y="1D", data=al_data, robust = True)
In [ ]:
# f, ax= plt.subplots()
# ax.set(xlim=(min(al_data['factor']), max(al_data['factor'])))
# sns.regplot(x="factor", y="1D", data=al_data, scatter = False, robust = True)

Further relationship analysis between factor quantile (daily) and 1D returns

In [ ]:
sns.violinplot(x="factor_quantile", y="1D",
               split=True, inner="quart",
               data=al_data)

Estimattion of central tendency of 1D returns per quantile.

Mean:

In [ ]:
# sns.regplot(x="factor_quantile", y="1D", data=al_data, x_estimator=np.mean, robust = True)

Median:

In [ ]:
sns.regplot(x="factor_quantile", y="1D", data=al_data, x_estimator=np.median, robust = True)

pyfolio analysis:

In [16]:
from alphalens.performance import create_pyfolio_input

import alphalens
import pyfolio

pf_returns, pf_positions, pf_benchmark = \
    create_pyfolio_input(al_data,
                         period='1D',
                         capital=1000000,
                         long_short=True,
                         group_neutral=False,
                         equal_weight=False, # Equal weight vs weight based on alpha factor
                         quantiles=[0,4], # Choose the "best" quantiles to trade based on your analysis above
                         groups=None,
                         benchmark_period='1D')
In [17]:
from pyfolio.tears import create_full_tear_sheet

create_full_tear_sheet(pf_returns,
                       positions=pf_positions,
                       benchmark_rets=pf_benchmark,
                       round_trips=True)
Start date2010-01-05
End date2017-11-07
Total months136
Backtest
Annual return 4.8%
Cumulative returns 69.6%
Annual volatility 3.3%
Sharpe ratio 1.41
Calmar ratio 1.13
Stability 0.98
Max drawdown -4.2%
Omega ratio 1.33
Sortino ratio 2.26
Skew 0.43
Kurtosis 4.11
Tail ratio 1.22
Daily value at risk -0.4%
Gross leverage 0.97
Alpha 0.05
Beta -0.13
Worst drawdown periods Net drawdown in % Peak date Valley date Recovery date Duration
0 4.21 2014-12-17 2015-04-09 2015-09-29 205
1 3.22 2014-04-29 2014-07-02 2014-10-13 120
2 2.79 2016-02-09 2016-02-29 2016-03-18 29
3 2.67 2010-07-01 2010-10-28 2011-02-18 167
4 1.96 2015-09-30 2015-10-05 2015-10-23 18
Stress Events mean min max
US downgrade/European Debt Crisis 0.01% -0.65% 0.48%
Fukushima 0.02% -0.44% 0.48%
EZB IR Event 0.03% -0.87% 0.70%
Flash Crash 0.10% -0.15% 0.49%
Apr14 0.10% -0.70% 0.91%
Oct14 0.01% -0.56% 0.60%
Fall2015 0.07% -1.48% 1.39%
Recovery 0.02% -0.87% 0.99%
New Normal 0.02% -1.48% 1.39%
Top 10 long positions of all time max
BBT 2.52%
HD 2.48%
JNPR 2.37%
LSI 2.34%
RL 2.25%
DOV 2.20%
BEXP 2.07%
CTL 2.06%
PVH 2.05%
WM 2.03%
Top 10 short positions of all time max
FIT -2.88%
ACIA -2.75%
ON -2.67%
DF -2.67%
RAD -2.53%
DNDN_Q -2.42%
ATVI -2.39%
WLT -2.32%
VRSN -2.27%
TRGP -2.26%
Top 10 positions of all time max
FIT 2.88%
ACIA 2.75%
ON 2.67%
DF 2.67%
RAD 2.53%
BBT 2.52%
HD 2.48%
DNDN_Q 2.42%
ATVI 2.39%
JNPR 2.37%
All positions ever held max
FIT 2.88%
ACIA 2.75%
ON 2.67%
DF 2.67%
RAD 2.53%
BBT 2.52%
HD 2.48%
DNDN_Q 2.42%
ATVI 2.39%
JNPR 2.37%
LSI 2.34%
WLT 2.32%
VRSN 2.27%
TRGP 2.26%
RL 2.25%
FEYE 2.22%
DATA 2.21%
CY 2.20%
DOV 2.20%
URI 2.16%
VRSK 2.10%
BEXP 2.07%
CTL 2.06%
SABR 2.05%
PVH 2.05%
WM 2.03%
LCC 2.03%
MJN 2.03%
GMCR 2.01%
COTY 2.01%
LH 1.99%
XOM 1.98%
ADM 1.98%
ARNA 1.97%
PPG 1.97%
QRVO 1.97%
UNP 1.95%
STJ 1.94%
KHC 1.93%
SINA 1.93%
GLW 1.92%
DISH 1.91%
ECL 1.90%
STX 1.89%
SSYS 1.86%
SYK 1.86%
AIG 1.85%
GRPN 1.84%
KDP 1.83%
MDVN 1.83%
ZG 1.83%
RAI 1.82%
RCL 1.82%
RCPT 1.81%
UAL 1.80%
ADS 1.79%
HCA 1.78%
OLED 1.78%
CAH 1.77%
LLTC 1.77%
NTAP 1.77%
VMED 1.76%
WSM 1.76%
TSRO 1.75%
ESI 1.73%
JAZZ 1.70%
DISC_A 1.70%
LMT 1.69%
PAY 1.68%
SJM 1.67%
GIS 1.66%
ESRX 1.66%
WMT 1.66%
JNJ 1.65%
HP 1.63%
VRTX 1.62%
AAL 1.62%
RSG 1.61%
P 1.61%
SRPT 1.60%
NVDA 1.60%
ICPT 1.60%
EQR 1.59%
PBCT 1.59%
AON 1.58%
FFIV 1.58%
SIRI 1.58%
NKE 1.57%
CCEP 1.57%
CYBR 1.57%
THC 1.57%
HOG 1.56%
AFL 1.56%
INTC 1.55%
CPRI 1.54%
ABC 1.53%
T 1.52%
RKT 1.52%
VMC 1.51%
SPGI 1.50%
FTR 1.50%
PFG 1.50%
HST 1.48%
BLK 1.48%
FDX 1.47%
MNST 1.46%
ADBE 1.46%
XL 1.46%
ENDP 1.46%
ADI 1.45%
LYB 1.45%
HFC 1.44%
TSLA 1.43%
LVS 1.42%
CCL 1.42%
SYY 1.42%
MO 1.42%
MBI 1.42%
JBHT 1.42%
SCCO 1.42%
S 1.41%
MXIM 1.41%
EXPE 1.41%
HZNP 1.40%
NI 1.39%
COG 1.39%
GT 1.38%
NWL 1.38%
LVLT 1.37%
KEY 1.37%
SWK 1.37%
MBLY 1.37%
CLX 1.36%
PXD 1.36%
AABA 1.36%
ABT 1.36%
MYL 1.36%
HLT 1.36%
CIT 1.36%
ANR 1.36%
CNP 1.35%
CA 1.35%
DD 1.35%
LBTY_A 1.35%
ZAYO 1.34%
NSC 1.34%
M 1.34%
PEG 1.34%
SPLK 1.33%
DLTR 1.33%
GGP 1.32%
BLUE 1.32%
TWX 1.32%
SLCA 1.31%
GPRO 1.31%
ASH 1.30%
ORLY 1.30%
KMX 1.30%
HSIC 1.30%
DAL 1.30%
CELG 1.30%
ALXN 1.30%
PCYC 1.29%
ILMN 1.29%
ETN 1.29%
PCP 1.28%
LEA 1.28%
KMI 1.27%
ARO 1.27%
CEG 1.27%
SOHU 1.27%
INCY 1.27%
TRIP 1.26%
BAC 1.26%
AVGO 1.26%
HSY 1.26%
YELP 1.25%
WIN 1.25%
PRGO 1.25%
FNSR 1.25%
OCLR 1.25%
JCP 1.23%
ESS 1.23%
MMI 1.22%
ACAD 1.22%
PG 1.22%
REGN 1.22%
AMZN 1.22%
NYCB 1.21%
APA 1.21%
PSA 1.21%
MCHP 1.21%
ABBV 1.20%
HCP 1.20%
VNO 1.19%
MAN 1.19%
AKS 1.19%
DNR 1.19%
HLF 1.19%
O 1.18%
FRX 1.18%
APH 1.18%
LNKD 1.17%
LRCX 1.17%
WMB 1.17%
PHM 1.16%
FCX 1.16%
PGN 1.16%
GWW 1.16%
XRAY 1.16%
MRK 1.15%
FWLT 1.15%
SCTY 1.15%
SHW 1.14%
BLL 1.14%
ISRG 1.13%
QCOR 1.13%
MON 1.13%
NFLX 1.13%
STI 1.12%
WLTW 1.12%
WELL 1.12%
CVS 1.12%
AMT 1.12%
ARUN 1.12%
CNC 1.12%
EMR 1.11%
TSN 1.11%
JCG 1.11%
BWA 1.10%
CENX 1.10%
CLF 1.10%
MMM 1.09%
VECO 1.09%
MOS 1.09%
BKD 1.09%
HRI 1.09%
NAV 1.09%
MLM 1.08%
IDCC 1.08%
XTO 1.08%
NRG 1.07%
WYNN 1.07%
CSIQ 1.07%
GENZ 1.07%
KOG 1.07%
TXN 1.07%
FLT 1.07%
LLL 1.07%
MCP 1.07%
ATI 1.07%
ALB 1.06%
F 1.06%
SHOP 1.05%
PH 1.05%
PAYX 1.05%
DUK 1.04%
KRFT 1.04%
WTW 1.04%
DOW 1.04%
HAS 1.04%
MGM 1.04%
STEC 1.04%
SII 1.04%
TRA 1.04%
STR 1.03%
RHT 1.03%
WFT 1.03%
MNK 1.03%
NEM 1.02%
PANW 1.02%
PLD 1.02%
PE 1.02%
MDT 1.02%
FANG 1.01%
GME 1.01%
ICE 1.00%
ARG 1.00%
HNZ 1.00%
PCG 1.00%
TRV 0.99%
KATE 0.99%
CRUS 0.99%
CMCS_A 0.98%
LNG 0.98%
AMAT 0.98%
IONS 0.98%
C 0.98%
VTR 0.98%
AVP 0.98%
BK 0.98%
RTN 0.98%
DDD 0.98%
KLAC 0.98%
LULU 0.97%
JOY 0.97%
BA 0.97%
TMO 0.97%
AER 0.97%
DHI 0.96%
MA 0.96%
KIM 0.95%
LMCA 0.95%
AMBA 0.95%
NOV 0.94%
SWY 0.94%
PRU 0.94%
PYPL 0.94%
CSCO 0.94%
MRO 0.94%
CMS 0.93%
CHKP 0.93%
ADP 0.92%
TWTR 0.92%
TPR 0.92%
BXP 0.92%
MAS 0.92%
ORCL 0.91%
GXP 0.91%
FLR 0.91%
DO 0.91%
EBAY 0.91%
PBI 0.91%
EQT 0.91%
MCD 0.91%
MCK 0.91%
WFM 0.91%
NUE 0.91%
AGN 0.90%
VLO 0.90%
SRE 0.90%
IOC 0.90%
PII 0.90%
ALTR 0.90%
HON 0.90%
HDS 0.90%
CVI 0.89%
CCI 0.89%
WDAY 0.89%
CAM 0.89%
SYF 0.89%
BURL 0.88%
BBY 0.88%
SD 0.88%
FIO 0.88%
BDX 0.88%
FB 0.87%
AES 0.87%
MOS 0.87%
FIS 0.87%
OI 0.86%
LB 0.86%
CLR 0.86%
WRK 0.86%
SRCL 0.86%
FSLR 0.86%
JCI 0.86%
SWN 0.86%
JWN 0.85%
BKNG 0.85%
ED 0.85%
ETR 0.85%
BMRN 0.85%
VMW 0.85%
PETM 0.84%
HSH 0.84%
RICE 0.84%
CRM 0.84%
UPL 0.84%
INFO 0.83%
STZ 0.83%
DXCM 0.83%
APKT 0.83%
TPX 0.83%
SHLD 0.83%
V 0.82%
TER 0.82%
EOG 0.82%
DVA 0.82%
TOL 0.82%
TRW 0.81%
AMD 0.81%
GPOR 0.81%
WU 0.81%
SUNE 0.81%
CMA 0.80%
OAS 0.80%
CME 0.80%
GE 0.80%
APOL 0.80%
ANTM 0.79%
FTI 0.79%
SLG 0.79%
SO 0.78%
HPQ 0.78%
SBUX 0.77%
HRB 0.77%
ROC 0.77%
PCAR 0.77%
STLD 0.77%
CL 0.77%
SM 0.77%
CEPH 0.76%
NLY 0.76%
SLB 0.76%
DLR 0.76%
FE 0.76%
TTWO 0.75%
TGNA 0.75%
WEC 0.75%
CBI 0.75%
TWC 0.75%
SODA 0.75%
STT 0.75%
CF 0.75%
MSFT 0.75%
MAC 0.75%
EIX 0.74%
RF 0.74%
UTHR 0.74%
AAP 0.73%
HUM 0.73%
TDG 0.73%
DIS 0.73%
NOW 0.72%
VVUS 0.72%
RRC 0.72%
DTE 0.72%
EVHC 0.72%
RIG 0.72%
LIFE 0.71%
DE 0.71%
PTV 0.71%
TJX 0.71%
AME 0.71%
OMC 0.71%
GR 0.71%
FTNT 0.71%
FL 0.70%
HES 0.70%
VAR 0.70%
YUM 0.70%
CI 0.70%
RAX 0.70%
ANDV 0.70%
LOW 0.69%
NDAQ 0.69%
APTV 0.69%
MCO 0.69%
ARIA 0.69%
BMY 0.69%
ZNGA 0.69%
ARNC 0.68%
K 0.68%
XEL 0.68%
KBH 0.68%
IBM 0.67%
EMN 0.67%
BEN 0.67%
JAH 0.67%
PFE 0.66%
FLIR 0.66%
CXO 0.66%
TIE 0.65%
PXP 0.65%
CE 0.65%
EW 0.65%
DKS 0.65%
LEN 0.65%
OPEN 0.64%
MRVL 0.64%
ATHR 0.64%
GLNG 0.64%
MPC 0.64%
WY 0.64%
BUCY 0.64%
EQIX 0.64%
ROK 0.64%
NLC 0.64%
GPS 0.63%
ZTS 0.63%
AEP 0.63%
AAPL 0.63%
AWK 0.63%
RH 0.63%
CVC 0.63%
APC 0.63%
MU 0.62%
ULTA 0.62%
MLNX 0.62%
AVB 0.62%
VIAV 0.62%
CAR 0.62%
ATML 0.62%
DGX 0.62%
AEE 0.62%
AMG 0.62%
CAG 0.61%
MAT 0.61%
DHR 0.61%
SNDK 0.61%
AMTD 0.61%
AAOI 0.61%
NBR 0.61%
KO 0.61%
CTSH 0.61%
NYX 0.61%
ANET 0.61%
TIF 0.61%
IP 0.61%
ES 0.61%
IVZ 0.61%
CPGX 0.60%
KMB 0.60%
AR 0.60%
SE 0.60%
ACL 0.60%
TAP 0.60%
NFX 0.60%
INFA 0.60%
ANF 0.60%
HMA 0.60%
RVBD 0.60%
BRCD 0.59%
SAVE 0.59%
WDC 0.59%
SPLS 0.58%
TXT 0.58%
GILD 0.58%
HAR 0.58%
CSX 0.58%
GM 0.58%
MELI 0.58%
KR 0.58%
CPB 0.58%
UNH 0.58%
RSPP 0.57%
NRF 0.57%
TWO 0.57%
BIG 0.57%
NBL 0.57%
VOYA 0.57%
DECK 0.57%
COST 0.57%
HSP 0.57%
CFG 0.56%
CBRE 0.56%
MEE 0.56%
YNDX 0.56%
WP 0.56%
CVX 0.56%
NUS 0.56%
ITMN 0.55%
MS 0.55%
SKX 0.55%
AEO 0.55%
SPWR 0.55%
KSS 0.55%
PPO 0.54%
HIG 0.54%
VZ 0.54%
CREE 0.54%
FSL 0.54%
HL 0.54%
XRX 0.54%
FAST 0.54%
IR 0.53%
ZBH 0.53%
GNC 0.53%
HCBK 0.53%
VFC 0.53%
MUR 0.53%
QCOM 0.53%
PM 0.53%
JPM 0.53%
WBA 0.53%
MDR 0.52%
FCAU 0.52%
SPG 0.52%
QRTE_A 0.52%
BTU 0.52%
FLS 0.52%
CTXS 0.52%
DELL 0.51%
LL 0.51%
UAA 0.51%
LZ 0.51%
JBLU 0.51%
RSH 0.51%
OXY 0.51%
BAX 0.51%
BHI 0.51%
MTB 0.51%
PNRA 0.51%
PGR 0.50%
AKRX 0.50%
UTX 0.50%
GS 0.50%
DRI 0.50%
SWKS 0.50%
TIBX 0.50%
CMG 0.50%
GD 0.50%
APD 0.50%
URBN 0.50%
BG 0.50%
TMUS 0.50%
UPS 0.49%
CHK 0.49%
PTEN 0.49%
GES 0.49%
CAT 0.49%
UNM 0.49%
AXLL 0.48%
NTRS 0.48%
FDO 0.48%
D 0.48%
A 0.48%
TDC 0.48%
PPL 0.48%
EL 0.48%
QEP 0.48%
TRN 0.48%
SFD 0.48%
BRK_B 0.47%
MAR 0.47%
OUTR 0.47%
WAT 0.47%
CB 0.47%
OVTI 0.47%
EXPD 0.47%
NE 0.47%
NCR 0.46%
DFS 0.46%
EMC 0.46%
ACI 0.46%
MET 0.46%
IGT 0.46%
WFC 0.46%
LLY 0.46%
BRCM 0.46%
JCI 0.46%
XLNX 0.45%
EA 0.45%
BIIB 0.45%
RLGY 0.45%
CNX 0.45%
WLL 0.45%
CTV 0.45%
AKAM 0.45%
VRUS 0.45%
BWLD 0.45%
SLXP 0.44%
NEE 0.44%
PLL 0.44%
TEX 0.44%
HOT 0.44%
ALL 0.43%
TSCO 0.43%
SNI 0.43%
GRMN 0.43%
HBAN 0.43%
GNW 0.43%
WNR 0.43%
INTU 0.42%
FST 0.42%
OC 0.42%
SYNA 0.42%
YUMC 0.42%
AXP 0.42%
ACN 0.42%
AMP 0.41%
ALK 0.41%
BBBY 0.41%
EP 0.41%
CIE 0.41%
SUG 0.40%
LITE 0.40%
SWC 0.40%
MDLZ 0.40%
SYMC 0.39%
CHRW 0.39%
AMGN 0.39%
SFSF 0.39%
COF 0.39%
DVN 0.39%
RFMD 0.39%
ATGE 0.39%
AYI 0.39%
JBL 0.38%
EXC 0.38%
XEC 0.38%
FITB 0.37%
SLM 0.37%
NUAN 0.37%
CRR 0.37%
UDR 0.36%
NVLS 0.36%
CIEN 0.36%
PWR 0.36%
COL 0.36%
COP 0.35%
ROST 0.35%
NETL 0.35%
IAC 0.35%
PDE 0.35%
KCI 0.34%
FOXA 0.34%
TROW 0.33%
HAL 0.32%
WOOF 0.32%
TGT 0.29%
In [ ]:
 
In [23]:
#FIRST Factor
bps_gr_af=factset.Fundamentals.bps_gr_af.latest.log().winsorize(.005,.995)
mkt_val=factset.Fundamentals.mkt_val.latest.log().winsorize(.005,.995)
BE=(bps_gr_af/mkt_val)# 
BE1=0.0-BE
#SECOND Factor
# entrpr_val_af = factset.Fundamentals.entrpr_val_af.latest.log().winsorize(.005,.995)
total_assets=factset.Fundamentals.assets.latest.log().winsorize(.005,.995)
com_shs_trade_af=factset.Fundamentals.com_shs_trade_af.latest.log().winsorize(.005,.995)
common_share_traded=0.0-com_shs_trade_af

MC=factset.Fundamentals.mkt_val_public.latest.log().winsorize(.005,.995)



my_factor=BE1.zscore() +common_share_traded.zscore()+MC.zscore()#+total_assets.zscore()

avg_dollar_vol = AverageDollarVolume(window_length = 63)
volume_filter = avg_dollar_vol.percentile_between(90, 100, mask=(avg_dollar_vol > 0))
In [24]:
# Call evaluate_factor on your factor to get Alphalens-formatted data.
al_data = evaluate_factor(
    factor = my_factor, 
    domain = US_EQUITIES, 
    start_date = '2010-01-01', 
    end_date = '2017-11-06', 
    factor_screen = volume_filter & Q500US(), # Remove Q500US() if using non-US market
    session = "Intraday", # Can be "Overnight", "Intraday", "Daily"
    quantiles = 5,
    returns_lengths = (1, 5, 10),
    chunksize = 252    #None # Put chunksize ~252-504 if you run into memory problems
)
In [25]:
# Import Alphalens and run our factor data through a tear sheet.
from alphalens.tears import create_full_tear_sheet

create_full_tear_sheet(al_data)
Quantiles Statistics
min max mean std count count %
factor_quantile
0 -5.517547 -0.267375 -1.102710 0.739029 115382 20.121550
1 -0.581575 0.211255 -0.148451 0.155235 114309 19.934429
2 -0.034613 0.742597 0.320246 0.142475 114261 19.926058
3 0.419522 1.264432 0.753813 0.146358 114294 19.931813
4 0.865103 3.835654 1.480277 0.515022 115179 20.086149
Returns Analysis
1D 5D 10D
Ann. alpha 0.076 0.076 0.075
beta -0.209 -0.218 -0.203
Mean Period Wise Return Top Quantile (bps) 1.070 1.085 1.098
Mean Period Wise Return Bottom Quantile (bps) -3.300 -3.335 -3.353
Mean Period Wise Spread (bps) 4.370 4.449 4.478
<matplotlib.figure.Figure at 0x7f5333c3d410>
Information Analysis
1D 5D 10D
IC Mean 0.014 0.022 0.030
IC Std. 0.135 0.129 0.125
Risk-Adjusted IC 0.103 0.166 0.240
t-stat(IC) 4.573 7.399 10.671
p-value(IC) 0.000 0.000 0.000
IC Skew 0.087 0.062 -0.093
IC Kurtosis -0.263 -0.270 -0.251

ValueErrorTraceback (most recent call last)
<ipython-input-25-3dba5307e48e> in <module>()
      2 from alphalens.tears import create_full_tear_sheet
      3 
----> 4 create_full_tear_sheet(al_data)

/usr/local/lib/python2.7/dist-packages/alphalens/plotting.pyc in call_w_context(*args, **kwargs)
     43             with plotting_context(), axes_style(), color_palette:
     44                 sns.despine(left=True)
---> 45                 return func(*args, **kwargs)
     46         else:
     47             return func(*args, **kwargs)

/usr/local/lib/python2.7/dist-packages/alphalens/tears.pyc in create_full_tear_sheet(factor_data, long_short, group_neutral, by_group)
    488                                   by_group,
    489                                   set_context=False)
--> 490     create_turnover_tear_sheet(factor_data, set_context=False)
    491 
    492 

/usr/local/lib/python2.7/dist-packages/alphalens/plotting.pyc in call_w_context(*args, **kwargs)
     45                 return func(*args, **kwargs)
     46         else:
---> 47             return func(*args, **kwargs)
     48     return call_w_context
     49 

/usr/local/lib/python2.7/dist-packages/alphalens/tears.pyc in create_turnover_tear_sheet(factor_data, turnover_periods)
    415                        for q in range(1, int(quantile_factor.max()) + 1)],
    416                       axis=1)
--> 417             for p in turnover_periods}
    418 
    419     autocorrelation = pd.concat(

/usr/local/lib/python2.7/dist-packages/alphalens/tears.pyc in <dictcomp>((p,))
    415                        for q in range(1, int(quantile_factor.max()) + 1)],
    416                       axis=1)
--> 417             for p in turnover_periods}
    418 
    419     autocorrelation = pd.concat(

/usr/local/lib/python2.7/dist-packages/alphalens/performance.pyc in quantile_turnover(quantile_factor, quantile, period)
    738         shifted_idx = utils.add_custom_calendar_timedelta(
    739                 quant_name_sets.index, -pd.Timedelta(period),
--> 740                 quantile_factor.index.levels[0].freq)
    741         name_shifted = quant_name_sets.reindex(shifted_idx)
    742         name_shifted.index = quant_name_sets.index

/usr/local/lib/python2.7/dist-packages/alphalens/utils.pyc in add_custom_calendar_timedelta(input, timedelta, freq)
    915     """
    916     if not isinstance(freq, (Day, BusinessDay, CustomBusinessDay)):
--> 917         raise ValueError("freq must be Day, BDay or CustomBusinessDay")
    918     days = timedelta.components.days
    919     offset = timedelta - pd.Timedelta(days=days)

ValueError: freq must be Day, BDay or CustomBusinessDay
In [26]:
from alphalens.performance import create_pyfolio_input

import alphalens
import pyfolio

pf_returns, pf_positions, pf_benchmark = \
    create_pyfolio_input(al_data,
                         period='1D',
                         capital=1000000,
                         long_short=True,
                         group_neutral=False,
                         equal_weight=False, # Equal weight vs weight based on alpha factor
                         quantiles=[0,4], # Choose the "best" quantiles to trade based on your analysis above
                         groups=None,
                         benchmark_period='1D')
In [27]:
from pyfolio.tears import create_full_tear_sheet

create_full_tear_sheet(pf_returns,
                       positions=pf_positions,
                       benchmark_rets=pf_benchmark,
                       round_trips=True)
Start date2010-01-05
End date2017-11-07
Total months136
Backtest
Annual return 5.6%
Cumulative returns 85.4%
Annual volatility 4.6%
Sharpe ratio 1.22
Calmar ratio 0.85
Stability 0.97
Max drawdown -6.6%
Omega ratio 1.27
Sortino ratio 1.88
Skew 0.17
Kurtosis 3.49
Tail ratio 1.23
Daily value at risk -0.6%
Gross leverage 0.97
Alpha 0.06
Beta -0.25
Worst drawdown periods Net drawdown in % Peak date Valley date Recovery date Duration
0 6.59 2015-01-18 2015-04-17 2015-11-12 214
1 3.74 2011-12-22 2012-02-17 2012-04-17 84
2 3.65 2013-04-21 2013-10-07 2014-03-25 242
3 3.63 2016-02-09 2016-03-08 2016-05-05 63
4 3.61 2010-07-07 2010-11-29 2011-04-04 194
Stress Events mean min max
US downgrade/European Debt Crisis 0.04% -0.74% 0.99%
Fukushima 0.06% -0.66% 0.59%
EZB IR Event 0.06% -0.62% 0.90%
Flash Crash 0.22% -0.43% 0.99%
Apr14 0.09% -0.64% 1.11%
Oct14 0.06% -1.23% 0.77%
Fall2015 0.05% -2.17% 1.17%
Recovery 0.02% -1.19% 1.22%
New Normal 0.02% -2.17% 1.31%
Top 10 long positions of all time max
HD 2.92%
BBT 2.78%
DOV 2.65%
LH 2.49%
XOM 2.40%
CTL 2.36%
PPG 2.34%
JNJ 2.34%
JNPR 2.33%
ADM 2.31%
Top 10 short positions of all time max
ON -3.83%
P -3.70%
HZNP -3.26%
RAD -3.12%
CY -3.11%
ATVI -2.94%
DNDN_Q -2.86%
FIT -2.85%
ACIA -2.84%
TSRO -2.74%
Top 10 positions of all time max
ON 3.83%
P 3.70%
HZNP 3.26%
RAD 3.12%
CY 3.11%
ATVI 2.94%
HD 2.92%
DNDN_Q 2.86%
FIT 2.85%
ACIA 2.84%
All positions ever held max
ON 3.83%
P 3.70%
HZNP 3.26%
RAD 3.12%
CY 3.11%
ATVI 2.94%
HD 2.92%
DNDN_Q 2.86%
FIT 2.85%
ACIA 2.84%
BBT 2.78%
TSRO 2.74%
VRSN 2.67%
DOV 2.65%
MBI 2.64%
SCTY 2.52%
URI 2.51%
LH 2.49%
XOM 2.40%
GMCR 2.39%
DF 2.38%
CTL 2.36%
ARNA 2.35%
PPG 2.34%
JNJ 2.34%
JNPR 2.33%
SIRI 2.31%
ADM 2.31%
ECL 2.28%
CLF 2.26%
S 2.24%
SYK 2.21%
SSYS 2.21%
FLT 2.16%
UNP 2.14%
TSLA 2.14%
OCLR 2.13%
COG 2.09%
AKS 2.07%
ARO 2.07%
FDX 2.05%
COTY 2.05%
MCP 2.05%
SABR 2.04%
WM 2.03%
PVH 2.02%
RL 2.00%
MYL 1.98%
PAY 1.98%
STJ 1.98%
NFLX 1.97%
NKE 1.96%
MGM 1.92%
TRGP 1.91%
OLED 1.90%
CAH 1.90%
CYBR 1.90%
KBH 1.89%
THC 1.87%
CRUS 1.87%
KDP 1.85%
EQR 1.84%
DD 1.83%
RAI 1.83%
MDVN 1.82%
FEYE 1.81%
VMC 1.80%
ORLY 1.80%
GIS 1.79%
ADBE 1.79%
ESS 1.79%
PANW 1.78%
BEXP 1.78%
ZG 1.77%
LLTC 1.75%
AMD 1.75%
HFC 1.74%
STEC 1.74%
PHM 1.72%
HCA 1.72%
ESI 1.72%
HLF 1.71%
AMBA 1.69%
CF 1.68%
CELG 1.68%
GWW 1.67%
AAL 1.67%
VVUS 1.67%
KOG 1.66%
PGN 1.66%
NSC 1.66%
DAL 1.66%
ADS 1.65%
SYY 1.65%
UAL 1.65%
VNO 1.65%
CVI 1.63%
GPRO 1.63%
ARUN 1.63%
JBHT 1.62%
SJM 1.62%
PFG 1.61%
LNG 1.61%
CCL 1.61%
FNSR 1.61%
LLL 1.59%
ILMN 1.59%
HOG 1.59%
STX 1.58%
AKRX 1.57%
VECO 1.56%
DISH 1.56%
GT 1.56%
MMM 1.56%
AABA 1.56%
EMR 1.51%
WMT 1.51%
PBI 1.51%
BKD 1.51%
IONS 1.51%
SLCA 1.50%
AMZN 1.50%
LRCX 1.50%
CENX 1.50%
CLR 1.49%
OAS 1.48%
GGP 1.48%
FWLT 1.48%
ABT 1.48%
BAC 1.47%
MAN 1.47%
MBLY 1.47%
ACAD 1.47%
GLW 1.46%
PG 1.46%
TRIP 1.46%
WYNN 1.45%
ADP 1.45%
T 1.45%
FRX 1.45%
LVS 1.44%
MCK 1.44%
TER 1.44%
VRTX 1.44%
PH 1.43%
FFIV 1.43%
ASH 1.43%
DDD 1.42%
MEE 1.41%
ICPT 1.40%
AFL 1.40%
MRK 1.40%
BKNG 1.40%
DUK 1.39%
MCD 1.39%
KATE 1.39%
INTC 1.37%
MU 1.37%
ANTM 1.37%
ABC 1.36%
ADI 1.36%
ENDP 1.36%
STR 1.35%
LEA 1.35%
RSG 1.34%
ETR 1.34%
HON 1.34%
BDX 1.34%
URBN 1.33%
FTI 1.33%
MXIM 1.33%
ATHR 1.33%
WELL 1.33%
DNR 1.33%
AMT 1.32%
RCL 1.31%
TWC 1.30%
VTR 1.29%
JBLU 1.29%
RKT 1.29%
ISRG 1.29%
APKT 1.28%
CNP 1.28%
HMA 1.28%
NI 1.27%
LYB 1.27%
WSM 1.26%
RICE 1.26%
NWL 1.25%
BRK_B 1.25%
RRC 1.24%
WMB 1.24%
DATA 1.24%
OVTI 1.23%
HRI 1.23%
MCHP 1.22%
RHT 1.22%
LBTY_A 1.22%
ED 1.22%
LMT 1.21%
HSIC 1.21%
QCOR 1.21%
MMI 1.20%
SRE 1.20%
V 1.20%
ETN 1.20%
SPWR 1.20%
JAZZ 1.19%
XRAY 1.19%
BLK 1.19%
MAS 1.18%
CVX 1.18%
PEG 1.18%
MON 1.18%
XL 1.17%
MNST 1.17%
NAV 1.16%
SWN 1.15%
PAYX 1.15%
COST 1.14%
AVB 1.14%
OI 1.14%
WTW 1.14%
BXP 1.14%
CEG 1.14%
VAR 1.14%
FE 1.13%
OXY 1.13%
Q 1.13%
LVLT 1.13%
FLS 1.13%
AR 1.13%
GOOG_L 1.13%
SHW 1.13%
UNH 1.12%
DLTR 1.12%
DOW 1.12%
NRG 1.12%
NVDA 1.11%
SLG 1.11%
TMO 1.11%
BURL 1.10%
SPLK 1.09%
GPOR 1.09%
FIS 1.09%
PM 1.08%
HP 1.08%
TXN 1.08%
BLL 1.08%
NYCB 1.08%
JCI 1.07%
O 1.07%
HIG 1.07%
AMG 1.06%
EBAY 1.06%
AAOI 1.05%
HUM 1.05%
PCG 1.05%
DHI 1.05%
NBL 1.05%
ZNGA 1.05%
DIS 1.05%
BMRN 1.04%
PLD 1.04%
FTNT 1.03%
EIX 1.03%
GE 1.03%
SNDK 1.03%
SHOP 1.02%
HL 1.02%
DTE 1.02%
EOG 1.01%
GS 1.01%
CVS 1.01%
IBM 1.01%
CNC 1.01%
BWLD 1.01%
MLM 1.01%
APA 1.01%
IDCC 1.00%
JOY 1.00%
CSCO 1.00%
MLNX 0.99%
HST 0.99%
PTV 0.99%
AEO 0.99%
CRM 0.98%
CREE 0.98%
SYF 0.98%
NFX 0.98%
HAS 0.98%
TSN 0.98%
BK 0.98%
SKX 0.97%
STI 0.97%
SHLD 0.97%
RSH 0.97%
EXPE 0.97%
PRGO 0.97%
ORCL 0.96%
CHKP 0.96%
D 0.96%
TRW 0.95%
SO 0.95%
BEN 0.95%
UPS 0.95%
APD 0.95%
NUE 0.94%
UTX 0.94%
SLB 0.94%
OMC 0.94%
AMGN 0.94%
WU 0.94%
ALB 0.93%
APC 0.93%
EA 0.93%
AEP 0.93%
DISC_A 0.93%
GNW 0.92%
CMA 0.92%
YELP 0.92%
CMS 0.91%
AMP 0.91%
DECK 0.91%
HDS 0.90%
BWA 0.90%
RTN 0.90%
VER 0.89%
EMN 0.89%
PNC 0.89%
ACN 0.89%
GILD 0.89%
ITMN 0.89%
MRVL 0.88%
CB 0.88%
KIM 0.88%
TIF 0.88%
RVBD 0.88%
PFE 0.88%
NEE 0.87%
EQIX 0.87%
SAVE 0.87%
ZBH 0.87%
ROST 0.86%
TWO 0.86%
APH 0.86%
KO 0.86%
TRV 0.86%
DLR 0.85%
MTB 0.85%
VIAV 0.85%
CHK 0.85%
SBUX 0.84%
AME 0.84%
WBA 0.84%
PTEN 0.84%
HK 0.83%
NTAP 0.83%
AIG 0.83%
XEL 0.83%
SYNA 0.83%
CEPH 0.82%
ICE 0.82%
PCAR 0.82%
TRN 0.82%
FCX 0.81%
UPL 0.81%
STT 0.81%
AMLN 0.81%
CIEN 0.81%
EQT 0.81%
ROK 0.81%
BCR 0.80%
CME 0.80%
GD 0.80%
WDC 0.80%
EXC 0.80%
REGN 0.80%
FB 0.80%
SM 0.80%
BMY 0.79%
CNX 0.79%
HPQ 0.79%
OUTR 0.79%
NOV 0.79%
INCY 0.79%
CLX 0.79%
BBY 0.79%
ES 0.79%
NLY 0.79%
DXCM 0.78%
RIG 0.78%
BIIB 0.78%
GPS 0.77%
PE 0.77%
QEP 0.77%
SWKS 0.77%
AVP 0.77%
DO 0.77%
SE 0.77%
WFC 0.77%
ARNC 0.77%
ATI 0.77%
SPGI 0.77%
MO 0.76%
TJX 0.76%
SWC 0.76%
NTRS 0.76%
HRB 0.76%
MSFT 0.76%
EL 0.76%
LOW 0.76%
FLR 0.75%
JWN 0.75%
COP 0.75%
KRFT 0.75%
INFA 0.75%
CMG 0.75%
BAX 0.74%
STLD 0.74%
AXP 0.74%
PDE 0.74%
SD 0.73%
CBRE 0.73%
CERN 0.73%
VMW 0.73%
X 0.73%
KLAC 0.72%
WFM 0.72%
LITE 0.72%
UTHR 0.72%
CL 0.72%
TWTR 0.71%
DGX 0.71%
LL 0.71%
IP 0.71%
WHR 0.71%
BA 0.71%
ZAYO 0.71%
RH 0.70%
CI 0.70%
PPL 0.70%
MDT 0.70%
VLO 0.70%
HBAN 0.70%
FOSL 0.70%
ULTA 0.70%
KMX 0.70%
WY 0.69%
WFT 0.69%
RSPP 0.69%
YUM 0.69%
CAG 0.69%
TPX 0.69%
MHS 0.69%
CCI 0.69%
ANDV 0.68%
GENZ 0.68%
F 0.68%
KR 0.67%
ALL 0.67%
DVA 0.67%
CTV 0.67%
BBBY 0.67%
TGNA 0.67%
QCOM 0.66%
COF 0.66%
EW 0.66%
TTWO 0.66%
KEY 0.65%
NOW 0.65%
TMUS 0.65%
JBL 0.65%
TXT 0.65%
EP 0.65%
AAP 0.64%
BHI 0.64%
FSLR 0.64%
RAX 0.64%
GES 0.63%
APTV 0.63%
TOL 0.63%
IVZ 0.62%
OCN 0.62%
PEP 0.62%
INFO 0.62%
NE 0.62%
LB 0.62%
EXPD 0.62%
ROP 0.61%
SRCL 0.61%
TEL 0.61%
IGT 0.61%
WLTW 0.61%
PYPL 0.61%
MCO 0.60%
NVLS 0.60%
CPB 0.60%
XLNX 0.59%
WWAV 0.59%
DE 0.59%
BEAM 0.59%
AES 0.59%
KSU 0.59%
FANG 0.59%
FST 0.59%
MAT 0.59%
CMI 0.59%
TGT 0.58%
KSS 0.58%
NLC 0.58%
LNC 0.58%
EVHC 0.58%
GM 0.58%
IPG 0.57%
XRX 0.57%
MUR 0.57%
INTU 0.57%
STZ 0.57%
AKAM 0.57%
PPO 0.56%
HRL 0.56%
MPC 0.56%
ANET 0.55%
AGCO 0.55%
NBR 0.54%
WEC 0.54%
NOC 0.54%
FLIR 0.54%
SCHW 0.54%
COL 0.53%
TROW 0.53%
CRR 0.53%
MAC 0.52%
PX 0.51%
VOYA 0.51%
DELL 0.51%
ATGE 0.51%
BTU 0.50%
LNKD 0.50%
CYH 0.49%
L 0.49%
NCR 0.49%
PII 0.49%
TEX 0.48%
KCI 0.48%
PGR 0.48%
WIN 0.48%
GRUB 0.48%
NCLH 0.47%
CIT 0.47%
ALXN 0.47%
MAR 0.47%
WP 0.47%
A 0.47%
CSX 0.47%
UDR 0.47%
ZTS 0.47%
AAPL 0.46%
ADSK 0.45%
AGNC 0.45%
M 0.45%
RMBS 0.44%
TIN 0.44%
HAL 0.44%
K 0.43%
SPLS 0.43%
BEAV 0.43%
IQV 0.43%
VFC 0.41%
RF 0.41%
FISV 0.41%
FL 0.40%
NUS 0.40%
HLT 0.38%
TAP 0.38%
SEE 0.33%
AGN 0.32%
ATHN 0.31%
In [ ]: