问题描述
解决方案
在 JoinQuant(聚宽)平台中,查询上市公司的营业利润和净利润数据,主要通过 get_fundamentals 函数配合 income(利润表)对象来实现。
以下是具体的查询方法和代码示例。
核心步骤
- 使用函数:
get_fundamentals(query_object, date=None, statDate=None) - 查询对象:
income表(利润表) - 关键字段:
income.operating_profit:营业利润income.net_profit:净利润
代码示例
1. 在研究环境(Research)中查询
在研究环境中,通常用于分析历史数据。你可以指定具体的日期(date)或报告期(statDate)。
# 导入聚宽数据库
from jqdata import *
# 构造查询语句
q = query(
income.code, # 股票代码
income.statDate, # 财报统计日期
income.pubDate, # 财报发布日期
income.operating_profit, # 营业利润
income.net_profit # 净利润
).filter(
# 这里以平安银行(000001.XSHE)和贵州茅台(600519.XSHG)为例
income.code.in_(['000001.XSHE', '600519.XSHG'])
)
# 获取 2023-12-31 之前发布的最新一份财报数据
# date参数表示观察日期,系统会返回该日期能看到的最新数据,避免未来函数
df = get_fundamentals(q, date='2023-12-31')
print(df)
2. 在回测/模拟交易(Backtest)中查询
在策略代码中,通常使用 context.current_dt 或 context.previous_date 来获取策略运行当天的财务数据。
def initialize(context):
# 设置我们要操作的股票
g.security_list = ['000001.XSHE', '600519.XSHG']
run_daily(my_trade, 'every_bar')
def my_trade(context):
# 构造查询
q = query(
income.code,
income.operating_profit,
income.net_profit
).filter(
income.code.in_(g.security_list)
)
# 查询数据,date传入 context.previous_date 以确保获取的是盘前已知的数据
# 注意:get_fundamentals 默认查询的是单季度数据还是累积数据取决于财报类型,
# 通常 income 表返回的是当期报告期的数据。
df = get_fundamentals(q, date=context.previous_date)
if not df.empty:
for index, row in df.iterrows():
log.info(f"股票: {row['code']}, 营业利润: {row['operating_profit']}, 净利润: {row['net_profit']}")
进阶说明:查询指定季度的财报
如果你需要查询特定季度(例如2023年第一季度)的数据,而不是“当前最新”的数据,可以使用 statDate 参数。
from jqdata import *
q = query(
income.code,
income.operating_profit,
income.net_profit
).filter(
income.code == '000001.XSHE'
)
# 查询 2023年第一季度 的数据
df_q1 = get_fundamentals(q, statDate='2023q1')
# 查询 2022年年度报告 的数据
df_year = get_fundamentals(q, statDate='2022')
print(df_q1)
注意事项
- 单位:返回的金额单位通常为元。
- 数据更新:
get_fundamentals在回测中,如果传入date参数,会返回该日期收盘后能看到的最新数据(即考虑了财报发布日期的延迟),这能有效避免未来函数。 - TTM数据:如果你做量化选股,通常更推荐使用 TTM(滚动12个月) 数据来消除季节性影响。TTM数据通常在
indicator表或因子库中,例如operating_profit_ttm和net_profit_ttm。
Q&A
Q: date 和 statDate 参数有什么区别?
A: date 是观察日期,查询的是在该日期“也就是当时”能看到的最新财报数据,用于模拟真实交易场景,避免未来函数。statDate 是财报统计期(如 '2023q1'),用于强制获取某一个具体季度的财报,不管它是什么时候发布的,通常用于历史研究。
Q: 查询到的利润数据是单季度的还是累积的?
A: get_fundamentals 查询 income 表时,返回的数据通常是该报告期的数据。对于季报(q1, q2, q3),通常是年初至报告期末的累计数,或者单季度数,具体取决于聚宽数据的清洗规则。为了稳健性,建议在做因子分析时使用 indicator 表中的 TTM 数据,或者使用 get_fundamentals_continuously 获取连续季度数据自行差分计算单季度值。
Q: 如何查询扣非净利润?
A: 扣非净利润的字段通常为 income.adjusted_profit(扣除非经常性损益后的净利润)。查询方式与上述代码一致,只需将 income.net_profit 替换或增加 income.adjusted_profit 即可。