数据质量检查:数据完整性验证、异常值检测与处理、数据对齐与频率统一

做量化交易,数据就是你的弹药。弹药有问题,枪法再准也白搭。

我见过太多人,策略回测曲线漂亮得不行,一上实盘就崩。十有八九,问题出在数据上。今天咱们就聊聊数据质量检查这回事。说白了,就是给你的数据做个全面体检。

核心观点:数据质量决定了策略可靠性的上限。数据脏,策略再牛也是空中楼阁。

数据质量检查 数据完整性验证 缺失值检查 · 时间戳连续性 异常值检测与处理 3σ · IQR · 截尾 · 插值 数据对齐与频率统一 重采样 · 时间戳对齐 前向填充 线性插值 3σ 法 IQR 法 降采样 升采样 数据干净 → 策略可信

一、数据完整性验证

数据完整性,说白了就是检查数据有没有「缺胳膊少腿」。我刚开始做回测时,拿到的日线数据看起来挺完整,结果一跑策略,某天突然跳空——原来是那天数据丢了。

完整性验证主要看两件事:

  • 时间戳是否连续——交易日有没有缺失
  • 字段值是否完整——开盘价、收盘价、成交量等有没有空值

举个例子,检查时间戳连续性:

import pandas as pd

# 假设 df 是日线数据,索引为 DatetimeIndex
# 检查是否有缺失的交易日
date_range = pd.date_range(start=df.index.min(), end=df.index.max(), freq='D')
missing_dates = date_range.difference(df.index)

if len(missing_dates) > 0:
    print(f"发现 {len(missing_dates)} 个缺失交易日")
    print(missing_dates[:10])  # 打印前10个
else:
    print("时间戳完整,没有缺失")

我的经验:别只看交易日历。A股有调休、港股有台风休市,直接用 calendar 容易踩坑。我个人习惯用交易所官方交易日历做基准。

对于字段空值,我一般用 df.isnull().sum() 快速扫一眼。如果空值比例超过 5%,我会怀疑数据源本身有问题。

二、异常值检测与处理

异常值,就是那些明显「不对劲」的数据点。比如某只股票平时成交量几千万,突然某天显示 0,或者价格突然涨了 100 倍——这明显是数据录入错误。

我常用的检测方法有两种:

方法 原理 适用场景
3σ 法 超出均值 ± 3 倍标准差 近似正态分布的数据
IQR 法 超出 Q1 - 1.5×IQR 或 Q3 + 1.5×IQR 偏态分布、有离群点

代码实现也不复杂:

def detect_outliers_iqr(series):
    Q1 = series.quantile(0.25)
    Q3 = series.quantile(0.75)
    IQR = Q3 - Q1
    lower = Q1 - 1.5 * IQR
    upper = Q3 + 1.5 * IQR
    return (series < lower) | (series > upper)

# 检测收盘价异常
outliers = detect_outliers_iqr(df['close'])
print(f"发现 {outliers.sum()} 个异常值")

注意:别一发现异常值就删掉。我曾经处理过一只股票,某天因为分红导致价格跳空,IQR 法把它标成了异常。但那是正常事件,不该处理。

处理异常值,我一般按优先级来:

  1. 确认数据源——先查是不是数据源本身错了
  2. 截尾处理——把异常值替换为上下限
  3. 插值填充——用前后值做线性插值
  4. 直接删除——实在没办法才删

举个例子,截尾处理:

def winsorize(series, limits=(0.01, 0.01)):
    """截尾处理,默认上下各截 1%"""
    lower = series.quantile(limits[0])
    upper = series.quantile(1 - limits[1])
    return series.clip(lower, upper)

df['close_clean'] = winsorize(df['close'])

三、数据对齐与频率统一

做多因子策略时,你可能会从不同数据源拿数据。有的数据是日频,有的是分钟频,还有的是 tick 级。频率不统一,策略就没法跑。

数据对齐的核心就一句话:以最低频率为基准,统一时间戳

举个例子,把分钟数据降采样到日线:

# 分钟数据 -> 日线数据
df_daily = df_minute.resample('D').agg({
    'open': 'first',
    'high': 'max',
    'low': 'min',
    'close': 'last',
    'volume': 'sum'
})

反过来,如果要把日线数据对齐到分钟级别,就需要升采样:

# 日线数据 -> 分钟数据(前向填充)
df_minute = df_daily.resample('1min').ffill()

避坑指南:我曾经把美股数据和 A 股数据直接合并,结果发现时间戳差了 12 小时——因为没做时区转换。记住,所有时间戳统一到 UTC 或交易所本地时间,别混用。

数据对齐还有一个容易忽略的点:不同资产的交易时间不一样。A 股 9:30 开盘,港股 9:00 开盘,美股 9:30(美东时间)。做跨市场策略时,一定要先对齐时间窗口。

小结

数据质量检查,说白了就是三件事:

  • 完整性——数据有没有缺
  • 准确性——数据有没有错
  • 一致性——数据能不能一起用

这三步走完,你的数据才算「能用」。别嫌麻烦,我见过太多人在这上面翻车。数据干净了,策略才有说服力。

一句话总结:数据质量检查不是锦上添花,而是量化交易的「入场券」。跳过这一步,后面全是白费功夫。

蓝海数据掘金营,专注资料整理