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 数据质量校验与清洗
数据质量是因子有效性的前提。以下是一套标准的数据质量校验流程:
- 完整性校验:检查时间序列是否存在缺失日期、空值或断点。
- 一致性校验:验证同一数据在不同字段或不同数据源之间是否逻辑自洽(如开盘价 ≤ 最高价 ≥ 最低价 ≤ 收盘价)。
- 异常值检测:使用 Z-Score、IQR 或 MAD 方法识别价格突变、成交量异常等离群点。
- 去重与对齐:去除重复记录,按统一时间戳对齐不同数据源。
- 填充与插值:对缺失值采用前向填充、线性插值或行业均值填充。
清洗示例:以下代码展示了如何对日频行情数据进行基础质量校验与清洗。
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 数据采集与清洗流程总览
下图展示了从数据源到因子库的完整数据采集与清洗链路,帮助你建立全局视角。
流程要点:数据清洗层是保证因子复现性的关键。建议在清洗层输出时,同时保存一份“原始数据快照”与“清洗后数据”,便于后续回溯因子计算差异时定位问题。
3.6 数据质量监控看板
建立持续的数据质量监控机制,是因子库长期稳定运行的保障。下表列出了核心监控指标与告警阈值:
| 监控维度 | 指标名称 | 正常范围 | 告警阈值 |
|---|---|---|---|
| 完整性 | 日频数据缺失率 | < 1% | ≥ 3% |
| 一致性 | OHLC 逻辑违反率 | 0% | > 0.1% |
| 时效性 | 数据延迟时间 | < 5 分钟 | ≥ 30 分钟 |
| 异常值 | 成交量 Z-Score > 5 占比 | < 0.5% | ≥ 2% |
| 重复率 | 重复记录占比 | 0% | > 0% |
监控实施建议:将上述指标接入 Prometheus + Grafana 或自建监控系统,每日生成数据质量报告。当告警触发时,自动暂停依赖该数据源的因子计算,避免脏数据污染因子库。