← 返回《初阶量化交易:策略编写及系统搭建》
📑 查看全课大纲(第 20 / 38 节)

抓取财报数据、数据定时更新

约 11 分钟

📺 正在播放小象官方高清录播(支持倍速与清晰度调节)

抓取财报数据与数据定时增量更新

小象实战讲义 · 初阶量化交易:策略编写及系统搭建 本讲义仅用于编程与量化方法教学,不构成任何投资建议。

在基本面量化与多因子选股模型中,仅有日线行情数据是远远不够的,财务报表数据(每股收益 EPS、净利润、净资产收益率 ROE 等) 构成了评估企业内在投资价值与计算估值倍数(如 PE、PB)的基石。不同于标准化的行情接口,财报数据往往散落在财经门户(如东方财富网)的数据中心中,需要通过定制爬虫进行定向采集与动态清洗。

本讲系统介绍东方财富业绩报表数据的抓包分析方法与网络爬虫编写流程;深入探讨财报披露日(Publish Date)与报告期截止日(Report Period)在量化回测中的时间戳防作弊对齐规范;并给出基于调度器的自动化定时增量入库方案。


💡 核心导读

  • 网页财报爬虫的标准五步开发流水线寻找数据源F12 网络抓包分析构造 API 请求 (Headers/参数)JSON 数据清洗MongoDB 批量存储\text{寻找数据源} \xrightarrow{\quad} \text{F12 网络抓包分析} \xrightarrow{\quad} \text{构造 API 请求 (Headers/参数)} \xrightarrow{\quad} \text{JSON 数据清洗} \xrightarrow{\quad} \text{MongoDB 批量存储}
  • 抓包实战技巧与接口分析(东方财富数据中心)
    • 通过 Chrome 开发者工具(F12 Network)定位异步数据接口(如 ygbb 业绩报表明细接口);
    • 解析返回的每股收益(EPS)、营业收入与净利润等核心财务指标,按 (code, report_date) 唯一键落库至 finance_report 集合。
  • 量化回测核心防坑:披露日(Publish Date) vs 报告期(Report Period)
    • 致命未来函数:年报报告期截止日为 12 月 31 日,但上市公司实际披露年报通常在次年 3 月或 4 月;
    • 工程铁律:回测在计算 1 月或 2 月的历史 PE 时,绝不能使用尚未披露的年报 EPS,必须严格按照实际披露日(publish_date)向后对齐(merge_asof,使用当时市场上真正已知的最新财报数据。
  • 数据定时增量更新机制(Incremental Updating)
    • 每日盘后定时调度任务(如 15:30),自动比对数据库最新日期,仅抓取当日新增行情与最新披露的财报,实现低功耗常态化运行。
┌─────────────────────────────────────────────────────────────┐
│                    财报时间戳对齐与动态 PE 计算模型             │
└──────────────────────────────┬──────────────────────────────┘

 2022-12-31 (报告期结束)        │ 2023-04-26 (年报实际披露日)
 ──────┼───────────────────────┼─────────────────────────────► (时间轴)
       │                       │
       │   在此区间回测交易时:  │ 从此处开始:
       │   ★ 严禁使用 2022 年报 │ ★ 方可正式使用 2022 年报 EPS
       │   ★ 只能使用 2022 三季报│ ★ 动态 PE = 当日 Close / 最新 EPS

一、东方财富财报抓包与爬虫实现

东方财富数据中心提供了全市场的业绩报表与预告信息:

  1. 接口定位:通过 Network 筛选 XHR/JS 请求,获取包含 EPS 与净利润的数据接口;
  2. 数据清洗:剔除退市或异常字符,将字符串类型的 EPS 转换为标准浮点数;
  3. 复合索引设计:在 finance_report 集合上创建 {'code': 1, 'report_date': 1} 唯一索引,采用 UpdateOne(..., upsert=True) 防止重复插入。

二、动态市盈率(PE)计算与防作弊对齐

在量化系统中,市盈率定义为:

PEt=ClosetEPSlatestpublishedPE_t = \frac{Close_t}{EPS{latest_published}}

必须通过 pandas.merge_asof 以交易日 date >= publish_date 的前向回溯方式进行匹配,确保回测完全符合真实历史信息流通逻辑。


📝 动手练一练

下面我们用 Python 编写一段 财报数据对齐与动态市盈率(PE)计算引擎,严格基于实际披露日合并行情与 EPS,演示如何杜绝未来函数:

import pandas as pd
import numpy as np

def calculate_dynamic_pe(price_df, finance_df):
    """
    财报数据解析与动态市盈率 (PE) 计算引擎:
    根据已实际披露的最新每股收益 (EPS), 动态计算每日市盈率 PE = Close / EPS
    """
    price_df = price_df.copy()
    
    # 模拟财报数据按实际披露日 (publish_date) 向前有序合并 (merge_asof)
    merged = pd.merge_asof(
        price_df.sort_values('date'),
        finance_df.sort_values('publish_date'),
        left_on='date',
        right_on='publish_date',
        by='code',
        direction='backward'
    )
    
    # 计算动态 PE (市盈率 = 当日收盘价 / 最新已披露每股收益 EPS)
    merged['PE'] = merged['close'] / merged['eps']
    
    # 标记价值筛选范围 (0 < PE < 30)
    merged['is_target_pe'] = (merged['PE'] > 0) & (merged['PE'] < 30.0)
    
    return merged

def test_pe_run():
    # 模拟 2023 年 4-5 月某股票价格时序
    dates = pd.to_datetime(["2023-04-20", "2023-04-25", "2023-04-28", "2023-05-04", "2023-05-10"])
    prices = pd.DataFrame({
        'code': ['600000'] * 5,
        'date': dates,
        'close': [10.0, 10.2, 10.5, 11.0, 11.2]
    })
    
    # 模拟财报披露: 4月26日披露 2022 年报 (EPS=0.80), 4月29日披露 2023 一季报 (EPS=0.90)
    finances = pd.DataFrame({
        'code': ['600000', '600000'],
        'publish_date': pd.to_datetime(["2023-04-26", "2023-04-29"]),
        'report_period': ['2022-12-31', '2023-03-31'],
        'eps': [0.80, 0.90]  # 年化 EPS
    })
    
    res = calculate_dynamic_pe(prices, finances)
    print("================ 动态市盈率 (PE) 与财报对齐引擎 ================")
    print(res[['date', 'code', 'close', 'publish_date', 'eps', 'PE', 'is_target_pe']])
    print("------------------------------------------------------------")
    print("量化防坑: 严格依据 publish_date (实际披露日) 对齐财报,杜绝报告期未来函数!")
    print("============================================================")

if __name__ == "__main__":
    test_pe_run()

运行结果输出:

================ 动态市盈率 (PE) 与财报对齐引擎 ================
        date    code  close publish_date  eps         PE  is_target_pe
0 2023-04-20  600000   10.0          NaT  NaN        NaN         False
1 2023-04-25  600000   10.2          NaT  NaN        NaN         False
2 2023-04-28  600000   10.5   2023-04-26  0.8  13.125000          True
3 2023-05-04  600000   11.0   2023-04-29  0.9  12.222222          True
4 2023-05-10  600000   11.2   2023-04-29  0.9  12.444444          True
------------------------------------------------------------
量化防坑: 严格依据 publish_date (实际披露日) 对齐财报,杜绝报告期未来函数!
============================================================

本章小结

  1. 掌握财报爬虫原理:通过抓包精准定位异步 API,提取 EPS、净利润等基础财务指标。
  2. 严守信息披露时序:必须使用实际披露日(publish_date)对齐财报,坚决杜绝报告期截止日的未来函数。
  3. 构建增量更新流水线:结合盘后调度任务与 upsert 操作,实现低维护成本的自动化数据增量入库。

📋 行动清单 (Action Checklist)

  • 运行本讲动态 PE 计算代码,观察 4 月 26 日前后的财报对齐与 PE 产生过程;
  • 检查自己爬取的财报数据集合中是否包含准确的 publish_date 字段;
  • 预习下一讲,学习如何基于动态 PE 规则构建低估值候选股票池。

— 小象教研组

配套学习资源与课件
  • 第3章课件:上手搭建最简单的交易系统(PDF · 3.8MB)
    下载
  • 开发环境准备:软件安装指导(PDF · 0.9MB · 建议第3章动手实践前先通读)
    下载
  • 量化入门推荐书单(PDF · 318KB)
    下载
🎁 免费学习资源

领取《小象 11GB VIP 课件资料包与大厂真题手册》

包含全套实战 Jupyter 源码、清洗后数据集、大厂高频面试真题与专属学员答疑交流群。

  • 完整 Python / 数据分析 Jupyter 实战源码
  • 大厂真实业务数据集与练习题
  • 微信扫码添加课程顾问,免费获取网盘下载链接
微信二维码:扫码添加课程顾问微信扫码添加顾问