问题描述
两者是主要的区别是什么?
finance.run.query()好像有条数限制,get_fundamentals()没有
解决方案
在 JoinQuant (聚宽) 量化平台中,get_fundamentals 和 finance.run_query 都是用于查询数据库中表格数据的 API,但它们在数据范围、条数限制以及参数设计上有着明显的区别。
首先纠正一个误区:两者都是有条数限制的,并非 get_fundamentals() 没有限制。
以下是两者的主要区别详解:
1. 查询的数据范围不同
get_fundamentals():专门用于查询财务数据和估值数据。包括三大财务报表(资产负债表、利润表、现金流量表)、财务指标数据以及市值估值表(如 PE、PB、市值等)。finance.run_query():用于查询更广泛的金融市场数据。主要包括深沪港通数据、股东信息(如十大股东)、公司概况、分红送股等非财务报表类的基础信息。
2. 返回条数限制不同
为了防止单次查询返回的数据量过大导致内存溢出或数据库压力,聚宽对这两个 API 都设置了单次查询的行数上限:
get_fundamentals():每次最多返回 5000 行数据。finance.run_query():每次最多返回 4000 行数据。
如果你的查询结果超过了这个限制,数据会被截断。解决方法是使用 .limit() 和 .offset() 进行分页查询,或者在 filter 中缩小查询范围(例如按日期或股票代码分批查询)。
3. 参数设计与防未来函数机制不同
get_fundamentals(query_object, date=None, statDate=None):- 内置了强大的防未来函数机制。在回测中,如果不指定
date,它会默认使用context.current_dt的前一天,确保你只能获取到当时已经公布的财报和市值数据。 - 支持通过
date(指定具体日期看当时能看到的最新财报)或statDate(指定具体的财报季度/年份,如 '2019q1')来灵活获取数据。
- 内置了强大的防未来函数机制。在回测中,如果不指定
finance.run_query(query_object):- 只有
query_object一个参数。 - 没有内置的
date参数来自动防未来函数。你必须在构建query对象时,手动在.filter()中加入日期限制(例如finance.STK_SHAREHOLDER_TOP10.pub_date < context.current_dt),否则极易引入未来数据。 - 不支持连表查询(即不能同时查询多张表内数据)。
- 只有
代码示例对比
使用 get_fundamentals 查询市值(自动防未来):
# 在回测中,默认获取昨天的市值数据,不会有未来函数
q = query(valuation.code, valuation.market_cap).filter(valuation.code == '000001.XSHE')
df = get_fundamentals(q)
使用 finance.run_query 查询十大股东(需手动防未来):
# 必须手动在 filter 中限制发布日期,否则会获取到未来的股东数据
q = query(finance.STK_SHAREHOLDER_TOP10).filter(
finance.STK_SHAREHOLDER_TOP10.code == '000001.XSHE',
finance.STK_SHAREHOLDER_TOP10.pub_date <= context.previous_date
).limit(10)
df = finance.run_query(q)
总结
- 查财报、查估值(PE/PB/市值) -> 用
get_fundamentals(上限 5000 条)。 - 查股东、查沪深港通、查公司概况 -> 用
finance.run_query(上限 4000 条,需手动限制日期防未来)。