Back to Community
Keyerror: Help

I am not able to get rid of this error to get OBVs due to this error.
Any help

import talib  
def initialize(context):  
    # we want to try this on a range of highly liquid stocks  
    set_universe(universe.DollarVolumeUniverse(98, 99))  
    context.bet_amount = 1000000  
    context.count = 20

def handle_data(context, data):  
    #set_nodata_policy(NoDataPolicy.LOG_ONLY)  
    days = 90  
    ranking = sort_returns(data, days)  
def sort_returns(data, days):  
    prices = history(bar_count=days, frequency='1d', field='price').dropna(axis=1)  
    volumes = history(bar_count=days, frequency='1d', field='volume').dropna(axis=1)  
    for stock in data.keys():  
            #set_nodata_policy(NoDataPolicy.LOG_ONLY)  
            p_c = prices[stock]  
            v_c = volumes[stock]  
            obv_n = talib.OBV(p_c, v_c)[-1]  
            log.info(obv_n)

    return  

Getting following error

KeyError: Equity(41667, symbol='AWAY', asset_name='HOMEAWAY INC', exchange='NASDAQ GLOBAL SELECT MARKET', start_date=Timestamp('2011-06-29 00:00:00+0000', tz='UTC'), end_date=Timestamp('2015-07-06 00:00:00+0000', tz='UTC'), first_traded=None)
There was a runtime error on line 11.

8 responses

Hi Yagnesh,

I don't think you can call history() with a variable number of days -- it must be hard coded. Quantopian do some magic optimisation which requires knowing the number of days in the history call before backtesting starts.

Also, since you've dropped all columns with any NaN present for prices then there may be sids in data not present in prices.

EDIT: Actually this is more tricky than I thought. Because prices = history(90, '1d', 'price').dropna(axis=1) is forward-filling the closing price, you might have an sid in prices not in volumes, so you need

def sort_returns(data):  
    prices = history(90, '1d', 'price').dropna(axis=1)  
    volumes = history(90, '1d', 'volume').dropna(axis=1)  
    for stock in volumes:   # volume is not forward-filled  
            p_c = prices[stock]  
            v_c = volumes[stock]  
            obv_n = talib.OBV(p_c, v_c)[-1]  
            log.info(obv_n)  
    return  

Not sure what the issue is, but I'm getting a similar error:

KeyError: Equity(25601, symbol='MAV', asset_name='PIONEER MUNICIPAL HIGH INCOME ADVANTAGE TRUST', exchange='NEW YORK STOCK EXCHANGE', start_date=Timestamp('2003-10-01 00:00:00+0000', tz='UTC'), end_date=Timestamp('2015-07-06 00:00:00+0000', tz='UTC'), first_traded=None)

def handle_data(context, data):  
    global oprc, cprc  
    oprc = history(200, '1d', field='open_price')  
    cprc = history(200, '1d', field='price')  
    record(leverage=context.account.leverage)  

@Yagnesh - You're calling sort_returns and assigning its result to ranking. But sort_returns ends with return, which in Python is the same as return None. So, after that, ranking is None, and not a sequence from which you can extract the first or last so-many elements.

Also to clarify, this is no longer true:

I don't think you can call history() with a variable number of days -- it must be hard coded

History() can accept a variable parameter for the number of bars :)

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.

Friends,
Thanks for your replies.

This is my way of building the algo. If I get error I first check the log
of the values I am calculating. I am getting log of various other securities till
i hit this error.

I used try: loop to overcome this problem in backtest.
But I am not sure what will happen in live trading if
algo builds the position in a security and it ends up in
a blacklist

import talib  
def initialize(context):  
    # we want to try this on a range of highly liquid stocks  
    set_universe(universe.DollarVolumeUniverse(98, 99))  
    context.bet_amount = 1000000  
    context.count = 20

def handle_data(context, data):  
    #set_nodata_policy(NoDataPolicy.LOG_ONLY)  
    days = 90  
    ranking = sort_returns(data, days)  
def sort_returns(data, days):  
    prices = history(bar_count=days, frequency='1d', field='price').dropna(axis=1)  
    volumes = history(bar_count=days, frequency='1d', field='volume').dropna(axis=1)  

    for stock in data.keys():  
        try:  
            p_c = prices[stock]  
            v_c = volumes[stock]  
            obv_n = talib.OBV(p_c, v_c)[-1]  
            #log.info(obv_n)  
        except:  
            log.warn("[Failed Order] asset = %s"%stock)

    return  

@Alisa
Whoops -- I must be behind the times again! I'll have to re-read the whole help-doc at this rate. Thank you.

@Yagnesh

import talib  
def initialize(context):  
    # we want to try this on a range of highly liquid stocks  
    set_universe(universe.DollarVolumeUniverse(98, 99))  
    context.bet_amount = 1000000  
    context.count = 20

def handle_data(context, data):  
    #set_nodata_policy(NoDataPolicy.LOG_ONLY)  
    days = 90  
    ranking = sort_returns(data, days)  
def sort_returns(data, days):  
    prices = history(bar_count=days, frequency='1d', field='price').dropna(axis=1)  
    volumes = history(bar_count=days, frequency='1d', field='volume').dropna(axis=1)  

    for stock in volumes:   # <<------------------------------!!  
        try:  
            p_c = prices[stock]  
            v_c = volumes[stock]  
            obv_n = talib.OBV(p_c, v_c)[-1]  
            #log.info(obv_n)  
        except:  
            log.warn("[Failed Order] asset = %s"%stock)

    return  

does not give any [Failed Order]

Thanks James;

I understand the logic that the algo will not throw error if I use

for stock in volumes:  

Now I am thinking on different track.
But my issue (consider live trading scene) is at start of the year the same
stock was in the volumes and considering it being delisted it was showing the signal of weakness
and the algo picks up the signal and shorts it.
Now it is delisted what to do.

Ah I get you. Well if you short something and the company gets delisted, you keep the cash, although in Quantopian the positions will stay zombie forever.

See https://www.quantopian.com/posts/exit-securities-which-no-longer-trade
and https://www.quantopian.com/posts/when-a-company-gets-acquired-my-portfolio-still-owns-shares-of-the-original-company-is-that-right