Notebook
In [17]:
from quantopian.pipeline import Pipeline
from quantopian.research import run_pipeline, volumes, prices
from quantopian.pipeline.data import Fundamentals, USEquityPricing
from quantopian.pipeline.factors import SimpleMovingAverage, ExponentialWeightedMovingAverage, Returns, MACDSignal, VWAP
from quantopian.pipeline.filters import QTradableStocksUS
from quantopian.pipeline.classifiers.fundamentals import Sector
import pandas as pd
import numpy as np
In [39]:
def make_pipeline():
    
    base_universe = QTradableStocksUS()
    factor_to_analyze = 0
    
    #Variables
    roe = Fundamentals.roe.latest
    sma_200 = SimpleMovingAverage(inputs=[USEquityPricing.close], window_length=200, mask=base_universe)
    sma_20 = SimpleMovingAverage(inputs=[USEquityPricing.close], window_length=20, mask=base_universe)
    ema_9 = ExponentialWeightedMovingAverage(inputs=[USEquityPricing.close], window_length=9, decay_rate=0.875, mask=base_universe)
    ema_12 = ExponentialWeightedMovingAverage(inputs=[USEquityPricing.close], window_length=12, decay_rate=0.875, mask=base_universe)
    ema_26 = ExponentialWeightedMovingAverage(inputs=[USEquityPricing.close], window_length=26, decay_rate=0.875, mask=base_universe)
    macd = MACDSignal()
    volume = USEquityPricing.volume.latest
    price = USEquityPricing.close.latest
    average_volume = SimpleMovingAverage(inputs=[USEquityPricing.volume], window_length=200, mask=base_universe)
    recent_change = Returns(window_length=2, mask=base_universe)
    year_performance = Returns(window_length=365, mask=base_universe)
    month_performance = Returns(window_length=20, mask=base_universe)
    week_performance = Returns(window_length=5, mask=base_universe)
    eps = Fundamentals.basic_eps_earnings_reports.latest
    eps_growth = Fundamentals.diluted_eps_growth.latest
    volume_filter = volume > 500000
    average_volume_filter = average_volume > 500000
    
    if price > sma_200:
        factor_to_analyze = factor_to_analyze + 1
    else:
        factor_to_analyze = factor_to_analyze - 1
    
    if roe > 0.1:
        factor_to_analyze = factor_to_analyze + 1
        
    if macd > 0:
        factor_to_analyze = factor_to_analyze + 1
    else:
        factor_to_analyze = factor_to_analyze - 1
        
    if ema_9 > 0:
        factor_to_analyze = factor_to_analyze + 1
    else:
        factor_to_analyze = factor_to_analyze - 1
        
    if year_performance > 0:
        factor_to_analyze = factor_to_analyze + 1
    else:
        factor_to_analyze = factor_to_analyze - 1
        
    if month_performance > 0 and week_performance < 0 and ema_9 > 0:
        factor_to_analyze = factor_to_analyze + 1
    elif month_performance < 0 and week_performance < 0:
        factor_to_analyze = factor_to_analyze - 1
        
    if recent_change > 0:
        factor_to_analyze = factor_to_analyze + 1
    else:
        factor_to_analyze = factor_to_analyze - 1  
    
    if eps > 0:
        factor_to_analyze = factor_to_analyze + 1
    else:
        factor_to_analyze = factor_to_analyze - 1
        
    if eps_growth > 0:
        factor_to_analyze = factor_to_analyze + 1
    else:
        factor_to_analyze = factor_to_analyze - 1
            
    universe = base_universe & volume_filter & average_volume_filter
    
    return Pipeline(
        columns = {'Price': price, 'factor_to_analyze': factor_to_analyze},
        screen = universe
    )
In [40]:
period_start = '2017-01-10'
period_end = '2018-06-10'

pipeline_output = run_pipeline(make_pipeline(), period_start, period_end)
pipeline_output.head(5)

TypeErrorTraceback (most recent call last)
<ipython-input-40-ca07f035ed01> in <module>()
      2 period_end = '2018-06-10'
      3 
----> 4 pipeline_output = run_pipeline(make_pipeline(), period_start, period_end)
      5 pipeline_output.head(5)

<ipython-input-39-c1b4217d46c6> in make_pipeline()
     33     return Pipeline(
     34         columns = {'Price': price, 'factor_to_analyze': factor_to_analyze},
---> 35         screen = universe
     36     )

/build/src/qexec_repo/zipline_repo/zipline/pipeline/pipeline.py in __init__(self, columns, screen, domain)
     44         domain=Domain
     45     )
---> 46     def __init__(self, columns=None, screen=None, domain=GENERIC):
     47         if columns is None:
     48             columns = {}

/build/src/qexec_repo/zipline_repo/zipline/pipeline/pipeline.pyc in __init__(self, columns, screen, domain)
     50         validate_column = self.validate_column
     51         for column_name, term in columns.items():
---> 52             validate_column(column_name, term)
     53             if not isinstance(term, ComputableTerm):
     54                 raise TypeError(

/build/src/qexec_repo/zipline_repo/zipline/pipeline/pipeline.py in validate_column(column_name, term)
    249     @expect_types(term=Term, column_name=six.string_types)
    250     def validate_column(column_name, term):
--> 251         if term.ndim == 1:
    252             raise UnsupportedPipelineOutput(column_name=column_name, term=term)
    253 

/build/src/qexec_repo/zipline_repo/zipline/utils/input_validation.pyc in _check(func, argname, argvalue)
    451                     'funcname': get_funcname(func),
    452                     'argname': argname,
--> 453                     'actual': actual(argvalue),
    454                 },
    455             )

TypeError: zipline.pipeline.pipeline.validate_column() expected a value of type zipline.pipeline.term.Term for argument 'term', but got int instead.
In [ ]:
len(pipeline_output)
In [ ]:
pricing_data = get_pricing(
  symbols=pipeline_output.index.levels[1], # Finds all assets that appear at least once in "factor_data"  
  start_date=period_start,
  end_date='2019-03-10', # must be after run_pipeline()'s end date. Explained more in lesson 4
  fields='open_price' # Generally, you should use open pricing. Explained more in lesson 4
)

# Show the first 5 rows of pricing_data
pricing_data.head(5)
In [ ]:
from alphalens.utils import get_clean_factor_and_forward_returns

merged_data = get_clean_factor_and_forward_returns(
  factor=pipeline_output['factor_to_analyze'], 
  prices=pricing_data, quantiles=2

)

# Show the first 5 rows of merged_data
merged_data.head(5)
In [ ]:
from alphalens.tears import create_full_tear_sheet, create_information_tear_sheet

create_information_tear_sheet(merged_data)
In [ ]:
from alphalens.tears import create_returns_tear_sheet

create_returns_tear_sheet(merged_data)
In [ ]:
from alphalens.tears import create_returns_tear_sheet

sector_labels, sector_labels[-1] = dict(Sector.SECTOR_NAMES), "Unknown"

factor_data = get_clean_factor_and_forward_returns(
    pipeline_output['factor_to_analyze'],
    prices=pricing_data,
    groupby=pipeline_output['sector'],
    groupby_labels=sector_labels,
    binning_by_group=True,
)

create_returns_tear_sheet(factor_data, by_group=True, group_neutral=True)
In [ ]: