3. 数据源与数据采集

因子库的底层质量直接取决于数据源的广度、精度与采集链路的可靠性。本章系统梳理常见数据源类型、采集策略、API 对接规范以及数据质量校验与清洗流程,帮助你在构建因子库的第一步就建立坚实的数据基座。

3.1 常见数据源分类

量化数据源按属性可分为三大类:行情数据、财务数据与另类数据。下表对比了各类数据源的核心特征与典型用途。

数据类别 典型数据项 更新频率 主要用途 常见供应商
行情数据 OHLCV、Tick、Level2 快照 实时 / 日频 价格因子、动量因子、波动率因子 Wind、聚宽、Tushare、Bloomberg
财务数据 利润表、资产负债表、现金流量表 季频 / 年频 价值因子、质量因子、成长因子 Wind、东方财富、Compustat
另类数据 舆情情绪、卫星图像、电商销量、供应链数据 日频 / 周频 / 事件驱动 情绪因子、高频因子、事件驱动因子 Refinitiv、Quandl、第三方爬虫
选型建议:初期因子库建议优先接入行情与财务数据,这两类数据标准化程度高、历史覆盖长,适合快速验证因子逻辑。另类数据可作为差异化因子来源,但需额外投入数据清洗与对齐成本。

3.2 数据采集策略

数据采集策略需根据数据源类型、更新频率与延迟要求进行设计。以下是三种主流采集模式:

  • 全量快照 + 增量更新:适用于日频行情与财务数据。每日收盘后拉取全量快照,后续仅拉取增量变更,降低带宽与存储压力。
  • 实时流式采集:适用于 Tick 级行情与高频因子。通过 WebSocket 或 TCP 协议订阅实时数据流,本地缓存并落盘。
  • 定时批量拉取:适用于另类数据与低频指标。通过 Cron 任务定时调用 API,批量拉取后写入数据库。
采集架构要点:建议采用“采集层 → 缓冲层 → 存储层”三层架构。采集层负责协议适配与数据接收;缓冲层使用 Kafka 或 Redis 削峰填谷;存储层按时间分区写入 ClickHouse 或 Parquet 文件,便于后续因子计算。

3.3 API 对接规范

API 对接是数据采集的核心环节。以下是一个标准化的 RESTful API 对接流程示例:

import requests
import pandas as pd
from datetime import datetime, timedelta

def fetch_daily_quotes(api_key, symbol, start_date, end_date):
    """
    从数据供应商获取日频行情数据
    """
    url = "https://api.dataprovider.com/v1/quote/daily"
    params = {
        "symbol": symbol,
        "start": start_date,
        "end": end_date,
        "apikey": api_key,
        "format": "json"
    }
    response = requests.get(url, params=params, timeout=30)
    response.raise_for_status()
    data = response.json()
    df = pd.DataFrame(data["records"])
    df["date"] = pd.to_datetime(df["date"])
    df.set_index("date", inplace=True)
    return df

# 使用示例
df_quotes = fetch_daily_quotes(
    api_key="your_api_key_here",
    symbol="000300.SH",
    start_date="2024-01-01",
    end_date="2024-12-31"
)
print(df_quotes.head())
API 对接避坑指南:
  • 始终设置请求超时(建议 10-30 秒),避免线程阻塞。
  • 实现指数退避重试机制,应对临时性网络故障。
  • 记录每次 API 调用的响应状态码与耗时,便于监控数据源健康度。
  • 注意 API 调用频率限制(Rate Limit),合理分配请求间隔。

3.4 数据质量校验与清洗

数据质量是因子有效性的前提。以下是一套标准的数据质量校验流程:

  1. 完整性校验:检查时间序列是否存在缺失日期、空值或断点。
  2. 一致性校验:验证同一数据在不同字段或不同数据源之间是否逻辑自洽(如开盘价 ≤ 最高价 ≥ 最低价 ≤ 收盘价)。
  3. 异常值检测:使用 Z-Score、IQR 或 MAD 方法识别价格突变、成交量异常等离群点。
  4. 去重与对齐:去除重复记录,按统一时间戳对齐不同数据源。
  5. 填充与插值:对缺失值采用前向填充、线性插值或行业均值填充。
清洗示例:以下代码展示了如何对日频行情数据进行基础质量校验与清洗。
def clean_quote_data(df):
    """
    清洗日频行情数据:去重、排序、异常值标记、缺失填充
    """
    # 去重
    df = df[~df.index.duplicated(keep='first')]
    # 排序
    df.sort_index(inplace=True)
    # 一致性校验:标记违反 OHLC 逻辑的记录
    mask = (df["high"] >= df["low"]) & \
           (df["high"] >= df["close"]) & \
           (df["low"] <= df["open"])
    df["quality_flag"] = mask.astype(int)
    # 异常值检测:成交量超过 5 倍滚动标准差
    df["volume_zscore"] = (df["volume"] - df["volume"].rolling(20).mean()) / \
                          df["volume"].rolling(20).std()
    df.loc[df["volume_zscore"].abs() > 5, "quality_flag"] = -1
    # 缺失值前向填充
    df.fillna(method='ffill', inplace=True)
    return df

df_clean = clean_quote_data(df_quotes)
print(df_clean["quality_flag"].value_counts())

3.5 数据采集与清洗流程总览

下图展示了从数据源到因子库的完整数据采集与清洗链路,帮助你建立全局视角。

数据采集与清洗流程总览 数据采集与清洗流程总览 行情数据源 财务数据源 另类数据源 API 采集层(RESTful / WebSocket / 批量拉取) 缓冲层(Kafka / Redis 削峰填谷) 数据清洗层(完整性 / 一致性 / 异常值 / 去重 / 填充) 存储层(ClickHouse / Parquet / HDF5) 质量校验点
流程要点:数据清洗层是保证因子复现性的关键。建议在清洗层输出时,同时保存一份“原始数据快照”与“清洗后数据”,便于后续回溯因子计算差异时定位问题。

3.6 数据质量监控看板

建立持续的数据质量监控机制,是因子库长期稳定运行的保障。下表列出了核心监控指标与告警阈值:

监控维度 指标名称 正常范围 告警阈值
完整性 日频数据缺失率 < 1% ≥ 3%
一致性 OHLC 逻辑违反率 0% > 0.1%
时效性 数据延迟时间 < 5 分钟 ≥ 30 分钟
异常值 成交量 Z-Score > 5 占比 < 0.5% ≥ 2%
重复率 重复记录占比 0% > 0%
监控实施建议:将上述指标接入 Prometheus + Grafana 或自建监控系统,每日生成数据质量报告。当告警触发时,自动暂停依赖该数据源的因子计算,避免脏数据污染因子库。