Notebook

Import packages, data and modules

In [77]:
from quantopian.pipeline import Pipeline
from quantopian.pipeline.data import morningstar
from quantopian.pipeline.data.builtin import USEquityPricing
from quantopian.pipeline.factors import SimpleMovingAverage
from quantopian.pipeline.filters.morningstar import IsPrimaryShare
from quantopian.pipeline.data.zacks import broker_ratings
from quantopian.research import run_pipeline
from zipline.api import get_datetime
from zipline.pipeline.factors.Factor import isnan

import numpy as np
import pandas as pd
InputRejected:
Importing isnan from zipline.pipeline.factors.Factor raised an ImportError. No modules or attributes with a similar name were found.
In [8]:
def universe_filters():
    """
    Create a Pipeline producing Filters implementing common acceptance criteria.
    
    Returns
    -------
    zipline.Filter
        Filter to control tradeablility
    """
    # Primary share equities.
    primary_share = IsPrimaryShare()
    
    # Equities listed as common stock. 'ST00000001' indicates common stock.
    common_stock = morningstar.share_class_reference.security_type.latest.eq('ST00000001') 
    
    # Non-depositary receipts
    not_depositary = ~morningstar.share_class_reference.is_depositary_receipt.latest
    
    # Equities not trading over-the-counter.
    not_otc = ~morningstar.share_class_reference.exchange_id.latest.startswith('OTC')
    
    # Not when-issued equities.
    not_wi = ~morningstar.share_class_reference.symbol.latest.endswith('.WI')
    
    # Equities without LP in their name
    not_lp_name = ~morningstar.company_reference.standard_name.latest.matches('.* L[. ]?P.?$')
    
    # Equities with a null value in the limited_partnership
    not_lp_balance_sheet = morningstar.balance_sheet.limited_partnership.latest.isnull()
    
    # Equities whose most recent Morningstar market cap is not null have fundamental data and therefore are not ETFs.
    have_market_cap = morningstar.valuation.market_cap.latest.notnull()

    universe_filter = (
        primary_share
        & common_stock
        & not_depositary
        & not_otc
        & not_wi
        & not_lp_name
        & not_lp_balance_sheet
        & have_market_cap
    )
    
    return universe_filter
In [85]:
def make_pipeline():    
    #Get price data
    latest_close = USEquityPricing.close.latest
    mean_close_10 = SimpleMovingAverage(inputs=[USEquityPricing.close], window_length=10)
    percent_difference = latest_close / mean_close_10 - 1
    
    #Get key financial ratios
    price_to_book = morningstar.valuation_ratios.pb_ratio.latest #TO-DO: adjust for goodwill_and_other_intangible_assets
    price_to_earnings = morningstar.valuation_ratios.pe_ratio.latest  #TO-DO: exclude extraordinary earnings items
    debt_to_equity = morningstar.operation_ratios.total_debt_equity_ratio.latest
    financials_ratio = (1/price_to_book + 10/price_to_earnings - debt_to_equity)/3
    
    #Add time discount from last filing date
    last_filing_date = morningstar.financial_statement_filing.file_date.latest #TO-DO: check what is the most relevant statement date
    #today = get_datetime()
    #time_penalty = (today - last_filing_date - 30)^2/100000
    
    #Get analyst estimations
    rating_strong_buys = broker_ratings.rating_cnt_strong_buys.latest
    rating_buys = broker_ratings.rating_cnt_mod_buys.latest
    rating_holds = broker_ratings.rating_cnt_holds.latest
    rating_sells = broker_ratings.rating_cnt_mod_sells.latest
    rating_strong_sells = broker_ratings.rating_cnt_strong_sells.latest
        
    ratings = np.array([rating_strong_buys, rating_buys, rating_holds, rating_sells, rating_strong_sells]) #TO-DO: Replace NaNs with 0      
    """
    #Replace NaNs with 0 for calculation purposes
    
    if np.isnan(ratings).any():  
        ratings = 0
    """
    rating_weights = np.array([0.025, 0.015, 0.005, -0.005, -0.015])    
    rating_coefficient = (ratings*rating_weights).sum()
    
    #Market capitalisation component
    market_cap = morningstar.valuation.market_cap.latest
    market_cap_coefficient = 46066000/market_cap
    
    #Calculate potential
    potential = (
        financials_ratio
        + rating_coefficient
        #- time_penalty
        - market_cap_coefficient
    )
    
    screening = potential.top(25)
    
    return Pipeline(
        columns={
            'P/B': price_to_book,
            'P/E' : price_to_earnings,
            'D/E' : debt_to_equity,
            'Financials ratio' : financials_ratio,
            'Rating coefficient': rating_coefficient,
            'Market cap coefficient': market_cap_coefficient,
            'Potential': potential*100
            #'Strong buy': rating_strong_buys,
            #'Buy': rating_buys,
            #'Hold': rating_holds,
            #'Sell': rating_sells,
            #'Strong sell': rating_strong_sells
        },
        screen=universe_filters() & screening
    )
In [86]:
my_pipe = make_pipeline()
In [87]:
result = run_pipeline(my_pipe, '2013-05-05', '2013-05-05')
print 'Number of securities that passed the filter: %d' % len(result)
Number of securities that passed the filter: 17
In [89]:
result.sort('Potential', ascending=False)
Out[89]:
D/E Financials ratio Market cap coefficient P/B P/E Potential Rating coefficient
2013-05-06 00:00:00+00:00 Equity(29884 [ISR]) 0.029080 87.828538 2.594434 2.8027 0.0380 8523.910338 0.005
Equity(43201 [FIVE]) 0.487674 37.386513 0.022522 28.9017 0.0888 3745.399058 0.090
Equity(29621 [LODE]) 0.097171 13.640118 0.413393 4.9702 0.2450 1326.672554 0.040
Equity(6656 [NEON]) 0.044503 11.183736 0.238153 36.4964 0.2979 1099.558282 0.050
Equity(29064 [CXPO]) 2.998028 6.637083 0.321953 1.8943 0.4468 637.513040 0.060
Equity(10748 [EMMS]) 3.417545 5.739171 0.741030 0.0859 1.1119 500.314073 0.005
Equity(26740 [NRF]) 3.443830 3.372239 0.023305 1.8242 0.7685 340.393435 0.055
Equity(18027 [AI]) 0.027482 2.318027 0.102667 0.8220 1.7346 225.035965 0.035
Equity(20479 [QTM]) 1.884330 2.251266 0.132524 0.1159 1000.0000 214.874153 0.030
Equity(27370 [EGLE]) 1.926753 2.876399 0.786564 0.0978 30.2115 206.983431 -0.020
Equity(24834 [CECO]) 0.000000 2.315248 0.313735 0.2462 3.4674 199.151307 -0.010
Equity(40530 [TROX]) 0.580710 1.622407 0.019788 0.9391 2.2815 163.761908 0.035
Equity(19127 [KCG]) 0.264110 1.632588 0.036358 0.8526 2.5069 161.622945 0.020
Equity(764 [OMX]) 0.964460 1.564368 0.046001 0.9394 2.1772 161.336751 0.095
Equity(9472 [STLY]) 0.000000 2.240239 0.805071 0.6731 1.9102 147.016812 0.035
Equity(27763 [NM]) 1.182517 1.509206 0.098496 0.3929 3.1596 144.071022 0.030
Equity(38989 [AOL]) 0.034439 1.240882 0.015423 1.3716 3.3025 141.545904 0.190
In [ ]: