分析字典时出现密钥错误的未知原因

2024-09-24 00:21:31 发布

您现在位置:Python中文网/ 问答频道 /正文

我有下面的函数,它指向dictionary tickerdata的每个值,然后在满足某些参数后更新它们。该函数正确地迭代这些值,但是存在多个键错误,我不确定其来源。我确信我已经用tickers中的所有名称定义了tickerdata。以下是我的职能

def fetchstock(stock):
        endpoint = 'https://api.tdameritrade.com/v1/marketdata/{stock_ticker}/quotes?'
        full_url = endpoint.format(stock_ticker=stock)
        page = requests.get(url=full_url, params= {'apikey':td_consumer_key})
        content = json.loads(page.content)
        return content[stock]

def scandata(volumelimita, volumelimitb, lastchangelimita,lastchangelimitb, ivlimita, ivlimitb):
    tickers = save_sp500_tickers()
    tickerdata = {key: {} for key in tickers}
    keydefine = {"price":0, "volume":0, "netchange":0, "iv":0}
    tickerdata = {key: keydefine.copy() for key in tickers}
    scandict = {}
    for i in range(100):
        #print("increment is "+str(i))
        stock = tickers[i]
        try:
            if((fetchstock(stock)['totalVolume']>volumelimita) and (fetchstock(stock)['totalVolume']< volumelimitb) and (fetchstock(stock)['netChange']>lastchangelimita) and (fetchstock(stock)['netChange']< lastchangelimitb) and((fetchstock(stock)['volatility']*100)>ivlimita)and((fetchstock(stock)['volatility']*100)<ivlimitb)):
                tickerdata[stock]['price'] = fetchstock(stock)['lastPrice']
                tickerdata[stock]['volume'] = fetchstock(stock)['totalVolume']
                tickerdata[stock]['netchange']= fetchstock(stock)['netChange']
                tickerdata[stock]['iv'] = fetchstock(stock)['volatility']*100
                scandict[stock ] = {"price":tickerdata[stock]['price'], "volume":tickerdata[stock]['volume'],
                                    "netchange":tickerdata[stock]['netchange'], "iv":tickerdata[stock]['iv']}
        except KeyError:
            print('here was a key error at '+ stock)
            pass
    return scandict       

print(scandata(0,10000000,-0.99,0.99,0,25))

输出:

here was a key error at ALK
here was a key error at ALB
here was a key error at ARE
here was a key error at ALXN
here was a key error at ALGN
here was a key error at ALLE
here was a key error at LNT
here was a key error at ALL
here was a key error at GOOGL
here was a key error at GOOG
here was a key error at MO
here was a key error at AMZN
here was a key error at AMCR
here was a key error at AEE
here was a key error at AAL
here was a key error at AEP
here was a key error at AXP
here was a key error at AIG
here was a key error at AMT
here was a key error at AWK
here was a key error at AMP
here was a key error at ABC
here was a key error at AME
here was a key error at AMGN
here was a key error at APH
here was a key error at ADI
here was a key error at ADM
here was a key error at AIZ
here was a key error at ADSK
here was a key error at ADP
here was a key error at AZO
here was a key error at AVB
here was a key error at AVY
here was a key error at BKR
here was a key error at BLL
here was a key error at BAC
here was a key error at BK
here was a key error at BAX
here was a key error at BDX
here was a key error at BRK.B
here was a key error at BBY
here was a key error at BIO
here was a key error at BIIB
here was a key error at BLK
here was a key error at BA
here was a key error at BKNG
here was a key error at BWA
here was a key error at BXP
here was a key error at BSX
here was a key error at BMY
here was a key error at AVGO
here was a key error at BR
here was a key error at BF.B
here was a key error at CHRW
here was a key error at COG
here was a key error at CDNS
here was a key error at CPB
here was a key error at COF
here was a key error at CAH
here was a key error at KMX
here was a key error at CCL
here was a key error at CARR
here was a key error at CTLT
here was a key error at CAT
here was a key error at CBOE
here was a key error at CBRE
here was a key error at CDW
here was a key error at CE
here was a key error at CNC
here was a key error at CNP
here was a key error at CERN
here was a key error at CF
here was a key error at SCHW
{'MMM': {'price': 173.52, 'volume': 1875764, 'netchange': -0.5, 'iv': 3.9899999999999998}, 'ABT': {'price': 106.8, 'volume': 4718995, 'netchange': -0.22, 'iv': 1.92}, 'ATVI': {'price': 83.68, 'volume': 5864152, 'netchange': 0.0, 'iv': 2.93}, 'ADBE': {'price': 475.0, 'volume': 3561554, 'netchange': -0.91, 'iv': 3.1300000000000003}, 'AAP': {'price': 157.0, 'volume': 906915, 'netchange': -0.66, 'iv': 3.29}, 'AES': {'price': 20.94, 'volume': 4495472, 'netchange': -0.21, 'iv': 2.07}, 'AFL': {'price': 45.5, 'volume': 3314639, 'netchange': 0.66, 'iv': 1.77}, 'A': {'price': 118.48, 'volume': 1400768, 'netchange': 0.0, 'iv': 3.39}, 'APD': {'price': 267.36, 'volume': 751837, 'netchange': 0.0, 'iv': 3.46}, 'AKAM': {'price': 103.53, 'volume': 1110303, 'netchange': 0.0, 'iv': 3.34}, 'ANSS': {'price': 335.185, 'volume': 329790, 'netchange': 0.0, 'iv': 5.86}, 'ANTM': {'price': 311.4, 'volume': 1372850, 'netchange': 0.0, 'iv': 3.5000000000000004}, 'AON': {'price': 204.11, 'volume': 1453281, 'netchange': 0.0, 'iv': 3.19}, 'AOS': {'price': 56.36, 'volume': 717023, 'netchange': 0.0, 'iv': 3.01}, 'APA': {'price': 16.02, 'volume': 8903476, 'netchange': -0.08, 'iv': 3.95}, 'AMAT': {'price': 88.08, 'volume': 5776367, 'netchange': -0.22, 'iv': 2.25}, 'APTV': {'price': 122.24, 'volume': 1599289, 'netchange': 0.0, 'iv': 3.44}, 'ANET': {'price': 277.34, 'volume': 610471, 'netchange': 0.0, 'iv': 6.36}, 'AJG': {'price': 119.94, 'volume': 995751, 'netchange': 0.0, 'iv': 2.4}, 'ATO': {'price': 99.07, 'volume': 1100930, 'netchange': 0.0, 'iv': 2.0500000000000003}}

我不知道从这里该怎么办


Tags: andkeyurlherestockerrorpriceat
1条回答
网友
1楼 · 发布于 2024-09-24 00:21:31

我复制并粘贴了您的代码并修改了:

tickers = save_sp500_tickers()tickers = ['LNT', 'AVGO', 'MMM', 'BAC']

结果是:

{'LNT': {'price': 51.705, 'volume': 810208, 'netchange': 0.0, 'iv': 2.53}, 'AVGO': {'price': 405.0, 'volume': 2666510, 'netchange': -0.82, 'iv': 4.9}, 'MMM': {'price': 173.52, 'volume': 1875764, 'netchange': -0.5, 'iv': 3.9899999999999998}}

LNT、AVGO和BAC是您的程序出现关键错误的代码,我加入了MMM以确保您接受的值也能正常工作

最可能的问题是,API通常对您可以请求的频率有限制,并且您在for循环中调用fetchstock(stock)的频率太高。相反,您应该只为每个ticker调用它一次,将它分配给一个变量,然后检查它的['lastPrice'] ['totalVolume']

另外,超级大的if语句不需要大部分括号(如果它都在一行上,则不需要任何括号),表达式可以简化(PyCharm在删除所有括号后为我做了这件事)

最终代码:

def scandata(volumelimita, volumelimitb, lastchangelimita, lastchangelimitb, ivlimita, ivlimitb):
    tickers = save_sp500_tickers()
    tickerdata = {key: {} for key in tickers}
    keydefine = {"price": 0, "volume": 0, "netchange": 0, "iv": 0}
    tickerdata = {key: keydefine.copy() for key in tickers}
    scandict = {}
    for i in range(100):
        # print("increment is "+str(i))
        stock = tickers[i]
        try:

            # Check if close to rate limit, if true then wait 1 minute
            if i % 100:
                time.sleep(60)

            # Call function once per loop and assign to variable
            current_stock = fetchstock(stock)

            if (volumelimita < current_stock['totalVolume'] < volumelimitb and
                    lastchangelimita < current_stock['netChange'] < lastchangelimitb and
                    ivlimita < current_stock['volatility'] * 100 < ivlimitb):

                tickerdata[stock]['price'] = current_stock['lastPrice']
                tickerdata[stock]['volume'] = current_stock['totalVolume']
                tickerdata[stock]['netchange'] = current_stock['netChange']
                tickerdata[stock]['iv'] = current_stock['volatility'] * 100

                scandict[stock] = {"price": tickerdata[stock]['price'],
                                   "volume": tickerdata[stock]['volume'],
                                   "netchange": tickerdata[stock]['netchange'],
                                   "iv": tickerdata[stock]['iv']}
        except KeyError:
            print('here was a key error at ' + stock)
            pass
    return scandict


print(scandata(0, 10000000, -0.99, 0.99, 0, 25))

预编辑

如果您仍然遇到问题,请尝试在for循环的末尾添加一个time.sleep(10)。TD Ameritrade API的限制请求为每分钟120个请求,因此,如果您需要通过120多个ticker,并且程序速度足够快,可以在一分钟内发送所有请求,那么您的请求将再次被阻止

后期编辑

注释中解释说,如果您只对每个股票符号请求一次,那么您实际上不需要time.sleep(),除非您在一分钟内检查了120多只股票。我添加了一个语句if i % 100: time.sleep(60),使程序每100个符号等待1分钟,这将有助于不触发请求限制

最后一个结束思想是,您可以导入traceback模块并获得有关异常的更多信息,下面是一个示例:

import traceback

try:
    print(2/0)
except Exception:
    print(traceback.format_exc())

相关问题 更多 >