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
from quantopian.pipeline.data.builtin import USEquityPricing
from quantopian.pipeline.data import Fundamentals
import math

# 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 [3]:
# 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
#my_factor = factset.Fundamentals..latest.log().winsorize(.005, .995)

class Volatility(CustomFactor):  
    inputs = [USEquityPricing.close]  
    window_length = 20  
    def compute(self, today, assets, out, close):  
        #[0:-1] is needed to remove last close since diff is one element shorter  
        daily_returns = np.diff(close, axis = 0) / close[0:-1]  
        out[:] = daily_returns.std(axis = 0) * math.sqrt(252)
        
#my_factor = Fundamentals.pb_ratio.latest.log().winsorize(.005, .995)
my_factor = -Volatility().winsorize(.005, .995)

# 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 [4]:
# Call evaluate_factor on your factor to get Alphalens-formatted data.
al_data = evaluate_factor(
    factor = my_factor, 
    domain = US_EQUITIES, 
    start_date = '2014-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 = 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 [5]:
# 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 -2.723850 -0.219742 -0.492690 0.212227 96355 20.109863
1 -0.602208 -0.153950 -0.279753 0.064117 95697 19.972534
2 -0.441733 -0.115144 -0.216528 0.050983 95731 19.979630
3 -0.351129 -0.091775 -0.174064 0.043948 95720 19.977335
4 -0.293907 -0.008494 -0.125946 0.041072 95640 19.960638
Returns Analysis
1D 5D 10D
Ann. alpha 0.127 0.130 0.129
beta -0.503 -0.523 -0.500
Mean Period Wise Return Top Quantile (bps) 3.430 3.179 2.877
Mean Period Wise Return Bottom Quantile (bps) -5.411 -5.608 -5.648
Mean Period Wise Spread (bps) 8.842 8.884 8.623
/usr/local/lib/python2.7/dist-packages/alphalens/tears.py:258: UserWarning: 'freq' not set in factor_data index: assuming business day
  UserWarning
<matplotlib.figure.Figure at 0x7f99007db310>
Information Analysis
1D 5D 10D
IC Mean 0.025 0.047 0.061
IC Std. 0.210 0.198 0.196
Risk-Adjusted IC 0.121 0.236 0.312
t-stat(IC) 3.764 7.337 9.714
p-value(IC) 0.000 0.000 0.000
IC Skew -0.002 -0.089 -0.109
IC Kurtosis -0.192 -0.219 -0.410

ValueErrorTraceback (most recent call last)
<ipython-input-5-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 [6]:
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 [7]:
sns.violinplot(x="factor_quantile", y="1D",
               split=True, inner="quart",
               data=al_data)
Out[7]:
<matplotlib.axes._subplots.AxesSubplot at 0x7f98e3024490>

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 [8]:
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')
/usr/local/lib/python2.7/dist-packages/alphalens/performance.py:394: UserWarning: 'freq' not set, using business day calendar
  UserWarning)
/usr/local/lib/python2.7/dist-packages/alphalens/performance.py:541: UserWarning: 'freq' not set, using business day calendar
  UserWarning)
In [9]:
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 date2014-01-03
End date2017-11-07
Total months66
Backtest
Annual return 8.9%
Cumulative returns 60.5%
Annual volatility 9.1%
Sharpe ratio 0.98
Calmar ratio 0.60
Stability 0.87
Max drawdown -14.8%
Omega ratio 1.23
Sortino ratio 1.44
Skew 0.04
Kurtosis 5.56
Tail ratio 1.04
Daily value at risk -1.1%
Gross leverage 0.96
Alpha 0.10
Beta -0.62
Worst drawdown periods Net drawdown in % Peak date Valley date Recovery date Duration
0 14.84 2016-01-20 2016-04-25 2017-02-08 276
1 8.62 2015-02-01 2015-04-20 2015-07-28 127
2 5.46 2015-08-24 2015-09-01 2015-09-29 27
3 5.21 2017-08-22 2017-10-04 NaT NaN
4 4.90 2015-09-30 2015-10-07 2016-01-12 75
/usr/local/lib/python2.7/dist-packages/numpy/lib/function_base.py:3834: RuntimeWarning: Invalid value encountered in percentile
  RuntimeWarning)
Stress Events mean min max
Apr14 0.21% -1.33% 2.03%
Oct14 0.08% -2.01% 1.36%
Fall2015 0.08% -2.11% 1.74%
New Normal 0.04% -3.08% 3.68%
Top 10 long positions of all time max
SIAL 1.20%
PCP 1.17%
PLL 0.97%
TRW 0.97%
HSP 0.97%
OCR 0.94%
ALTR 0.93%
LNKD 0.92%
BEAM 0.91%
LIFE 0.91%
Top 10 short positions of all time max
ARIA -5.72%
PLUG -5.62%
LBTY_A -5.53%
SRPT -5.40%
GMCR -5.23%
ANAC -5.09%
EBAY -5.08%
RH -4.85%
SUNE -4.81%
DISC_A -4.69%
Top 10 positions of all time max
ARIA 5.72%
PLUG 5.62%
LBTY_A 5.53%
SRPT 5.40%
GMCR 5.23%
ANAC 5.09%
EBAY 5.08%
RH 4.85%
SUNE 4.81%
DISC_A 4.69%
All positions ever held max
ARIA 5.72%
PLUG 5.62%
LBTY_A 5.53%
SRPT 5.40%
GMCR 5.23%
ANAC 5.09%
EBAY 5.08%
RH 4.85%
SUNE 4.81%
DISC_A 4.69%
GOOG_L 4.65%
VRTX 4.47%
RAD 4.37%
UAA 4.30%
NRF 4.23%
ITMN 4.13%
CLVS 4.08%
LNKD 4.08%
OCN 3.94%
BTU 3.80%
DXCM 3.66%
IONS 3.66%
KRFT 3.60%
SKX 3.53%
MNST 3.45%
AMBA 3.38%
WMB 3.33%
CAM 3.32%
ENDP 3.29%
CBI 3.15%
AAOI 3.12%
HTZ 3.11%
YELP 3.10%
HPQ 3.10%
ARNC 3.09%
CHK 3.05%
TWTR 3.04%
X 3.03%
LL 3.03%
OAS 2.98%
ALTR 2.95%
CB 2.95%
BLUE 2.93%
FL 2.89%
GNW 2.86%
HZNP 2.85%
SYNA 2.82%
CPRI 2.81%
HLF 2.80%
JCP 2.76%
EVHC 2.76%
SPLK 2.72%
HSP 2.71%
MBLY 2.69%
FCX 2.68%
NUS 2.66%
WFT 2.63%
CLF 2.60%
CSIQ 2.58%
KITE 2.58%
NRG 2.58%
FIT 2.58%
SODA 2.57%
BBY 2.56%
HUM 2.55%
WLL 2.53%
SCTY 2.51%
SLXP 2.51%
CBST 2.51%
FOSL 2.49%
GTAT 2.47%
TPX 2.45%
BRCM 2.45%
TWLO 2.41%
ULTA 2.40%
DNR 2.39%
S 2.39%
AMD 2.39%
HAIN 2.37%
WLT 2.34%
PCYC 2.33%
LULU 2.33%
ILMN 2.29%
FRX 2.27%
FEYE 2.26%
DATA 2.24%
WFM 2.24%
SSYS 2.23%
ICPT 2.22%
LLTC 2.20%
P 2.17%
FTR 2.16%
CYH 2.15%
MU 2.14%
PANW 2.14%
WOOF 2.14%
CSX 2.14%
FSLR 2.14%
EXEL 2.12%
GRPN 2.11%
ADT 2.11%
SM 2.10%
FDO 2.07%
ESV 2.02%
SRC 2.00%
RCPT 1.99%
EFX 1.99%
WPX 1.99%
SLCA 1.97%
DKS 1.97%
RICE 1.97%
SNAP 1.97%
ACIA 1.96%
RAX 1.95%
AKS 1.93%
GPRO 1.92%
TRIP 1.90%
GRUB 1.90%
NE 1.89%
SWN 1.88%
NVDA 1.88%
ANR 1.87%
CNX 1.83%
GME 1.82%
KSS 1.82%
COV 1.79%
MDVN 1.79%
CCEP 1.78%
CLR 1.78%
URBN 1.75%
ZNGA 1.72%
ACAD 1.72%
AAP 1.71%
ARG 1.71%
MCK 1.70%
NWL 1.69%
YNDX 1.68%
ALXN 1.68%
CAG 1.68%
ZTS 1.68%
CIEN 1.67%
QCOR 1.67%
SNDK 1.67%
BIIB 1.65%
PRGO 1.65%
PLL 1.65%
GLNG 1.64%
STX 1.64%
MYL 1.62%
BCR 1.62%
HOG 1.62%
MJN 1.61%
OCLR 1.61%
CYBR 1.60%
NFLX 1.58%
JUNO 1.58%
ANF 1.57%
ZG 1.57%
WYNN 1.56%
SPWR 1.54%
GPOR 1.54%
VER 1.53%
MAT 1.53%
TWX 1.53%
CNQR 1.51%
CELG 1.51%
ACHN 1.51%
TSLA 1.50%
NBR 1.50%
AVP 1.49%
EA 1.49%
RIG 1.48%
CAR 1.47%
ORLY 1.46%
SINA 1.44%
BBBY 1.41%
KMX 1.41%
STJ 1.40%
ISRG 1.39%
OKE 1.39%
IGT 1.39%
SIG 1.39%
CREE 1.38%
TRN 1.38%
BEAM 1.37%
M 1.37%
DDD 1.37%
PCG 1.36%
HRI 1.35%
ANET 1.35%
AKAM 1.35%
MNK 1.35%
DG 1.34%
KR 1.33%
MUR 1.33%
CMG 1.32%
HAR 1.32%
ATVI 1.31%
CF 1.31%
RRC 1.30%
MRO 1.29%
WNR 1.29%
NFX 1.29%
WDAY 1.28%
CNC 1.27%
HBI 1.27%
EW 1.26%
W 1.25%
SYF 1.25%
EXPE 1.24%
PNRA 1.24%
UAL 1.24%
INCY 1.23%
NTAP 1.22%
NLSN 1.22%
QRVO 1.22%
AEO 1.21%
AYI 1.21%
SIAL 1.20%
SHOP 1.20%
BHI 1.20%
BMRN 1.20%
TXT 1.19%
MRVL 1.18%
TSRO 1.17%
HDS 1.17%
PCP 1.17%
TSCO 1.16%
SWKS 1.16%
WBA 1.15%
DVN 1.15%
THC 1.15%
SPLS 1.15%
PBI 1.15%
ATHN 1.14%
MELI 1.13%
SRCL 1.12%
GWW 1.12%
CI 1.12%
RHT 1.12%
LB 1.11%
CXO 1.11%
CTL 1.10%
AAL 1.10%
KMI 1.10%
AA 1.09%
BMY 1.08%
WWAV 1.08%
UHS 1.08%
NOW 1.07%
JAZZ 1.06%
JWN 1.06%
AVGO 1.06%
LITE 1.06%
ADBE 1.05%
GPS 1.05%
ALK 1.04%
SYMC 1.03%
AMZN 1.02%
JBLU 1.02%
VMW 1.02%
CTSH 1.01%
PTEN 1.01%
BG 1.00%
ALGN 0.99%
URI 0.99%
RL 0.97%
TRW 0.97%
TMUS 0.97%
RFMD 0.97%
PETM 0.97%
TPR 0.97%
FANG 0.96%
SE 0.96%
FNSR 0.96%
GNC 0.95%
GILD 0.95%
HSY 0.95%
YUMC 0.95%
JOY 0.95%
WDC 0.95%
LO 0.94%
OCR 0.94%
ABC 0.93%
YUM 0.93%
XLNX 0.92%
AGN 0.91%
MLM 0.91%
CLB 0.91%
LIFE 0.91%
DRC 0.90%
ADSK 0.90%
QEP 0.90%
RAI 0.90%
SNI 0.89%
NEM 0.89%
LVS 0.88%
HAS 0.88%
CFN 0.88%
PE 0.88%
QCOM 0.87%
AET 0.87%
SAVE 0.86%
DVA 0.86%
DO 0.86%
NKE 0.85%
CRM 0.85%
APC 0.85%
HSH 0.84%
FB 0.84%
DE 0.84%
REGN 0.84%
NCLH 0.83%
KSU 0.82%
MGM 0.82%
BRCD 0.82%
DECK 0.81%
BSX 0.81%
ZBH 0.81%
CPGX 0.80%
LLL 0.80%
HFC 0.79%
AGN 0.79%
DTV 0.78%
TSN 0.78%
WM 0.78%
TAP 0.77%
AMTD 0.77%
COG 0.77%
AKRX 0.77%
SWY 0.76%
APA 0.76%
BURL 0.76%
NXPI 0.75%
MON 0.75%
DHI 0.75%
NBL 0.75%
CVC 0.75%
KATE 0.75%
UTHR 0.75%
BKD 0.74%
COL 0.74%
HP 0.74%
LNG 0.73%
TIF 0.73%
NLY 0.72%
CAH 0.72%
FTI 0.72%
HAL 0.72%
MOS 0.72%
LNC 0.72%
AGNC 0.72%
IPG 0.72%
DUK 0.72%
STLD 0.71%
SYY 0.71%
TIBX 0.71%
IVZ 0.71%
VTR 0.71%
DLTR 0.71%
EMC 0.70%
CPN 0.70%
HES 0.70%
CHKP 0.70%
PVH 0.70%
DD 0.70%
GIS 0.69%
PEP 0.69%
UPS 0.69%
PX 0.69%
KO 0.69%
FIS 0.68%
COTY 0.68%
DNKN 0.68%
MCD 0.68%
MDLZ 0.68%
WMT 0.68%
KLAC 0.68%
AABA 0.68%
PG 0.68%
SO 0.67%
LUV 0.67%
T 0.67%
HCA 0.67%
LMT 0.67%
NEE 0.67%
PPL 0.67%
BAX 0.67%
LYB 0.67%
D 0.67%
DOW 0.67%
PM 0.67%
PXD 0.67%
PFE 0.67%
CPB 0.67%
CHRW 0.67%
JPM 0.67%
LRCX 0.67%
VZ 0.66%
PGR 0.66%
WEC 0.66%
PSA 0.66%
MO 0.66%
KMB 0.66%
WELL 0.66%
GE 0.66%
STZ 0.66%
K 0.66%
TEL 0.66%
AIG 0.66%
JNJ 0.66%
CL 0.66%
BDX 0.66%
VFC 0.66%
CLX 0.66%
XOM 0.66%
IR 0.66%
CMS 0.66%
HST 0.66%
MMC 0.66%
ALL 0.66%
HD 0.66%
ICE 0.66%
CB 0.66%
ED 0.66%
SRE 0.65%
AVB 0.65%
AMAT 0.65%
DHR 0.65%
ESRX 0.65%
EQR 0.65%
CVS 0.65%
CMI 0.65%
AMT 0.65%
GGP 0.65%
BWLD 0.65%
UTX 0.65%
PAYX 0.65%
KBH 0.65%
PPG 0.65%
WHR 0.65%
EL 0.65%
XEL 0.65%
PEG 0.65%
EIX 0.65%
ORCL 0.65%
EQT 0.65%
TMO 0.65%
LH 0.64%
HCP 0.64%
SHW 0.64%
GLW 0.64%
KOG 0.64%
ADI 0.64%
AFL 0.64%
KDP 0.64%
SPG 0.64%
AON 0.64%
SEE 0.64%
CCI 0.64%
MMM 0.64%
NOV 0.64%
FLT 0.64%
LVLT 0.64%
HIG 0.64%
INTU 0.64%
TWC 0.63%
CA 0.63%
AZO 0.63%
ECL 0.63%
DIS 0.63%
CSC 0.63%
FFIV 0.63%
SYK 0.63%
CVX 0.63%
COST 0.63%
MRK 0.63%
PNC 0.63%
ADP 0.63%
AEP 0.63%
HON 0.63%
USB 0.63%
FCAU 0.62%
ITW 0.62%
ROP 0.62%
MSI 0.62%
IBM 0.62%
FDX 0.62%
SIRI 0.62%
BRK_B 0.62%
UNH 0.62%
ETFC 0.62%
CMCS_A 0.62%
TGT 0.62%
WY 0.62%
ABT 0.62%
ROST 0.62%
COP 0.62%
TRV 0.62%
APD 0.62%
KIM 0.62%
FISV 0.61%
MCO 0.61%
HRB 0.61%
CSCO 0.61%
CCL 0.61%
ASH 0.61%
ROC 0.61%
SJM 0.61%
SWK 0.61%
FE 0.61%
COF 0.61%
VLO 0.61%
O 0.61%
NOC 0.61%
XL 0.61%
V 0.61%
SBAC 0.61%
MAC 0.61%
ACN 0.61%
MTB 0.60%
OMC 0.60%
LLY 0.60%
MDT 0.60%
BWA 0.60%
RTN 0.60%
SPGI 0.60%
MXIM 0.60%
JNPR 0.60%
DPZ 0.60%
WYND 0.60%
GS 0.60%
WP 0.60%
DXC 0.60%
AXP 0.60%
LOW 0.60%
ETR 0.60%
PSX 0.60%
AMP 0.60%
MSFT 0.60%
EMR 0.60%
BKNG 0.60%
CBRE 0.60%
CERN 0.59%
TROW 0.59%
HRL 0.59%
SBUX 0.59%
BEN 0.59%
FITB 0.59%
WFC 0.59%
PLD 0.59%
KHC 0.59%
HSIC 0.59%
BK 0.59%
GD 0.59%
STT 0.59%
AER 0.58%
MPC 0.58%
CME 0.58%
CAT 0.58%
C 0.58%
CC 0.58%
BBT 0.58%
ADM 0.58%
DGX 0.58%
BLL 0.58%
MAR 0.58%
APTV 0.58%
AAPL 0.58%
TDG 0.58%
DVMT 0.58%
LEA 0.58%
BAC 0.58%
DTE 0.58%
RKT 0.58%
TTWO 0.58%
ABBV 0.58%
ADS 0.58%
SLB 0.58%
INTC 0.58%
TXN 0.58%
EXC 0.58%
CHTR 0.58%
BLK 0.57%
AEE 0.57%
TOL 0.57%
OXY 0.57%
WLTW 0.57%
FOXA 0.57%
IP 0.57%
BXP 0.57%
CIT 0.57%
MA 0.57%
CBS 0.57%
PYPL 0.57%
CNP 0.57%
COO 0.57%
SABR 0.56%
CTXS 0.56%
BA 0.56%
JCI 0.56%
ROK 0.56%
RCL 0.56%
ZAYO 0.56%
PNR 0.56%
UNP 0.56%
DOV 0.56%
KEY 0.56%
PRU 0.56%
GXP 0.56%
NUAN 0.56%
HLT 0.56%
TJX 0.56%
MCHP 0.56%
PH 0.56%
EQIX 0.56%
PCAR 0.56%
NSC 0.56%
HBAN 0.56%
EMN 0.55%
GT 0.55%
TDC 0.55%
INFO 0.55%
AME 0.55%
DFS 0.55%
GRMN 0.55%
MHK 0.55%
JCI 0.55%
A 0.55%
EOG 0.55%
DRI 0.55%
ANTM 0.55%
GM 0.55%
ES 0.55%
XEC 0.55%
DLR 0.55%
STI 0.55%
FAST 0.55%
MS 0.54%
DISH 0.54%
VOYA 0.54%
ETN 0.54%
CIE 0.54%
VNO 0.54%
DAL 0.54%
NTRS 0.54%
VMC 0.54%
MET 0.54%
SCHW 0.54%
MAS 0.53%
HOT 0.53%
WSM 0.53%
AWK 0.53%
HOLX 0.53%
TRGP 0.53%
XRAY 0.53%
PII 0.53%
NYCB 0.53%
LMCA 0.53%
ON 0.52%
NWSA 0.52%
GPN 0.52%
F 0.52%
VRSK 0.52%
IQV 0.52%
UPL 0.52%
CMA 0.51%
RSPP 0.51%
WU 0.51%
TW 0.51%
AMGN 0.51%
FTV 0.51%
RF 0.51%
ALB 0.50%
IAC 0.49%
HPE 0.49%
ZION 0.49%
CY 0.49%
SLM 0.49%
PHM 0.48%
CFG 0.48%
FNF 0.48%
SNA 0.47%
AES 0.47%
WIN 0.47%
OII 0.47%
ODP 0.46%
LEN 0.46%
COLE 0.46%
XRX 0.46%
ANDV 0.46%
NUE 0.46%
NI 0.46%
BXLT 0.46%
BEAV 0.45%
JAH 0.45%
SQ 0.45%
ALLY 0.44%
FMC 0.44%
COMM 0.44%
HUN 0.44%
SOHU 0.44%
EXAS 0.44%
FRC 0.44%
FLR 0.42%
AMG 0.41%
RDN 0.38%
TEX 0.37%
AR 0.36%
OLED 0.33%
RLGY 0.31%
NPSP 0.26%
OC 0.23%
WRK 0.20%
EXR 0.18%
WAB 0.12%
NCR 0.12%
FLS 0.09%
FSL 0.09%
OIS 0.09%
In [ ]: