You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python获取NSE股票历史数据时触发IndexError: single positional indexer is out-of-bounds错误求助

Python获取NSE股票历史数据时触发IndexError: single positional indexer is out-of-bounds错误求助

Hey there! 看起来你在使用Upstox API批量拉取NSE印度1700多家企业近120天股票数据时,遇到了IndexError: single positional indexer is out-of-bounds错误,结合你的代码片段和Python 3.13的环境,我来帮你分析下可能的问题和解决思路:

先理清楚你的场景

  • 需求:获取1700+家NSE上市公司近120天的日线数据
  • 环境:Python 3.13
  • 核心错误:IndexError: single positional indexer is out-of-bounds
  • 你的核心代码片段(补全了合理的未写完部分):
def getHistoricalData(symInfo):
    res = None
    try:
        parseInstrument = urllib.parse.quote(symInfo.instrument_key)
        fromDate = (datetime.now(TIME_ZONE) - timedelta(days=120)).strftime("%Y-%m-%d")
        todate = datetime.now(TIME_ZONE).strftime("%Y-%m-%d")        
        url = f'https://api.upstox.com/v2/historical-candle/{parseInstrument}/day/{todate}/{fromDate}'        
        res = requests.get(url, headers=YOUR_AUTH_HEADERS)  # 推测你这里有授权头信息
        # 推测你后续有解析响应为DataFrame的操作,这一步触发了错误
        response_data = res.json()
        candles = response_data['data']['candles']
        df = pd.DataFrame(candles)
        # 比如用df.iloc[:, 0]这类位置索引操作时触发了错误
    except IndexError as e:
        print(f"Error for {symInfo.instrument_key}: {e}")

错误的常见原因

这个错误本质是你尝试用位置索引(比如pandas的iloc/iat,或者列表的下标访问)去一个不存在的位置,结合你的场景,大概率是以下几种情况:

  • 1. API返回的内容不符合预期(空数据或错误响应)
    有些上市企业可能近120天没有交易数据,或者你的instrument_key无效、权限不足,导致API返回的candles列表是空的,甚至直接返回错误信息。这时候你强行转成DataFrame再做索引操作,就会触发越界错误。

  • 2. API的日期参数顺序搞反了
    看你构造的URL:day/{todate}/{fromDate},Upstox的历史K线API通常要求日期参数是起始日期在前,结束日期在后,你这里把todate和fromDate的顺序写反了,可能导致API返回空的蜡烛图数据,后续解析时触发错误。

  • 3. 处理DataFrame时的索引操作无数据可访问
    比如你假设返回的蜡烛图数据有固定列数,直接用df.iloc[:, 1]去访问第二列,但如果DataFrame是空的(没有行/列),就会触发这个索引错误。

具体的解决步骤

步骤1:先验证API的返回内容

在请求API后,先不要急着解析数据,先打印响应状态码和返回内容,确认数据结构是否正确:

res = requests.get(url, headers=YOUR_AUTH_HEADERS)
# 先检查请求是否成功
if res.status_code != 200:
    print(f"Request failed for {symInfo.instrument_key}, status code: {res.status_code}")
    print(f"Error message: {res.json()}")
    return None
# 再检查返回的数据结构是否符合预期
response_data = res.json()
if not response_data.get('data') or not response_data['data'].get('candles') or len(response_data['data']['candles']) == 0:
    print(f"No historical data found for {symInfo.instrument_key}")
    return None

步骤2:修正日期参数的顺序

把URL里的todate和fromDate调换位置,符合API的参数要求:

# 修正后的URL,起始日期在前,结束日期在后
url = f'https://api.upstox.com/v2/historical-candle/{parseInstrument}/day/{fromDate}/{todate}'

步骤3:给DataFrame操作加安全判断

在对DataFrame做索引操作前,先确认DataFrame非空,有足够的行/列:

candles = response_data['data']['candles']
df = pd.DataFrame(candles)
# 比如要访问第一列,先判断列数足够
if len(df.columns) > 0:
    first_column = df.iloc[:, 0]
else:
    print(f"DataFrame has no columns for {symInfo.instrument_key}")
    return None

步骤4:批量处理时隔离单个错误

因为你要处理1700多家企业,单个企业的错误不应该中断整个批量任务,所以在循环调用getHistoricalData时也要加异常捕获:

# 假设你有一个所有标的的列表all_symbols
for sym in all_symbols:
    try:
        getHistoricalData(sym)
    except Exception as e:
        print(f"Failed to fetch data for {sym.instrument_key}: {str(e)}")
        continue  # 跳过错误的标的,继续处理下一个

备注:内容来源于stack exchange,提问作者NeedBasedLearner

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.15 11:23:07