Quantopian's community platform is shutting down. Please read this post for more information and download your code.
Back to Community
Beta 0 strategy - Backtesting stucked

I've been writing the code below, trying to create an algorithm that calculate the beta of each security with SPY as benchmark.
When I run the code, it is like it works for a short time, and then it gets stuck. Any suggestions why this might be?

This is my very first post so if you need more information than the code below, please let me know.

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  
import numpy as np  
import pandas as pd

def _beta(ts, benchmark, benchmark_var):  
    return np.cov(ts, benchmark)[0, 1] / benchmark_var 

class Beta(CustomFactor):  
    inputs = [USEquityPricing.close]  
    window_length = 30  
    def compute(self, today, assets, out, close):  
        returns = pd.DataFrame(close, columns=assets).pct_change()[1:]  
        spy_returns = returns[sid(8554)]  
        spy_returns_var = np.var(spy_returns)  
        out[:] = returns.apply(_beta, args=(spy_returns,spy_returns_var,))  
# DollarVolume will calculate yesterday's dollar volume for each stock in the universe.  
class DollarVolume(CustomFactor):  
    # We need close price and trade volume for this calculation.  
    inputs = [USEquityPricing.close, USEquityPricing.volume]  
    window_length = 1  
    # Dollar volume is volume * closing price.  
    def compute(self, today, assets, out, close, volume):  
        out[:] = (close[-1] * volume[-1])  
def initialize(context):  
    """  
    Called once at the start of the algorithm.  
    """  
    # User defined variables  
    context.long_number = 5  
    context.short_number = 5  
    # Create and attach pipeline  
    pipe = Pipeline()  
    attach_pipeline(pipe,name='pipeline')  
    # Add beta to pipeline  
    beta = Beta()  
    pipe.add(beta, 'beta')  
    beta_filter = (beta < 1) & (beta > -1)  
    # Create the dollar_volume factor using default inputs and window_length  
    dollar_volume = DollarVolume()  
    dollar_filter = (dollar_volume > 10000000)  
    pipe.add(dollar_volume, 'dollar_volume')  
    pipe.set_screen(beta_filter & dollar_filter)  
    # Rebalance every day, 1 hour after market open.  
    schedule_function(rebalance, date_rules.week_start(), time_rules.market_open(hours=1))  
    # Record tracking variables at the end of each day.  
    schedule_function(my_record_vars, date_rules.every_day(), time_rules.market_close())  

def before_trading_start(context, data):  
    """  
    Called every day before market open.  
    """  
    context.output = pipeline_output('pipeline')  
    context.long_list = context.output.sort(['beta'], ascending=False).head(context.long_number)  
    context.short_list = context.output.sort(['beta'], ascending=True).head(context.short_number)  
    pass  

def my_assign_weights(context, data):  
    """  
    Assign weights to securities that we want to order.  
    """  
    pass  
def rebalance(context,data):  
    """  
    Execute orders according to our schedule_function() timing.  
    """  
    # Sum of long and short betas  
    sum_long = np.sum(context.long_list['beta'])  
    sum_short = np.sum(context.short_list['beta'])  
    # Calculate leverage so beta becomes 0  
    pct_long = 1 - (sum_long / (sum_long - sum_short))  
    pct_short = -(1 - (-sum_short / (sum_long - sum_short)))  
    # Calculate weight per share  
    long_weight = pct_long / float(len(context.long_list))  
    short_weight = pct_short / float(len(context.short_list))  
    # Order long stocks  
    for long_stock in context.long_list.index:  
        if data.can_trade(long_stock):  
            order_target_percent(long_stock, long_weight)  
    # Order short stocks  
    for short_stock in context.short_list.index:  
        if data.can_trade(short_stock):  
            order_target_percent(short_stock, short_weight)  
    for stock in context.portfolio.positions.iterkeys():  
        if stock not in context.long_list.index and stock not in context.short_list.index:  
            order_target(stock, 0)  
    pass  
def my_record_vars(context, data):  
    """  
    Plot variables at the end of each day.  
    """  
    pass  
def handle_data(context,data):  
    """  
    Called every minute.  
    """  

    pass  
2 responses

I think this is what you need.

def _beta(ts, benchmark, benchmark_var):  
    return np.cov(ts, y=benchmark)[0, 1] / benchmark_var 

class Beta(CustomFactor):  
    inputs = [USEquityPricing.close]  
    window_length = 30  
    def compute(self, today, assets, out, close):  
        returns = np.diff(close, axis=0) / close[:-1]  
        spy_returns = returns[:, assets.searchsorted(8554)]  
        spy_returns_var = np.var(spy_returns)  
        beta = np.apply_along_axis(_beta, 0, returns, spy_returns, spy_returns_var)  
        out[:] =  beta  

Don't assume my math is right. The output looks like beta values, but I put my effort into getting the matrix dimensions to match, not making sure I was doing the math right.

That solved my problem. Much appreciated! thanks.