Quantopian's community platform is shutting down. Please read this post for more information and download your code.
Back to Community
Problems to define the trading universe

Dear all,

I followed the "Fundamental Data Algorithm" to construct my only algorithm for rating a bunch of stocks. The only difference is that I would like to track all 12 sectors instead of tracking only one selected sector (just like in the sample algorithm).

The problem is then total number of "selected" stocks is over 800, which forbids me to use update_universe(). Therefore, I can only use context.stocks = fundamental_df[picked].columns.value to save those picked stocks.

As I run the backtest, I found that some of stocks simply won't show up (like Apple). However, it showed up if I check its price using history() function. Does that mean the stock universe changing randomly? And how should I resolve this problem or what did I do wrong?

Please see my code below and the screenshot in which I printed out the weekly returns(here). Thanks a lot in advance!


def initialize(context):  
    """ Set a counter """  
    context.counter = 0  
    """ Set sector ETFs and benchmark """  
    context.ETF = symbols('XLB','XLY','XLF','IYR','XLP','XLV','XLU','IYZ','XLE','XLI','XLK','SPY')  
    context.rating_etf = pd.DataFrame( [initial_rating]*(len(context.ETF)-1), index = context.ETF[:-1] ).T  
    context.rating_spy = pd.DataFrame( [initial_rating]*(len(context.ETF)-1), index = context.ETF[:-1] ).T  
    context.exp = pd.DataFrame( [0.5]*len(context.ETF), index = context.ETF).T

    """ Use the top 5% of stocks defined by average daily trading volume. """  
    set_universe(universe.DollarVolumeUniverse(90, 95))  
    """ Set execution cost assumptions. For live trading with Interactive Brokers  
        we will assume a $1.00 minimum per trade fee, with a per share cost of $0.0075. """  
    set_commission(commission.PerShare(cost=0.0075, min_trade_cost=1.00))  
    """ Set market impact assumptions. We limit the simulation to  
        trade up to 2.5% of the traded volume for any one minute,  
        and  our price impact constant is 0.1. """  
    set_slippage(slippage.VolumeShareSlippage(volume_limit=0.05, price_impact=0.10))

    """ Create an empty dataframe for fundamental data"""  
    context.fundamental_df = pd.DataFrame()  
    """ Sector mappings """  
    context.sector_mappings = {  
       101.0: "Basic Materials",  
       102.0: "Consumer Cyclical",  
       103.0: "Financial Services",  
       104.0: "Real Estate",  
       205.0: "Consumer Defensive",  
       206.0: "Healthcare",  
       207.0: "Utilites",  
       308.0: "Communication Services",  
       309.0: "Energy",  
       310.0: "Industrials",  
       311.0: "Technology"  
    }  
    """ Sector ETF mappings """  
    context.etf_mappings = {  
       101.0: symbol('XLB'),  
       102.0: symbol('XLY'),  
       103.0: symbol('XLF'),  
       104.0: symbol('IYR'),  
       205.0: symbol('XLP'),  
       206.0: symbol('XLV'),  
       207.0: symbol('XLU'),  
       308.0: symbol('IYZ'),  
       309.0: symbol('XLE'),  
       310.0: symbol('XLI'),  
       311.0: symbol('XLK')  
    }  
     schedule_function(rating_stocks,  
                      date_rule=date_rules.week_start(),  
                      time_rule=time_rules.market_open(minutes=6))  
def before_trading_start(context, data): 

    """  
      Called before the start of each trading day.  
      It updates our universe with the  
      securities and values found from get_fundamentals.  
    # Setup SQLAlchemy query to screen stocks based on PE ratio  
    # and industry sector. Then filter results based on  
    # market cap and shares outstanding.  
    # We limit the number of results to num_stocks and return the data  
    # in descending order.  
    """  
    #try:  
    #    print "initial num of stocks:%s" %len(context.stocks)  
    #except:  
    #    pass  
    fundamental_df = get_fundamentals(  
        query(  
            # put your query in here by typing 'fundamentals.'  
            fundamentals.earnings_report.basic_eps,  
            fundamentals.asset_classification.morningstar_sector_code,  
            fundamentals.asset_classification.morningstar_industry_group_code,  
            fundamentals.valuation.market_cap,  
            fundamentals.asset_classification.growth_score  
        )  
        .filter(fundamentals.valuation.market_cap != None)  
        .filter(fundamentals.valuation.shares_outstanding != None)  
        .filter(fundamentals.earnings_report.basic_eps != None)  
        #.order_by(fundamentals.valuation.market_cap.desc())  
        #.limit(num_stocks)  
    )  
    print "fundamental df length:%s" %len(fundamental_df.columns.values)  
    """ Find the average market cap in this sector """  
    avg_market_cap = np.mean(np.array(fundamental_df.ix["market_cap",:]))  
    """ Get volume MA for past 60 days """  
    volume_history = history(60,'1d',"volume",ffill=True)  
    #print "length of volume_history:%s" %len(volume_history.columns)  
    ave_volume = np.round(volume_history.mean(),0)  
    #print "length of ave_volume:%s" %len(ave_volume)  
    """ Get current price"""  
    #prices = history(1,'1d',"price",ffill=True)  
    picked = []  
    if len(ave_volume)>0:  
        for stock in context.stocks:  
            try:  
                if fundamental_df.ix["market_cap",stock] >= 0.8*avg_market_cap and ave_volume[stock] >= 1000000.0:  
                    picked.append(stock)  
                #print "%s:%r" %(stock, ave_volume[stock])  
            except:  
                pass  
                #print "%s" %(stock)  
        #print "length of picked by market cap and volume:%s" %len(picked)  
    else:  
        for stock in fundamental_df:  
            if fundamental_df.ix["market_cap",stock] >= 0.8*avg_market_cap:  
                picked.append(stock)  
        #print "length of picked by market cap:%s" %len(picked)  
    """ Update context.fundamental_df with the securities (and pe_ratio) that we need """  
    if len(picked)>0:  
        context.fundamental_df = fundamental_df[picked]  
    else:  
        context.fundamental_df = fundamental_df  
    #print context.fundamental_df.columns  
    #print len(context.fundamental_df.columns.values)  
    #update_universe(context.fundamental_df.columns.values)  
    context.stocks = context.fundamental_df.columns.values  
    print "num of stocks stored in context.fundamental_df:%s" %len(context.fundamental_df.columns)  
    print "num of stock for trading:%s" %len(context.stocks)

    """ create a dictionary to stock lists in each sector """  
    stock_dict = { key: [] for key in context.sector_mappings.keys() }  
    for stock in context.fundamental_df:  
        sector = fundamental_df[stock]['morningstar_sector_code']

        if sector in stock_dict.keys():  
            stock_dict[sector].append(stock)  
        else:  
            pass  
    context.sector = stock_dict  
    #print context.sector[101.0]

    context.counter += 1


""" rating stocks """
def rating_stocks(context, data):  
    if context.counter > 1:  
        ## extract percentage return for those stocks in this sector  
        prices = history(10,'1d','price',ffill=True)  
        #print prices[symbol('AA')]  
        ## first we try to identify the last trading day two weeks ago  
        week_num = np.array([ prices.index[i].isocalendar()[1] for i in range(len(prices.index))])  
        #print week_num  
        day_index = np.where( week_num[:-1] != week_num[-2])[0][-1]  
        #print day_index  
        ## calculate return  
        prices_pct = ( (prices.iloc[-2,:]-prices.iloc[day_index,:])/prices.iloc[day_index,:] )  
        #print prices_pct[symbol('AAPL')]  
        ## loop over sector keys  
        for key in context.sector_mappings.keys():  
            #print key  
            #print context.sector[key]  
            #print history(1,'1d','price')[context.sector[key]]  
            stock_return = prices_pct[context.sector[key]]  
            ## adding sector ETF  
            stock_return[context.etf_mappings[key]] = prices_pct[context.etf_mappings[key]]  
            print prices[context.sector[key]]  
            print stock_return