问题描述
我使用的是国金的 QMT,
df = ContextInfo.get_financial_data(
fieldList=['PERSHAREINDEX.inc_net_profit', # 归母净利润
'PERSHAREINDEX.du_profit', # 净利润
'ASHAREINCOME.revenue_inc', # 营业收入
'PERSHAREINDEX.du_return_on_equity'], # ROE
stockList=['002130.SZ'],
startDate='20240101', # 开始日期
endDate='20250822', # 结束日期
report_type='report_time' # 按报告期
)
以上是代码,print 出来以后 20250717 NaN NaN NaN NaN 全是 NAN。
请问各位大神,这是哪里需要修改吗?试了很多地方还是不行
解决方案
在 QMT(如国金 QMT)中调用 ContextInfo.get_financial_data 获取财务数据时,如果返回的结果全是 NaN,通常是由以下几个原因导致的。结合你提供的代码,我们可以逐一排查并解决:
1. 查询了未来的日期或尚未发布的财报
在你的代码中,endDate 设置为了 '20250822'。财务数据是按季度发布的,如果你查询的日期对应的财报尚未发布(例如 2025 年中报在现实时间中还未披露),那么该日期之后的数据自然为空(NaN)。
解决方法:将 endDate 修改为当前真实日期,或者确保查询的区间内确实有已发布的财报。
2. report_type='report_time' 的机制问题
你使用了 report_type='report_time'(按报告期取数)。在 QMT 中,按报告期取数意味着返回的 DataFrame 的时间索引(Index)只会是标准的财报截止日期,即每年的 0331(一季报)、0630(中报)、0930(三季报)和 1231(年报)。
如果你在打印时看到了 20250717 这样的非财报截止日期,且对应的值全是 NaN,通常是因为你将财务数据与日线行情数据(K线)进行了合并(Merge/Join),或者 QMT 在填充非报告期日期时默认填入了 NaN。
3. 财务数据未正确下载
虽然你提到“数据也都下载了”,但请再次确认在 QMT 的【数据管理】->【补充数据】中,是否专门勾选并下载了**“财务数据”**。很多时候用户只下载了“日线行情”,而遗漏了财务数据。
💡 终极解决方案与代码优化
如果你希望在任意一个交易日(如 20250717)都能获取到最新的财务数据(避免 NaN),你需要对获取到的财务数据进行向前填充(Forward Fill)。同时,建议在实盘或回测中,使用 announce_time(公告期)而不是 report_time,以避免引入未来函数(因为报告期 0630 的数据,实际上要到 8 月份才公告,如果在 7 月份就使用 0630 的数据,属于偷看未来)。
以下是修改后的优化代码:
import pandas as pd
def handlebar(ContextInfo):
# 1. 获取财务数据(建议使用 announce_time 避免未来函数)
df = ContextInfo.get_financial_data(
fieldList=['PERSHAREINDEX.inc_net_profit', # 归母净利润
'PERSHAREINDEX.du_profit', # 净利润
'ASHAREINCOME.revenue_inc', # 营业收入
'PERSHAREINDEX.du_return_on_equity'], # ROE
stockList=['002130.SZ'],
startDate='20230101', # 往前多取一段时间,确保有历史数据可以向前填充
endDate='20240501', # 修改为合理的历史/当前日期
report_type='announce_time' # 按公告期取数,更符合实际交易逻辑
)
# 2. 如果 df 为空,直接返回
if df is None or df.empty:
print("未获取到财务数据,请检查数据下载情况。")
return
# 3. 清理全为 NaN 的无效行(可选)
df = df.dropna(how='all')
# 4. 向前填充数据(ffill),使得非财报发布日也能取到最近一次的财报数据
# 这样即使是 0717 这种非财报日,也能继承上一次财报的值,不再是 NaN
df_filled = df.ffill()
print("填充后的财务数据:\n", df_filled)
总结排查步骤:
- 改日期:把
endDate改为确定的历史日期(如20231231)测试是否有数据。 - 改类型:尝试将
report_type改为'announce_time'。 - 做填充:使用 Pandas 的
.ffill()方法处理非财报日的NaN值。 - 查本地:去 QMT 客户端左上角【数据管理】确认“财务数据”已下载至最新。