问题描述
用query获取的股票利润数据,如截图中长江电力的年末的数据连续缺失,请问是什么原因造成的?谢谢!
q = query(income.statDate,income.code,income.netprofit).filter(income.code.in(stocks))
df_all = pd.concat([get_fundamentals(q,date=i) for i in latest_trade_dates], axis=0)
解决方案
在 JoinQuant 平台中使用 get_fundamentals 获取财务数据时,遇到年末利润数据“缺失”或不符合预期,通常是由以下几个原因造成的:
1. date 参数的查询逻辑
当您使用 get_fundamentals(q, date=i) 时,系统查询的是在指定日期 i 收盘后所能看到的最新一期单季度财务数据。为了避免未来函数,系统严格按照财报实际披露日期来返回数据。
例如,如果您将 date 设置为某年的 12 月 31 日,此时该公司的年度报告(年报)尚未发布(年报通常在次年的 1 月至 4 月披露)。因此,在 12 月 31 日这一天,市场能看到的最新财报其实是第三季度报告(Q3)。这就导致您按年末日期查询时,获取到的 statDate 往往是三季报的日期,从而产生“年末数据缺失”的错觉。
2. 单季度数据 vs 累计数据
JoinQuant 的 income 表默认提供的是单季度数据,而不是年度累计数据。如果您希望获取全年的利润总和,按 date 查询单季度表是无法直接得到年度总利润的。
解决方法
如果您明确需要获取年度的财务数据,建议放弃使用 date 参数,改用 statDate 参数,或者使用专门获取历史财务数据的 API get_history_fundamentals。
方法一:使用 statDate 参数获取年度数据
statDate 允许您直接指定财报统计的年份或季度。例如,传入 '2020' 表示获取 2020 年的年报数据。
# 导入需要的库
import pandas as pd
from jqdata import *
stocks = ['600900.XSHG'] # 以长江电力为例
years = ['2019', '2020', '2021', '2022'] # 需要查询的年份
q = query(income.statDate, income.code, income.net_profit).filter(income.code.in_(stocks))
# 循环获取每年的年报数据
df_list = []
for year in years:
# 注意:使用 statDate 时,不需要传入 date 参数
df = get_fundamentals(q, statDate=year)
df_list.append(df)
df_all = pd.concat(df_list, axis=0)
print(df_all)
注意:使用 statDate 获取历史年报时,在回测中如果不注意当前逻辑时间,可能会引入未来函数。请确保在回测中,您查询的 statDate 对应的财报在当前 context.current_dt 已经实际披露。
方法二:使用 get_history_fundamentals (推荐)
如果您需要获取过去多个季度或年度的历史财务数据,get_history_fundamentals 是更高效且安全的选择。它可以指定观察日期(watch_date),有效避免未来函数。
from jqdata import *
stocks = ['600900.XSHG']
# 获取长江电力在 2023-01-01 之前能看到的过去 4 年的年度利润数据
df = get_history_fundamentals(stocks,
fields=[income.net_profit],
watch_date='2023-01-01',
count=4,
interval='1y',
stat_by_year=True)
print(df)
总结
您遇到的“数据缺失”实际上是 API 严格遵守财报披露时间线的结果。将查询方式从“按日期查询最新单季度财报 (date)”改为“按报告期查询年度财报 (statDate 或 get_history_fundamentals)”,即可解决您的问题。