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 监控维度

我一般从四个维度来监控数据质量:

  1. 完整性:数据有没有缺失?有没有断点?
  2. 准确性:数值是否在合理范围内?有没有异常跳变?
  3. 一致性:不同数据源之间的数据是否对得上?
  4. 时效性:数据是否及时更新?延迟了多少?

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