Quantopian's community platform is shutting down. Please read this post for more information and download your code.
Back to Community
Very slow fundamental access with pipeline
# Import the libraries we will use here  
import math  
import numpy as np  
import pandas  
from scipy.optimize import minimize  
from quantopian.algorithm import attach_pipeline, pipeline_output  
from quantopian.pipeline import Pipeline  
from quantopian.pipeline.data.builtin import USEquityPricing  
from quantopian.pipeline import CustomFactor  
from quantopian.pipeline.factors import SimpleMovingAverage,AverageDollarVolume  
from quantopian.pipeline.data import morningstar

class Mean(CustomFactor):  
    inputs = [USEquityPricing.close]

    def compute(self, today, asset_ids, out, close):  
        r = np.diff(close, axis=0) / close[0:-1]  
        mean = np.mean(r,axis=0)  
        out[:] = mean  
class Variance(CustomFactor):  
    inputs = [USEquityPricing.close]

    def compute(self, today, asset_ids, out, close):  
        r = np.diff(close, axis=0) / close[0:-1]  
        var = np.var(r,axis=0)  
        out[:] = var

class Value(CustomFactor):  
    inputs = [morningstar.valuation_ratios.ev_to_ebitda]

    def compute(self, today, asset_ids, out, ratio):  
        out[:] = 1.0/ratio[-1]  
class Quality(CustomFactor):  
    inputs = [morningstar.cash_flow_statement.free_cash_flow,morningstar.balance_sheet.net_debt]

    def compute(self, today, asset_ids, out, fcf, debt):  
        out[:] = fcf[-1]/debt[-1]  
class Growth(CustomFactor):  
    inputs = [morningstar.earnings_ratios.diluted_eps_growth]

    def compute(self, today, asset_ids, out, ratio):  
        out[:] = ratio[-1]  
class Volume(CustomFactor):  
    inputs = [USEquityPricing.volume]

    def compute(self, today, asset_ids, out, vol):  
        out[:] = np.nan_to_num(np.mean(vol,axis=0))  
# The initialize function is the place to set your tradable universe and define any parameters.  
def initialize(context):  
    set_symbol_lookup_date('2016-01-01')  
    # OPTIONS ###################################  
    # context.random_universe = False  
    context.random_universe = True  
    context.securities = []  
    context.longs = []  
    context.shorts = []  
    context.leverage = {}  
    context.benchmark = symbol('SPY')  
    context.riskless = symbol('SHY')  
    context.riskless_apr = 1.005 # Assumed rate of riskless investment  
    # context.riskless = symbol('BSV')  
    # context.riskless_apr = 1.01 # Assumed rate of riskless investment  
    context.ignore = [ # Stocks to ignore when picking  
        context.riskless,  
        context.benchmark,  
    ]  
    context.max_drawdown = 1.0 # Portion of portfolio to risk  
    context.risk_leverage = 1.0 # Portion leverage = max_drawdown * risk_leverage  
    context.curr_risk = context.portfolio.portfolio_value*context.max_drawdown  
    context.max_risk = context.curr_risk  
    context.port_ceil = context.portfolio.portfolio_value  
    context.recalculate_period_days = 10  
    context.trade_period_days = 1  
    context.lookback = 21*12 # Number of previous days to sample  
    # context.minute_mode_only = True  
    context.minute_mode_only = False  
    # context.hold_cash = False # Use or don't use excess cash to invest in riskless  
    context.hold_cash = True # Use or don't use excess cash to invest in riskless  
    context.hedge = True  
    # context.hedge = False  
    context.hedge_shortable = False  
    # context.hedge_shortable = True  
    context.always_shorted = False  
    context.hedge_kelly_limit = True  
    context.hedge_max_variance = 999  
    context.hedge_short_long_ratio = 0.1  
    context._day_count = -1  
    context._first_traded = False  
    context.borrowing_rate = 1.02  
    context.accrued_interest = 0  
    context.pick_period = context.recalculate_period_days  
    context.long_size = 10  
    context.short_size = 10  
    context.alpha = 1.0  
    context.drawdown_trigger = 0.10  
    context.trigger_fraction = 1.00  
    context.max_pct_liquidity = 0.10  
    # END #######################################  
    if context.random_universe == False:  
        context.universe = symbols(  
            # 'EDV',  
            # 'VTI',  
            # 'VNQ',  
            # 'VNQI',  
            # 'VPL',  
            # 'VGK',  
            # 'VWO',  
            # 'VDE',  
            # 'BIV',  
            'VTI', # USA  
            'IYR', # REIT  
            'EZU', # Europe  
            'EWJ', # Japan  
            'EEM', # Emerging  
            'IYE', # US Energy  
            'TLT', # 20+ Treasury  
            'IEF', # 7-10 Treasury  
            'LQD', # Corporate bonds  
            'DBC', # Commodities index  
            'FXE', # Euro  
            'FXY', # Yen  
            'XIV',  
        )  
        context.universe_yield = dict.fromkeys(context.universe,1.00)  
        custom_yield = {  
            # 'EDV' :1.025,  
            # 'VTI' :1.02,  
            # 'VNQ' :1.025,  
            # 'VNQI':1.025,  
            # 'VPL' :1.02,  
            # 'VGK' :1.02,  
            # 'VWO' :1.02,  
            # 'VDE' :1.02,  
            # 'BIV' :1.02,  
            'VTI':1.02,  
            'IYR':1.03,  
            'EZU':1.02,  
            'EWJ':1.01,  
            'EEM':1.02,  
            'IYE':1.02,  
            'TLT':1.02,  
            'IEF':1.015,  
            'LQD':1.03,  
        }  
        for sec in context.universe:  
            if sec.symbol in custom_yield:  
                context.universe_yield[sec] = custom_yield[sec.symbol]  
    if context.random_universe == True:  
        pipe = Pipeline()  
        attach_pipeline(pipe, name='my_pipeline')  
        mean = Mean(window_length = context.lookback)  
        var = Variance(window_length = context.lookback)  
        f1 = (mean - var/2.0)  
        f2 = Value(window_length = context.lookback)  
        f3 = Quality(window_length = context.lookback)  
        f4 = Growth(window_length = context.lookback)  
        pipe.add(f1,'f1')  
        pipe.add(f2,'f2')  
        pipe.add(f3,'f3')  
        pipe.add(f4,'f4')

def before_trading_start(context,data):  
    if not context._first_traded:  
        context._day_count = -1

    context._day_count += 1

    if context.random_universe and context._day_count % context.pick_period == 0:  
        context.universe = pipeline_output('my_pipeline').dropna(axis=0)  
        context.universe = context.universe[~context.universe.index.isin(context.ignore)]  
        context.universe = context.universe[~context.universe.index.isin(security_lists.leveraged_etf_list)]  
        context.universe = context.universe.rank().mean(axis=1).order()  
        longs = context.universe.tail(context.long_size)  
        shorts = context.universe.head(context.short_size)  
        context.universe = pandas.concat((longs,shorts)).index  
        context.universe_yield = dict.fromkeys(context.universe,1.00)  
        update_universe(context.universe)  
def handle_data(context,data):  
    pass  

I commented out the factors that access Morningstar and the backtest works fine. I always get a timeout with the fundamental factors on.

1 response

I managed to fix it by reducing the window_length to 1 for the fundamental factors.