Quantopian's community platform is shutting down. Please read this post for more information and download your code.
Back to Community
TypeError: Expected assets argument to be of type or iterable of type Asset, Continuous Future, basestring

Good afternoon,
Thanks to this paper: http://www.sciencedirect.com/science/article/pii/S1059056016301563
I developed this strategy in which I predict the direction of the overnight SPY and of the first 30 minutes of trading based on the last 30 minutes of the day before.

Now I wanted to use the same strategy, but applied to a universe of stocks instead of a single index. I wanted to go long only on the top 10% performing stocks of the S&P500 and go short in the bottom 10% stocks. In particular, if the return in the last 30 minutes of trading is positive, I want to go long overnight (or vice-versa). In addition, if the overnight ends up being positive for real, I want to go short in the first 30 minutes of trading of the next morning (or vice-versa).

This is my code:

from quantopian.algorithm import attach_pipeline, pipeline_output  
from quantopian.pipeline import Pipeline  
from quantopian.pipeline import CustomFactor  
from quantopian.pipeline.data.builtin import USEquityPricing  
from quantopian.pipeline.data import morningstar  
import numpy as np  
import pandas as pd  
from datetime import date, timedelta  
from quantopian.pipeline.factors import SimpleMovingAverage, AverageDollarVolume  
from quantopian.pipeline.filters.morningstar import Q500US

def initialize(context):  
    #set a realistic commission and slippage  
    set_commission(commission.PerTrade(cost=0.035))  
    set_slippage(slippage.FixedSlippage(spread=0.01))  
    #schedule functions so that I open my positions 1 minute before market  
    #closes and change position when the market opens the next day  
    #I close all positions 30 minutes after the market opens everyday  
    schedule_function(rebalance1, date_rules.every_day(), time_rules.market_close(minutes=1))  
    schedule_function(rebalance2, date_rules.every_day(), time_rules.market_open(minutes=1))  
    schedule_function(rebalance3, date_rules.every_day(), time_rules.market_open(minutes=31))  
    pipe = Pipeline()  
    attach_pipeline(pipe, 'stocks_500')  
    base_universe = Q500US()  
    pipe.set_screen(base_universe)  
    context.long_leverage = 1  
    context.short_leverage = -1  
def before_trading_start(context, data):  
    # Call pipelive_output to get the output  
    context.output = pipeline_output('stocks_500')  
    # Narrow down the securities to only the top and bottom 10% percentile update my universe  
    context.long_list = context.output.sort().iloc[:100]  
    context.short_list = context.output.sort().iloc[:-100]  
    universe = update_universe(context.long_list.index.union(  
            context.short_list.index)) 


def handle_data(context, data):  
    #Record and plot the leverage of our portfolio over time.  
    record(leverage = context.account.leverage)  
    print "Long List"  
    log.info("\n" + str(context.long_list.head(10)))  
    print "Short List"  
    log.info("\n" + str(context.short_list.head(10)))  
def rebalance1(context, data):  
    # get minute 30 and last minute before market closes  
    last30min_befclos = data.history(universe, 'close', 30, '1m')[0]  
    last1min_befclos = data.history(universe, 'close', 1, '1m')[0]  
    #compute weights  
    long_weight = context.long_leverage / float(len(context.long_list))  
    short_weight = context.short_leverage / float(len(context.short_list))

    # If last 30 minutes of trading are increasing go long otherwise go short  
    for long_stock in context.long_list.index:  
        if last1min_befclos > last30min_befclos in data:  
            order_target_percent(long_stock, long_weight)  
    for short_stock in context.short_list.index:  
        if last1min_befclos < last30min_befclos in data:  
            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)  
def rebalance2(context, data):  
    # Get today's open  and yesterday's close prices  
    today_open = data.history(universe, 'open', 1, '1d')[0]  
    yesterday_close = data.history(universe, 'close', 2, '1d')[0]  
    #compute weights  
    long_weight = context.long_leverage / float(len(context.long_list))  
    short_weight = context.short_leverage / float(len(context.short_list))  
    # If I earn overnight go short, otherwise go long  
    for long_stock in context.long_list.index:  
        if today_open < yesterday_close in data:  
            order_target_percent(long_stock, long_weight)  
    for short_stock in context.short_list.index:  
        if today_open > yesterday_close in data:  
            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)  
def rebalance3(context, data):  
    #I close every position 30 minutes after the market opens  
    for long_stock in context.long_list.index:  
        if long_stock in data:  
            order_target_percent(long_stock, 0)  
    for short_stock in context.short_list.index:  
        if short_stock in data:  
            order_target_percent(short_stock, 0)  
    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)  

The error comes in line 69 and says:
"TypeError: Expected assets argument to be of type or iterable of type Asset, Continuous Future, basestring" in detail:

    today_open = data.history(universe, 'open', 1, '1d')[0]  

The thing that I don't understand is why the error comes at this point, while in line 50, which is really similar, the same error does not appear.
How can I solve this issue?

Thanks a lot in advance for the help,
Mattia

2 responses

The 'update_universe' method, and subsequent references to 'universe', have been deprecated. In Quantopian 2 simply set a context variable. See https://www.quantopian.com/quantopian2/migration#universe . So instead of

    universe = update_universe(context.long_list.index.union(context.short_list.index))

Replace with

   context.universe = context.long_list.index.union(context.short_list.index)

Then instead of referencing 'universe' replace all those references with 'context.universe'.

That will fix that error. You will now run into errors with the line(s)

    today_open = data.history(context.universe, 'open', 1, '1d')[0]  

The 'history' method returns a pandas dataframe when more than one asset is requested. One can't slice a dataframe using the bracket notation (ie [0]). Maybe use 'head(1)' instead?. Then once you get that working, remember 'today_open' and 'yesterday_close' are series. They are not scalers. The following line therefore won't work and isn't what you want.

        if today_open < yesterday_close in data:  

Good luck.

Hi Dan,
Thanks for the help! I have been able to make the code work without errors. Unfortunately, the result is really weird since it looks like the algorithm is not trading at all (this doesn't change whatever time interval I pick). Do you have any idea why this could happen?
Thanks a lot in advance,
Mattia