3、因子数据源管理:数据源类型、接入规范与质量监控
做量化这几年,我最大的体会就是:因子研究到最后,拼的不是模型多 fancy,而是数据底子扎不扎实。你想想看,再牛的策略,喂进去的数据是脏的,出来的结果能信吗?
这一章,咱们就聊聊数据源管理。说白了,就是搞清楚三件事:数据从哪来、怎么接进来、怎么保证它靠谱。
3.1 数据源类型:行情、财务、舆情
我个人习惯把数据源分成三大类。每一类都有它的脾气,你得顺着毛捋。
3.1.1 行情数据
这是最基础、最刚需的数据。包括日线、分钟线、Tick 级数据。我在项目中遇到过最头疼的事,就是不同交易所的 Tick 数据时间戳格式不统一。上交所用毫秒,深交所用微秒,你直接拼在一起算因子,结果全是错的。
| 子类型 | 频率 | 典型字段 | 常见问题 |
|---|---|---|---|
| 日线 | 每日 | open, high, low, close, volume | 复权处理、停牌数据 |
| 分钟线 | 1min/5min/30min | 同上 + 成交笔数 | 不同交易所收盘时间差异 |
| Tick 级 | 逐笔 | price, volume, bid/ask | 数据量巨大,存储成本高 |
3.1.2 财务数据
财务数据是基本面因子的命根子。但这里有个大坑——数据时效性。财报发布日和实际数据截止日之间,有滞后。你拿最新一期的财报算 PE,可能用的还是三个月前的数据。
我曾经犯过一个错:直接用财报发布日期对齐数据,结果算出来的因子在回测里表现特别好,实盘却一塌糊涂。后来才发现,我用的「最新」数据,在实盘时根本还没发布。这就是典型的前视偏差。
- 资产负债表:总资产、负债、股东权益
- 利润表:营业收入、净利润、扣非净利润
- 现金流量表:经营活动现金流净额
- 衍生指标:ROE、ROA、毛利率、净利率
3.1.3 舆情数据
舆情数据这两年越来越火。新闻、公告、社交媒体、研报,都能挖出 alpha。但说实话,这玩意儿最难搞。为什么?因为它是非结构化的。
我记得有一次接了一个新闻情感分析的数据源,对方说准确率 90%。结果我一测,发现它对「业绩预增」和「业绩预亏」的判断准确率确实高,但对「业绩预告修正」这种中性表述,直接给判成了正面。嗯,这里要注意:舆情数据的质量,不能只看整体准确率,要分场景看。
- 新闻:财经新闻、公司公告、行业政策
- 社交媒体:股吧、雪球、微博讨论
- 研报:券商研报、评级调整
- 另类数据:招聘信息、供应链数据、卫星图像
3.2 数据接入规范
数据接入这事,看着简单,做起来全是细节。我见过太多团队,数据源换了一个,整个因子库就得重写一遍。说白了,就是没做好抽象层。
3.2.1 统一接入接口
我个人建议,所有数据源都走同一个接口。不管底层是 CSV、数据库、API 还是消息队列,对外暴露的接口必须一致。
# 这是我常用的数据接入抽象类
class DataSource:
def __init__(self, config):
self.config = config
def get_data(self, symbol, start_date, end_date, fields=None):
"""统一的数据获取接口"""
raise NotImplementedError
def get_latest(self, symbol, fields=None):
"""获取最新数据"""
raise NotImplementedError
def check_health(self):
"""健康检查"""
raise NotImplementedError
3.2.2 数据格式标准化
不同数据源,字段名可能不一样。比如「收盘价」,有的叫 close,有的叫 closing_price,还有的叫 last_price。你想想看,如果每个因子都去适配不同的字段名,那维护成本得多高?
| 标准字段名 | 含义 | 常见别名 |
|---|---|---|
| symbol | 证券代码 | code, ticker, instrument_id |
| trade_date | 交易日期 | date, datetime, timestamp |
| open | 开盘价 | open_price, opn |
| close | 收盘价 | close_price, last_price, cls |
| volume | 成交量 | vol, turnover_volume |
3.3 数据质量监控
数据质量监控,说白了就是防呆。你不能假设数据源永远靠谱。我见过太多案例,数据源某一天突然断了,或者某个字段全变成了 NaN,结果因子库跑出来的信号全是错的。
3.3.1 监控维度
我一般从四个维度来监控数据质量:
- 完整性:数据有没有缺失?有没有断点?
- 准确性:数值是否在合理范围内?有没有异常跳变?
- 一致性:不同数据源之间的数据是否对得上?
- 时效性:数据是否及时更新?延迟了多少?
3.3.2 自动化监控脚本
这是我团队里每天都在跑的监控脚本片段:
def check_data_quality(df, symbol, date):
issues = []
# 1. 检查缺失值
missing_pct = df.isnull().sum() / len(df)
if missing_pct['close'] > 0.05:
issues.append(f"{symbol} 在 {date} 的收盘价缺失超过5%")
# 2. 检查异常值
if df['close'].max() > df['close'].median() * 10:
issues.append(f"{symbol} 在 {date} 的收盘价存在异常跳变")
# 3. 检查时间连续性
date_diff = df['trade_date'].diff().dropna()
if (date_diff > pd.Timedelta(days=1)).any():
issues.append(f"{symbol} 在 {date} 存在数据断点")
return issues
3.3.3 告警与处理机制
发现问题只是第一步,怎么处理才是关键。我建议设置三级告警:
- 黄色告警:数据延迟超过 30 分钟,自动重试一次
- 橙色告警:数据缺失超过 1%,触发人工复核
- 红色告警:数据异常跳变超过 5 个标准差,立即暂停因子计算
3.4 知识体系总览
下面这张图,是我对数据源管理的整体理解。你可以把它当成一个检查清单,看看自己的数据管理流程有没有遗漏。
数据源管理这件事,说难不难,说简单也不简单。核心就一句话:把数据当成产品来管理。给它定标准、做监控、设告警。只有这样,你的因子库才能跑得稳、跑得久。
好了,这一章就聊到这儿。记住,数据质量是因子研究的生命线。别等到出了问题再后悔,那时候就晚了。
公众号:蓝海资料掘金营,微信deep3321