Back to Community
Plea for help

Two days without sleep and still getting an error.

ValueError: need more than 1 value to unpack
... USER ALGORITHM:36, in trade

Here's the code.

import numpy as np  
import scipy  
import pandas as pd  
import statsmodels.api as sm

def initialize(context):  
    context.longleverage = 0.5  
    context.shortleverage = -0.5  
    context.reduce_correlation = True  
    context.reference = symbol('SPY')  
    # There's bad data for this security so I ignore it  
    context.ignores = [sid(7143)]  
    set_universe(universe.DollarVolumeUniverse(98.0, 100.0))

    schedule_function(trade,  
                      date_rule=date_rules.every_day(),  
                      time_rule=time_rules.market_open(minutes=20))  
def handle_data(context, data):  
    leverage=context.account.leverage  
    exposure=context.account.net_leverage  
    record(leverage=leverage, exposure=exposure)  
def trade(context, data):  
    p = history(100, '1d', 'price').dropna(axis=1)  
    p0 = p.iloc[-11:-1]  
    p1 = p.shift(1).iloc[-11:-1]  
    for stock in p:  
        n,k = regression(p0,p1,context.reference,stock)  
    # ranks = ...  
    # Take the top and botton percentiles for the long and short baskets  
    lower, upper = ranks.quantile([.05, .95])  
    shorts = ranks[ranks <= lower]  
    longs = ranks[ranks >= upper]  
    # Get weights that reduce the correlation within each basket  
    if context.reduce_correlation:  
        R = p.pct_change().dropna()  
        longs = get_reduced_correlation_weights(R[longs.index])  
        shorts = get_reduced_correlation_weights(R[shorts.index])  
    else:  
        # Use even weights  
        longs = longs.abs()  
        longs /= longs.sum()  
        shorts = shorts.abs()  
        shorts /= shorts.sum()  
    for stock in data:  
        if stock in context.ignores:  
            continue  
        try:  
            if get_open_orders(sid = stock):  
                continue  
            elif stock in shorts.index:  
                order_target_percent(stock,  
                                     context.shortleverage * shorts[stock])  
            elif stock in longs.index:  
                order_target_percent(stock,  
                                     context.longleverage * longs[stock])  
            else:  
                order_target(stock, 0)  
        except:  
            log.warn("[Failed Order] stock = %s"%stock.symbol)  
def get_reduced_correlation_weights(returns, risk_adjusted=True):  
    """  
    Implementation of minimum correlation algorithm.  
    ref: http://cssanalytics.com/doc/MCA%20Paper.pdf  
    :Params:  
        :returns <Pandas DataFrame>:Timeseries of asset returns  
        :risk_adjusted <boolean>: If True, asset weights are scaled  
                                  by their standard deviations  
    """  
    correlations = returns.corr()  
    adj_correlations = get_adjusted_cor_matrix(correlations)  
    initial_weights = adj_correlations.T.mean()

    ranks = initial_weights.rank()  
    ranks /= ranks.sum()

    weights = adj_correlations.dot(ranks)  
    weights /= weights.sum()

    if risk_adjusted:  
        weights = weights / returns.std()  
        weights /= weights.sum()  
    return weights

def get_adjusted_cor_matrix(cor):  
    values = cor.values.flatten()  
    mu = np.mean(values)  
    sigma = np.std(values)  
    distribution = scipy.stats.norm(mu, sigma)  
    return 1 - cor.apply(lambda x: distribution.cdf(x))

# Linear regression  
def regression(p0, p1, stock0, stock1):  
    s0 = p0[stock0]  
    s1 = sm.add_constant(p1[stock1], prepend=True)  
    return sm.OLS(s0, s1).fit().params  

The line with the error is

n,k = regression(p0,p1,context.reference,stock)

Any help will be greatly appreciated.

4 responses

It's likely that you're not passing in all the values that the "regression" function is expecting.
Did you try to print the value of all the parameters before passing them to "regression" to see which value caused the error?

Since the parameters are used in pairs in "regression", you can actually just use two parameters "p0[stock0], p1[stock1]" instead of passing all four into the function.

Thank yo very much for you advice.

I have checked the inputs to the regression subroutine and they seem perfectly all right, two series of real numbers with the (same) date and time indeces.

I have no idea what your function does, but when I got that error it was because I was not providing enough variables to store the output of the function.

Are you sure that "return sm.OLS(s0, s1).fit().params" only outputs 2 objects? Perhaps try assigning more variables...

n,k,x = regression(p0,p1,context.reference,stock)

n,k,x,y = regression(p0,p1,context.reference,stock)

n,k,x,y,z = regression(p0,p1,context.reference,stock)

Thanks, Tristan, I will definitely try your idea!