3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
在 JoinQuant(聚宽)平台上,为了防止单次请求返回的数据量过大导致内存溢出或服务器压力过大,官方对 get_fundamentals 等财务数据查询 API 设置了单次返回条数的限制(官方文档目前标注的上限是 5000条)。
当您需要统计全市场(目前A股有5000多只股票)的财务数据时,单次查询必然会被截断。最有效且通用的解决方法是:分批获取(Batch Query)并拼接数据。
将全市场的股票代码列表(或您需要查询的庞大股票池)切分成多个小批次(例如每批 500 只股票),然后利用 for 循环结合 in_() 过滤条件,分批调用 get_fundamentals,最后使用 pandas.concat 将所有批次的结果合并成一个完整的 DataFrame。
以下是一个封装好的分批获取财务数据的通用函数示例,您可以直接在研究环境或策略中使用:
import pandas as pd
from jqdata import *
def get_fundamentals_in_batches(base_query, date=None, statDate=None, batch_size=500):
"""
分批获取财务数据,突破单次 5000 条的限制。
:param base_query: 基础的 sqlalchemy query 对象(不需要包含 code.in_ 过滤)
:param date: 查询日期
:param statDate: 财报统计的季度或者年份
:param batch_size: 每批次查询的股票数量,建议设置在 500-1000 之间
:return: 包含所有查询结果的 pandas.DataFrame
"""
# 1. 获取全市场所有股票代码(如果您有特定的股票池,可以替换这里)
all_stocks = list(get_all_securities(['stock']).index)
result_list = []
# 2. 将股票列表分批
for i in range(0, len(all_stocks), batch_size):
batch_stocks = all_stocks[i : i + batch_size]
# 3. 在基础 query 上追加当前批次的股票过滤条件
# 注意:这里假设您查询的表中包含 valuation.code,如果是其他表请替换为对应的 code 字段
# 例如:income.code.in_(batch_stocks)
q = base_query.filter(valuation.code.in_(batch_stocks))
# 4. 获取当前批次数据
df = get_fundamentals(q, date=date, statDate=statDate)
if not df.empty:
result_list.append(df)
# 5. 合并所有批次的数据
if result_list:
final_df = pd.concat(result_list, ignore_index=True)
return final_df
else:
return pd.DataFrame()
# ================= 使用示例 =================
# 假设我们要查询全市场股票的总市值、市盈率和营业总收入
q = query(
valuation.code,
valuation.market_cap,
valuation.pe_ratio,
income.total_operating_revenue
)
# 调用分批获取函数(注意:date 和 statDate 只能传入一个)
all_data_df = get_fundamentals_in_batches(q, date='2023-10-10', batch_size=800)
print(f"成功获取到 {len(all_data_df)} 条财务数据!")
print(all_data_df.head())
filter 中使用 .in_() 时,请确保使用的 code 字段与您 query 中查询的主表一致。例如,如果您只查 income 表,过滤条件应写为 income.code.in_(batch_stocks)。batch_size 不宜设置过大(避免单次依然超过5000条,特别是当您进行了复杂的连表查询导致产生多条记录时),也不宜设置过小(会导致 API 调用次数过多,降低运行速度)。通常设置为 500 到 1000 是比较稳妥的。write_file 或 to_csv(mode='a')),而不是全部保存在内存里。