Back to Community
Key Error Equity

I keep getting this Key Error message in my daily rebalance. Any idea what might be causing this?

Clone Algorithm
3
Loading...
Backtest from to with initial capital
Total Returns
--
Alpha
--
Beta
--
Sharpe
--
Sortino
--
Max Drawdown
--
Benchmark Returns
--
Volatility
--
Returns 1 Month 3 Month 6 Month 12 Month
Alpha 1 Month 3 Month 6 Month 12 Month
Beta 1 Month 3 Month 6 Month 12 Month
Sharpe 1 Month 3 Month 6 Month 12 Month
Sortino 1 Month 3 Month 6 Month 12 Month
Volatility 1 Month 3 Month 6 Month 12 Month
Max Drawdown 1 Month 3 Month 6 Month 12 Month
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
from collections import defaultdict
      
class momentum_factor_1(CustomFactor):    
   inputs = [USEquityPricing.close]   
   window_length = 20  
     
   def compute(self, today, assets, out, close):      
     out[:] = close[-1]/close[0]      
   
class momentum_factor_2(CustomFactor):    
   inputs = [USEquityPricing.close]   
   window_length = 60  
     
   def compute(self, today, assets, out, close):      
     out[:] = close[-1]/close[0]   
   
class momentum_factor_3(CustomFactor):    
   inputs = [USEquityPricing.close]   
   window_length = 125  
     
   def compute(self, today, assets, out, close):      
     out[:] = close[-1]/close[0]  
   
class momentum_factor_4(CustomFactor):    
   inputs = [USEquityPricing.close]   
   window_length = 252  
     
   def compute(self, today, assets, out, close):      
     out[:] = close[-1]/close[0]  
   
class market_cap(CustomFactor):    
   inputs = [USEquityPricing.close, morningstar.valuation.shares_outstanding]   
   window_length = 1  
     
   def compute(self, today, assets, out, close, shares):      
     out[:] = close[-1] * shares[-1]        
        
class efficiency_ratio(CustomFactor):    
   inputs = [USEquityPricing.close, USEquityPricing.high, USEquityPricing.low]   
   window_length = 252
     
   def compute(self, today, assets, out, close, high, low):
       lb = self.window_length
       e_r = np.zeros(len(assets), dtype=np.float64)
       a=np.array(([high[1:(lb):1]-low[1:(lb):1],abs(high[1:(lb):1]-close[0:(lb-1):1]),abs(low[1:(lb):1]-close[0:(lb-1):1])]))      
       b=a.T.max(axis=1)
       c=b.sum(axis=1)
       e_r=abs(close[-1]-close[0]) /c  
       out[:] = e_r
        
def initialize(context):  
    set_commission(commission.PerShare(cost=0.005, min_trade_cost=1.00))
    schedule_function(func=monthly_rebalance, date_rule=date_rules.month_start(days_offset=5), time_rule=time_rules.market_open(), half_days=True)  
    schedule_function(func=daily_rebalance, date_rule=date_rules.every_day(), time_rule=time_rules.market_close(hours=1))
    
    set_do_not_order_list(security_lists.leveraged_etf_list)
    context.acc_leverage =0.8
    context.acc_leverage_short =-0.2 
    context.holdings_longs =10
    context.holdings_shorts =5
    context.profit_taking_factor = 0.01
    context.profit_taking_factor_short = -0.01
    context.profit_target_short={}
    context.profit_target={}
    context.profit_taking={}
    context.profit_taking_short={}
    context.entry_date={}
    context.stop_pct = 0.75
    context.stop_pct_short =1.25
    context.stop_price = defaultdict(lambda:0)
    context.stop_price_short = defaultdict(lambda:0)
       
    pipe = Pipeline()  
    attach_pipeline(pipe, 'ranked_stocks')  
     
    factor1 = momentum_factor_1()  
    pipe.add(factor1, 'factor_1')   
    factor2 = momentum_factor_2()  
    pipe.add(factor2, 'factor_2')  
    factor3 = momentum_factor_3()  
    pipe.add(factor3, 'factor_3')  
    factor4 = momentum_factor_4()  
    pipe.add(factor4, 'factor_4') 
    factor5=efficiency_ratio()
    pipe.add(factor5, 'factor_5')
        
        
    mkt_screen = market_cap()    
    stocks = mkt_screen.top(3000) 
    factor_5_filter = factor5 > 0.031
    total_filter = (stocks& factor_5_filter)
    pipe.set_screen(total_filter)  
     
        
    factor1_rank = factor1.rank(mask=total_filter, ascending=False)  
    pipe.add(factor1_rank, 'f1_rank')  
    factor2_rank = factor2.rank(mask=total_filter, ascending=False)  
    pipe.add(factor2_rank, 'f2_rank')  
    factor3_rank = factor3.rank(mask=total_filter, ascending=False)   
    pipe.add(factor3_rank, 'f3_rank')  
    factor4_rank = factor4.rank(mask=total_filter, ascending=False)  
    pipe.add(factor4_rank, 'f4_rank')  
   
    combo_raw = (factor1_rank+factor2_rank+factor3_rank+factor4_rank)/4  
    pipe.add(combo_raw, 'combo_raw')   
    pipe.add(combo_raw.rank(mask=total_filter), 'combo_rank')       
         
def before_trading_start(context, data):  
    context.output = pipeline_output('ranked_stocks')  
   
    #context.rank_above_1 = context.output[context.output.factor_1 > 1]
    context.rank_above_0 = context.output[context.output.factor_5 > 0]

    ranked_stocks = context.rank_above_0
    
    # Only consider stocks with a positiefficiency rating
    #ranked_stocks = ((context.output[context.output.factor_5 > 0]) and  (context.output[context.output.factor_1 > 1]))
    
    # We are interested in the top 10 stocks ranked by combo_rank
    context.stock_factors = ranked_stocks.sort(['combo_rank'], ascending=True).iloc[:context.holdings_longs]  
    # We are intserested in the top 5 stocks of the list sorted in a non ascending order using the same combo rank   
    context.stock_factors_shorts = ranked_stocks.sort(['combo_rank'], ascending=False).iloc[:context.holdings_shorts] 
    
   
    context.stock_list_longs = context.stock_factors.index
    context.stock_list_shorts = context.stock_factors_shorts.index         
    context.stock_list = context.stock_factors.index.union(context.stock_factors_shorts.index).tolist()
    context.stock_set = set(context.stock_list)
def handle_data(context, data):
        
    for stock in context.portfolio.positions:
        if data.can_trade(stock):
            # Set/update stop price
            price = data.current(stock, 'price')
            context.stop_price[stock] = max(context.stop_price[stock], context.stop_pct * price)
            # Check stop price, sell if price is below it
            if price < context.stop_price[stock]:
                order_target(stock, 0)
                context.stop_price[stock] = 0
    for stock in context.portfolio.positions:
        if data.can_trade(stock):
            if context.portfolio.positions < 0:
                price = data.current(stock, 'price')
                context.stop_price_short[stock] = max(context.stop_price_short[stock], context.stop_pct_short * price)
                if price > context.stop_price_short[stock]:
                    order_target(stock, 0)
                    context.stop_price[stock] = 0
          
           

def daily_rebalance(context, data):

    for stock in context.portfolio.positions:
           if data.can_trade(stock) and data.current(stock, 'close') > context.profit_target[stock]:
                context.profit_target[stock] = data.current(stock, 'close')*1.25
                context.profit_taking_amount = context.portfolio.positions[stock].amount * context.profit_taking_factor
                order_target(stock, context.profit_taking_amount)
    
    for stock in context.portfolio.positions:
           if context.portfolio.positions < 0:
                if data.can_trade(stock) and data.current(stock, 'close') < context.profit_target_short[stock]:
                    context.profit_target_short[stock] = data.current(stock, 'close')*-1.25
                    context.profit_taking_amount_short = context.portfolio.positions[stock].amount * context.profit_taking_factor_short
                    order_target(stock, context.profit_taking_amount_short)
    #print "Long List" 
    #log.info("\n" + str(context.stock_factors.sort(['combo_rank'],                                              ascending=True).head(context.holdings_longs)))
    #print "Short List"
    #log.info("\n" + str(context.stock_factors_shorts.sort(['combo_rank'],                                      ascending=False).head(context.holdings_shorts)))
    
    # Record leverage and number of positions held
    record(leverage=context.account.leverage, positions=len(context.portfolio.positions))
   
    
    
def monthly_rebalance(context,data):
    
    long_secs = context.stock_list_longs
    short_secs = context.stock_list_shorts
    long_weight = context.acc_leverage / len(context.stock_factors)
    short_weight = context.acc_leverage_short / len(context.stock_factors_shorts)
    
    
    for stock in context.stock_set:
        if stock in long_secs:
            order_target_percent(stock, long_weight)
            
        elif stock in short_secs:
            order_target_percent(stock, short_weight)
            
        else:
            order_target(stock, 0)
               
    for stock in context.portfolio.positions:
        if stock not in context.stock_set:
            order_target(stock,0)


There was a runtime error.
2 responses

context.profit_target gets initialized as an empty dictionary, and you never fill it with any values, so trying to access context.profit_target[stock] raises a KeyError. To avoid this, you should check if stock is in context.profit_target first and fill that value somehow.

The same goes for context.profit_target_short.

Disclaimer

The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by Quantopian. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. No information contained herein should be regarded as a suggestion to engage in or refrain from any investment-related course of action as none of Quantopian nor any of its affiliates is undertaking to provide investment advice, act as an adviser to any plan or entity subject to the Employee Retirement Income Security Act of 1974, as amended, individual retirement account or individual retirement annuity, or give advice in a fiduciary capacity with respect to the materials presented herein. If you are an individual retirement or other investor, contact your financial advisor or other fiduciary unrelated to Quantopian about whether any given investment idea, strategy, product or service described herein may be appropriate for your circumstances. All investments involve risk, including loss of principal. Quantopian makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances.

Thanks Nathan! Ill give it a go.