第三章:数据源管理

做量化研究,数据就是你的命根子。这话一点都不夸张。

我见过太多团队,策略模型写得花里胡哨,结果数据源一塌糊涂,最后回测跑出来全是幻觉。说白了,数据质量决定了你的策略到底是在「发现规律」还是在「拟合噪音」。

这一章,我们就来聊聊数据源管理那些事。我会把我在实战中踩过的坑、总结的经验,都摊开来讲。

3.1 常见数据源类型

量化投资的数据源,大致可以分为三类:行情数据、财务数据、另类数据。每一类都有自己的脾气。

3.1.1 行情数据

行情数据是最基础的。包括日线、分钟线、Tick 级数据。我个人习惯把行情数据分成两个层级:

  • Level-1 行情:快照数据,每秒一次。够做大部分策略了。
  • Level-2 行情:逐笔委托、逐笔成交。做高频或者订单簿分析才需要。

我在项目中遇到过一个问题:某家数据商提供的分钟线,是用最后几秒的成交价拼出来的。你想想看,这跟真实的市场状态差多远?所以,拿到行情数据后,第一件事就是做质量检查。

3.1.2 财务数据

财务数据是基本面策略的基石。主要包括:

  • 三大报表(资产负债表、利润表、现金流量表)
  • 财务指标(ROE、PE、PB 等)
  • 业绩预告、快报

这里有个坑:财务数据有「发布日」和「报告期」的区别。比如 2024 年一季报,可能在 4 月底才发布。如果你直接用报告期去对齐交易数据,那就犯了未来函数的大忌。

⚠️ 避坑指南:我曾经因为没注意财报的「实际发布日期」,导致回测业绩虚高 30%。后来我强制要求所有财务数据必须附带「公告日期」字段,才算过关。

3.1.3 另类数据

另类数据是近年来的热门。包括:

  • 舆情数据(新闻、社交媒体)
  • 供应链数据
  • 卫星图像数据
  • 电商销售数据

另类数据的价值在于「信息差」。但它的处理成本也高。我建议:先搞清楚你的策略是否需要另类数据,别为了用而用。

3.2 数据质量检查

数据质量检查,是数据管理中最枯燥但最重要的一环。我总结了一套「四步检查法」:

  1. 完整性检查:有没有缺失日期?有没有停牌期间的数据?
  2. 一致性检查:价格、成交量是否为正?复权因子是否合理?
  3. 异常值检查:有没有突然的跳空?有没有涨停跌停但成交量异常?
  4. 交叉验证:用不同数据源互相核对。

举个例子,这是我常用的一个检查脚本片段:

def check_data_quality(df):
    """数据质量检查"""
    issues = []
    
    # 1. 完整性检查
    missing_dates = pd.date_range(start=df.index.min(), 
                                  end=df.index.max()).difference(df.index)
    if len(missing_dates) > 0:
        issues.append(f"缺失交易日: {len(missing_dates)} 天")
    
    # 2. 一致性检查
    if (df['close'] <= 0).any():
        issues.append("存在非正收盘价")
    
    # 3. 异常值检查
    daily_return = df['close'].pct_change()
    if (daily_return.abs() > 0.2).any():
        issues.append("存在单日涨跌幅超过20%的异常")
    
    return issues
💡 个人经验:我习惯把数据质量检查做成自动化脚本,每天跑一次。发现问题就发邮件报警。别等到回测跑完了才发现数据有问题,那太晚了。

3.3 数据存储与更新策略

数据存储,说白了就是解决两个问题:存哪里?怎么更新?

3.3.1 存储方案选择

我根据数据量级和访问频率,把存储方案分成三类:

数据量级 推荐方案 适用场景
小(< 10GB) CSV / Parquet 文件 个人研究、小团队
中(10GB - 1TB) SQLite / PostgreSQL 中小型团队、日频策略
大(> 1TB) ClickHouse / InfluxDB 高频策略、机构级别

我个人习惯用 Parquet 格式做本地存储。原因很简单:压缩率高、读取快、支持列式存储。你想想看,一个 5 年的日线数据,用 CSV 存可能要 2GB,用 Parquet 只要 300MB。

3.3.2 更新策略

数据更新,核心是「增量更新」而不是「全量覆盖」。全量更新太慢了,而且容易出错。

我常用的更新流程是这样的:

def update_daily_data(data_source, storage_path):
    """增量更新日线数据"""
    # 1. 获取本地已有数据的最后日期
    last_date = get_last_date(storage_path)
    
    # 2. 只拉取新数据
    new_data = fetch_data(data_source, 
                          start_date=last_date + timedelta(days=1),
                          end_date=today())
    
    # 3. 追加到本地存储
    append_to_storage(new_data, storage_path)
    
    # 4. 更新元数据
    update_metadata(storage_path, last_updated=today())
🔑 关键点:增量更新一定要做「去重检查」。我曾经因为网络重试,导致同一天的数据被插入了两次。后来我加了个唯一索引,才彻底解决。

3.4 知识体系总览

下面这张图,是我对数据源管理核心逻辑的总结。你可以把它当作一个检查清单:

数据源管理核心框架 行情数据 财务数据 另类数据 数据质量检查 完整性 一致性 异常值 交叉验证 数据存储与更新 存储方案选择 增量更新策略 去重与校验 可靠的数据资产

嗯,这张图把整个数据源管理的流程串起来了。从数据源类型,到质量检查,再到存储更新,最后输出可靠的数据资产。每一步都不能省。

💡 最后说一句:数据管理是个「脏活累活」,但也是量化研究的护城河。你花在数据上的每一分钟,都会在策略回测和实盘中得到回报。

专注资料整理