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

获取指数和个股历史行情数据

约 28 分钟

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

获取指数和个股历史行情数据

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

在量化交易系统中,数据被称为”量化之血”。一切数学建模、特征工程与策略回测,都建立在高质量、高一致性的底层行情与财务数据之上。对于 A 股市场而言,数据获取面临着除权除息(XD/XR)价格跳空、大盘指数与个股编码混淆、交易日历缺失等一系列真实的工程挑战。

本讲系统介绍如何通过 Python 财经数据接口(Tushare)批量抓取全市场历史行情;深度剖析量化数据库中不复权数据集合(daily)与后复权数据集合(daily_hfq)的职责分工与存储规范;并阐明”先抓指数、后抓个股”的交易日历对齐工程设计。


💡 核心导读

  • 行情数据的核心 7 要素与集合存储规范
    • code(股票/指数代码,如 600000000300);
    • date(标准 ISO 交易日期,如 2023-05-04);
    • index(布尔标记:True 为指数,False 为个股);
    • openclosehighlow(四价序列);
    • volume(成交量)。
  • 不复权(daily) vs 后复权(daily_hfq)的分工哲学
    • 除权除息断崖:当上市公司实施高送转(如 10 送 10)或大额分红时,除权日股价出现断崖式除权缺口(例如从 20 元跌至 10 元),市值并未变动;
    • 后复权(daily_hfq:以历史首日价格为基准,将后续所有分红除权收益向上累加,保持价格曲线平滑无跳空,专用于技术指标计算(MA、MACD、RSI、BOLL)与择时信号生成
    • 不复权(daily:真实记录历史上当日交易所的实际挂牌价,专用于计算每日实际可成交股数、可用资金占用与市盈率(PE)估值计算
  • 先抓指数(Index First)的工程意义
    • 大盘指数(如沪深 300 000300、上证指数 000001)永不停牌,其时间序列构成全市场最权威的标准交易日历(Trading Calendar)
    • 先入库指数数据,可在后续数据清洗中作为基准标尺,精准识别并修复个股的停牌与数据缺失。
┌─────────────────────────────────────────────────────────────┐
│                    量化行情数据库双集合分工模型                 │
└──────────────────────────────┬──────────────────────────────┘

 ┌─────────────────────────────┴─────────────────────────────┐
 ▼                                                           ▼
┌──────────────────────────────┐           ┌──────────────────────────────┐
│   不复权集合 (daily)          │           │   后复权集合 (daily_hfq)      │
├──────────────────────────────┤           ├──────────────────────────────┤
│ • 记录历史真实挂牌成交价     │           │ • 消除除权除息跳空断崖       │
│ • 用于实际买卖撮合与资金计算 │           │ • 保持价格曲线平滑连续       │
│ • 用于计算每日动态 PE / PB   │           │ • 专用于计算 MACD/RSI/均线   │
└──────────────────────────────┘           └──────────────────────────────┘

一、除权除息对量化信号的致命影响

假设一只股票在 tt 日收盘价为 20.0 元,当晚实施 10 送 10 除权除息,在 t+1t+1 日开盘参考价降为 10.0 元并平开收于 10.0 元:

  • 不复权视角:当日收益率为 (10.020.0)/20.0=50.0%(10.0 - 20.0)/20.0 = -50.0%,均线与 MACD 会产生虚假暴跌信号;
  • 后复权视角t+1t+1 日收盘价等价于 10.0×2.0=20.010.0 \times 2.0 = 20.0 元,收益率为 0.0%0.0%,真实反映持仓价值未变。

因此,技术指标计算必须在 daily_hfq 集合上运行,而账户资金回测必须在 daily 集合上进行


二、行情抓取流水线与 MongoDB 批量入库

工程实现中,DailyCrawler 封装了标准的数据拉取与持久化流程:

  1. 防重复入库:使用 (code, date) 作为唯一复合索引,采用 UpdateOne(..., upsert=True)
  2. 批量并发写入:使用 bulk_write 减少与 MongoDB 的网络往返 IO 开销。

📝 动手练一练

下面我们用 Python 编写一段代码,直观对比不复权与后复权价格在除权事件发生时的收益率差异,验证双数据集合存储的必要性:

import pandas as pd
import numpy as np

def simulate_daily_and_hfq_data():
    """
    演示量化系统中不复权 (daily) 与 后复权 (daily_hfq) 的异同及除权除息影响
    """
    dates = pd.date_range("2023-05-01", periods=6, freq="B")
    
    # 模拟某股票在第 4 天发生 10 送 10 除权除息:
    # 1. 真实不复权挂牌价: 20 -> 21 -> 22 -> 11 (除权断崖) -> 11.5 -> 12.0
    daily_close = [20.0, 21.0, 22.0, 11.0, 11.5, 12.0]
    
    # 2. 后复权价格: 保持走势平滑 (除权后乘以复权因子 2.0)
    hfq_close = [20.0, 21.0, 22.0, 22.0, 23.0, 24.0]
    
    stock_df = pd.DataFrame({
        'code': '600000',
        'close_raw': daily_close,
        'close_hfq': hfq_close,
        'index': False
    }, index=dates)
    
    # 计算日收益率
    stock_df['raw_pct_change'] = stock_df['close_raw'].pct_change() * 100.0
    stock_df['hfq_pct_change'] = stock_df['close_hfq'].pct_change() * 100.0
    
    print("================ 行情数据: 不复权 vs 后复权 ================")
    print(stock_df[['code', 'close_raw', 'close_hfq', 'raw_pct_change', 'hfq_pct_change']])
    print("----------------------------------------------------------")
    print("量化启示: 不复权价格在除权日显示暴跌 -50% (虚假信号),而后复权真实反映 0.0% 涨跌!")
    print("指标计算必须使用 daily_hfq,实盘真实成交与市值必须使用 daily!")
    print("==========================================================")

if __name__ == "__main__":
    simulate_daily_and_hfq_data()

运行结果输出:

================ 行情数据: 不复权 vs 后复权 ================
              code  close_raw  close_hfq  raw_pct_change  hfq_pct_change
2023-05-01  600000       20.0       20.0             NaN             NaN
2023-05-02  600000       21.0       21.0        5.000000        5.000000
2023-05-03  600000       22.0       22.0        4.761905        4.761905
2023-05-04  600000       11.0       22.0      -50.000000        0.000000
2023-05-05  600000       11.5       23.0        4.545455        4.545455
2023-05-08  600000       12.0       24.0        4.347826        4.347826
----------------------------------------------------------
量化启示: 不复权价格在除权日显示暴跌 -50% (虚假信号),而后复权真实反映 0.0% 涨跌!
指标计算必须使用 daily_hfq,实盘真实成交与市值必须使用 daily!
==========================================================

本章小结

  1. 严格区分双数据集合daily 记录真实历史挂牌价用于资金撮合,daily_hfq 记录后复权价格用于技术指标运算。
  2. 指数作为交易日历基准:优先抓取大盘指数,建立标准化时间轴,为后续清洗个股停牌与缺失提供基准。
  3. 高效批量入库实践:利用 MongoDB 的复合索引与批量 Upsert,保障海量金融时序数据的高效持久化。

📋 行动清单 (Action Checklist)

  • 运行本讲模拟代码,观察不复权与后复权在除权日的收益率跳变差异;
  • 检查本地 MongoDB 中的 dailydaily_hfq 集合设计,确保包含 (code, date) 索引;
  • 预习下一讲,学习如何系统清洗与修复行情数据中的停牌与缺失值。

— 小象教研组

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

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

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

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