问题描述
解决方案
在PTrade中,获取上市公司的一季报、半年报和年报数据,主要通过 get_fundamentals 函数实现。关键在于设置 report_types 参数。
核心参数说明
get_fundamentals 函数中的 report_types 参数用于指定财报类型:
'1':表示 一季报。'2':表示 半年报(中报)。'3':表示 三季报(截止到三季度的累计数据)。'4':表示 年报。
获取方式
你可以通过两种模式来获取这些数据:
- 按年份查询模式(推荐用于研究历史数据):指定
start_year和end_year,配合report_types获取特定年份的特定财报。 - 按日期查询模式(推荐用于回测防未来函数):指定
date,配合report_types获取在指定日期前发布的最近一份特定类型的财报。
策略代码示例
以下是一个完整的策略示例,展示了如何在 initialize 或 handle_data 中分别获取一季报、半年报和年报的净利润数据。
def initialize(context):
# 设置股票池,以恒生电子为例
g.security = '600570.SS'
set_universe(g.security)
# 为了演示,我们在初始化后直接运行一次查询逻辑
# 实际策略中可以在 before_trading_start 或 handle_data 中调用
run_daily(context, check_financial_reports, time='09:30')
def check_financial_reports(context):
stock = g.security
# 设定查询的财务字段,这里以利润表中的净利润(net_profit)为例
# 表名: income_statement (利润表)
table_name = 'income_statement'
field_name = 'net_profit'
log.info("========== 开始查询财报数据 ==========")
# -------------------------------------------------------
# 方式一:按年份查询 (获取指定年份的特定财报)
# -------------------------------------------------------
# 1. 获取 2022年的 一季报
q1_data = get_fundamentals(
stock,
table_name,
field_name,
start_year='2022',
end_year='2022',
report_types='1'
)
log.info("2022年一季报净利润: %s" % q1_data)
# 2. 获取 2022年的 半年报
semi_data = get_fundamentals(
stock,
table_name,
field_name,
start_year='2022',
end_year='2022',
report_types='2'
)
log.info("2022年半年报净利润: %s" % semi_data)
# 3. 获取 2022年的 年报
annual_data = get_fundamentals(
stock,
table_name,
field_name,
start_year='2022',
end_year='2022',
report_types='4'
)
log.info("2022年年报净利润: %s" % annual_data)
# -------------------------------------------------------
# 方式二:按日期查询 (获取指定日期前最新发布的特定财报)
# 这种方式在回测中非常重要,可以避免用到未来数据
# -------------------------------------------------------
current_date = context.blotter.current_dt.strftime("%Y%m%d")
# 获取当前日期(回测日)之前发布的最近一份年报
# 如果当前是2023年3月,可能获取到的是2021年的年报(因为2022年报可能还没发)
# 如果当前是2023年5月,通常能获取到2022年的年报
latest_annual = get_fundamentals(
stock,
table_name,
field_name,
date=current_date,
report_types='4'
)
log.info("截止%s前发布的最近一份年报净利润: %s" % (current_date, latest_annual))
def handle_data(context, data):
pass
注意事项
- 数据表选择:
get_fundamentals的第二个参数需要指定表名。常用的有:balance_statement(资产负债表)income_statement(利润表)cashflow_statement(现金流量表)growth_ability(成长能力)profit_ability(盈利能力)eps(每股指标)operating_ability(营运能力)debt_paying_ability(偿债能力)
- 返回格式:
- 按日期查询时,返回的是
pandas.DataFrame。 - 按年份查询时,返回的是
pandas.Panel(在旧版Pandas中)或多级索引的DataFrame(取决于PTrade具体的Pandas版本,通常建议打印出来确认结构)。
- 按日期查询时,返回的是
- 缺失值:如果指定年份或日期的财报尚未披露,或者数据不存在,返回结果中对应的值可能为
NaN。
Q&A
Q: 如果我不指定 report_types 会返回什么?
A:
- 如果是按年份查询 (
start_year/end_year),不输入report_types将返回当年可查询到的全部类型财报。 - 如果是按日期查询 (
date),不输入report_types将返回距离指定日期最近一份财报(通常是最近的一个季度数据)。
Q: 如何获取三季报?
A: 将 report_types 设置为 '3' 即可。
Q: get_fundamentals 有调用限制吗?
A: 有。每秒不得调用超过100次,单次最大调用量是500条数据(1个股票1个字段算1条)。如果在循环中大量调用,建议使用 time.sleep() 进行间隔,或者一次性传入多个股票代码和字段进行批量查询。