🚀 AI 一键生成 qmt 策略代码
立即体验
👉 AI 生成代码 👈

QMT xtdata 获取指数行情数据时 volume 整数溢出怎么办?

qmt | 发布时间: 2026/5/29
以下内容由 EasyQuant 生成。

问题描述

xtdata获取指数数据market_data的volume值可能存在整数溢出问题

测试代码:

import pandas as pd
from tqdm import tqdm
from xtquant import xtdata
import time

STOCK_LIST = xtdata.get_stock_list_in_sector('沪深A股')
INDEX_LIST = xtdata.get_stock_list_in_sector('沪深指数')
ETF_LIST = xtdata.get_stock_list_in_sector('沪深ETF')

ALL_CODE = INDEX_LIST

# 按装订区域中的绿色按钮以运行脚本。
if __name__ == '__main__':

start = time.time()
# xtdata.download_history_data2数据量大时会超时
for code in tqdm(ALL_CODE):
xtdata.download_history_data(code,'1d')

df_d = xtdata.get_market_data_ex([],stock_list=ALL_CODE)
df_l = [df.assign(stock_code=code,name = xtdata.get_instrument_detail(stock_code=code)['InstrumentName']) for code,df in df_d.items()]
df = pd.concat(df_l,axis=0).dropna()

print(f'Elapsed time: {time.time()-start}')

解决方案

问题原因分析

在使用 xtquantxtdata.get_market_data_ex 获取沪深指数(如上证指数 000001.SH)的数据时,确实可能会遇到 volume(成交量)字段整数溢出的问题。这通常表现为成交量出现负数或极不合理的异常值。

根本原因
在早期的底层 C++ 接口或数据结构定义中,volume 字段可能被定义为 32 位有符号整数(int32)。32 位有符号整数的最大值是 2,147,483,647(约 21.47 亿)。
对于个股而言,单日成交量很难突破这个数值;但对于大盘指数(如上证指数、深证成指),其单日成交量(通常以“手”或“股”为单位)经常会超过 21.47 亿。一旦超过这个阈值,数据就会发生溢出,变成负数。


解决方案

1. 升级 xtquant 到最新版本

迅投官方在发现此类问题后,通常会在新版本中将底层数据结构或 Python 封装层的 volume 字段类型修改为 int64float64。建议您首先尝试更新库:

pip install --upgrade xtquant -i https://pypi.tuna.tsinghua.edu.cn/simple

2. 替代方案:使用 amount(成交额)代替 volume(成交量)

如果您当前的版本仍未修复此问题,或者您急需进行数据分析,强烈建议在指数分析中使用 amount(成交额)字段

  • amount 字段通常被定义为双精度浮点数(double / float64),其上限极大,不会出现溢出问题
  • 在宏观和指数层面的量化分析中,成交额(金额)往往比成交量(股数/手数)具有更高的参考价值,因为它排除了低价股和高价股对成交“数量”的扭曲。

3. 优化您的测试代码

在您的代码基础上,我们可以提取 amount 字段,并对数据类型进行显式转换,以确保后续计算的稳定性:

import pandas as pd
from tqdm import tqdm
from xtquant import xtdata
import time

# 获取指数列表
INDEX_LIST = xtdata.get_stock_list_in_sector('沪深指数')
ALL_CODE = INDEX_LIST

if __name__ == '__main__':
    start = time.time()
    
    # 1. 下载历史数据
    print("开始下载历史数据...")
    for code in tqdm(ALL_CODE):
        xtdata.download_history_data(code, '1d')

    # 2. 获取数据,明确指定需要的字段,避免加载过多无用数据
    print("开始读取本地数据...")
    fields = ['open', 'high', 'low', 'close', 'amount'] # 放弃使用可能溢出的 volume,改用 amount
    df_d = xtdata.get_market_data_ex(fields, stock_list=ALL_CODE, period='1d')
    
    # 3. 数据拼接与处理
    df_l = []
    for code, df in df_d.items():
        if not df.empty:
            # 获取指数名称
            detail = xtdata.get_instrument_detail(code)
            name = detail['InstrumentName'] if detail else 'Unknown'
            
            # 赋值新列
            df = df.assign(stock_code=code, name=name)
            df_l.append(df)
            
    if df_l:
        final_df = pd.concat(df_l, axis=0).dropna()
        # 确保 amount 为 float64 类型
        final_df['amount'] = final_df['amount'].astype('float64')
        print(final_df.head())
    else:
        print("未获取到有效数据")

    print(f'Elapsed time: {time.time()-start:.2f} seconds')

总结

指数的 volume 溢出是由于 32 位整数限制导致的经典问题。在量化投研中,处理指数级别的数据时,优先使用 amount(成交额) 是规避此类底层数据类型限制的最佳实践。