数据质量评估:三大核心检查
做市库存数据,说白了就是你的交易命根子。
数据脏了,策略再好也是白搭。我见过太多团队,模型跑得飞起,结果一查数据全是坑。今天咱们就聊聊数据质量评估这件事,我把它拆成三个维度:完整性、准确性、一致性。
核心观点:数据清洗不是一次性工作,而是贯穿做市全流程的持续动作。每次数据入库,都要过这三关。
一、数据完整性检查:缺失值比例
先问个问题:你的数据表里,有多少空值?
很多人觉得缺失几个值无所谓,但做市交易里,一个缺失的 tick 数据可能让你错过最佳报价时机。我个人习惯,每次拿到新数据源,第一件事就是跑缺失值统计。
1.1 缺失值类型
- 完全随机缺失:比如网络抖动丢了一个包,这种影响相对小
- 随机缺失:跟其他字段有关,比如大单成交时行情推送延迟
- 非随机缺失:最危险的一种。比如涨跌停时数据不更新,这种缺失本身就有信息量
注意:涨跌停期间的缺失值,千万别直接填充!我曾经踩过这个坑,用前向填充把涨停价填成了正常交易价,回测结果直接翻车。
1.2 缺失值评估指标
| 指标 | 计算公式 | 阈值建议 |
|---|---|---|
| 字段缺失率 | 缺失数 / 总记录数 | < 5% 可接受,> 20% 需排查 |
| 连续缺失长度 | 连续缺失的 tick 数 | 做市数据 < 3 个 tick |
| 时间窗口缺失率 | 每 5 分钟窗口内的缺失比例 | < 1% |
# 我常用的缺失值检查代码
import pandas as pd
import numpy as np
def check_missing_quality(df, threshold=0.05):
"""
数据完整性检查
"""
# 字段级别缺失率
missing_ratio = df.isnull().mean()
print("字段缺失率:")
print(missing_ratio[missing_ratio > 0])
# 连续缺失检测
for col in ['bid_price', 'ask_price', 'last_price']:
if col in df.columns:
consecutive_missing = df[col].isnull().astype(int).groupby(
(df[col].notnull()).cumsum()
).cumsum()
max_consecutive = consecutive_missing.max()
if max_consecutive > 3:
print(f"警告:{col} 存在连续 {max_consecutive} 个缺失值")
# 时间窗口缺失率
df['time_window'] = df['timestamp'].dt.floor('5min')
window_missing = df.groupby('time_window').apply(
lambda x: x.isnull().mean()
)
return missing_ratio, window_missing
实战经验:做市数据里,bid/ask 的缺失往往比 last_price 更致命。因为报价缺失意味着你无法判断当前市场深度,策略会直接瘫痪。
二、数据准确性校验:价格跳变与涨跌停异常
数据不缺了,但数据对吗?
嗯,这里要注意。价格跳变和涨跌停异常,是做市数据里最常见的两个坑。我记得有一次,某个品种的 tick 数据里突然出现一个 99999 的价格,明显是交易所的异常报文。如果没过滤掉,策略会直接报出天价单。
2.1 价格跳变检测
什么叫价格跳变?就是相邻两个 tick 之间,价格变化幅度远超正常范围。
- 绝对跳变:价格变化超过 N 个最小变动价位
- 相对跳变:价格变化比例超过阈值(比如 1%)
- 回跳检测:价格跳变后又迅速恢复,这种往往是数据错误
def detect_price_jumps(df, price_col='last_price', threshold=0.01):
"""
检测价格跳变
threshold: 相对变化阈值,默认 1%
"""
# 计算价格变化率
price_changes = df[price_col].pct_change()
# 标记跳变点
jump_mask = price_changes.abs() > threshold
# 回跳检测:跳变后 3 个 tick 内恢复
rollback_mask = pd.Series(False, index=df.index)
for i in range(1, 4):
rollback_mask |= (price_changes.shift(-i).abs() > threshold)
# 综合判断
anomaly = jump_mask & ~rollback_mask
print(f"检测到 {anomaly.sum()} 个价格跳变异常")
return anomaly
2.2 涨跌停异常处理
涨跌停的时候,数据会变得很奇怪。价格不动了,但成交量还在涨。很多新手直接把这部分数据删掉,其实不对。
关键认知:涨跌停期间的数据,反映了市场的极端情绪。直接删除会丢失重要信息,但保留又会影响统计指标。我的做法是单独标记,做策略时特殊处理。
def handle_limit_up_down(df, limit_pct=0.1):
"""
涨跌停数据标记
limit_pct: 涨跌停幅度,比如 10%
"""
# 计算当日涨跌停价格
df['daily_high'] = df.groupby(df['timestamp'].dt.date)['last_price'].cummax()
df['daily_low'] = df.groupby(df['timestamp'].dt.date)['last_price'].cummin()
# 标记涨跌停状态
df['is_limit_up'] = (df['last_price'] >= df['daily_high'] * (1 - limit_pct * 0.01))
df['is_limit_down'] = (df['last_price'] <= df['daily_low'] * (1 + limit_pct * 0.01))
# 涨跌停期间,bid/ask 可能不更新
df.loc[df['is_limit_up'] | df['is_limit_down'], 'data_quality'] = 'limit'
return df
避坑指南:我曾经遇到过一个情况,某只股票连续涨停,但我的数据里 last_price 一直不变,导致策略以为市场没波动。后来加了涨跌停标记,才把这个问题暴露出来。
三、数据一致性核对:多源数据交叉验证
最后一个环节,也是最容易被忽视的。
你从交易所拿到的数据,和从行情商拿到的数据,对得上吗?我见过最离谱的情况,两个数据源的同一笔成交,价格差了 0.5 个 tick。这种误差在回测里可能不明显,但实盘做市时,0.5 个 tick 就是盈亏的分界线。
3.1 交叉验证维度
| 验证维度 | 检查内容 | 容忍误差 |
|---|---|---|
| 时间戳对齐 | 同一笔成交的时间是否一致 | < 1ms |
| 价格一致性 | 同一时刻的 bid/ask/last 是否匹配 | 0 误差 |
| 成交量一致性 | 累计成交量是否吻合 | < 0.1% |
| 订单簿快照 | 买卖盘口深度是否一致 | 允许 1 档差异 |
3.2 交叉验证实现
def cross_validate_data(source_a, source_b, tolerance=1e-6):
"""
多源数据交叉验证
"""
# 时间戳对齐
merged = pd.merge_asof(
source_a.sort_values('timestamp'),
source_b.sort_values('timestamp'),
on='timestamp',
suffixes=('_a', '_b'),
tolerance=pd.Timedelta('1ms')
)
# 价格一致性检查
price_diff = abs(merged['last_price_a'] - merged['last_price_b'])
price_errors = price_diff > tolerance
# 成交量一致性检查
vol_diff = abs(merged['volume_a'] - merged['volume_b'])
vol_errors = vol_diff > (merged['volume_a'] * 0.001)
# 汇总结果
results = {
'total_records': len(merged),
'price_mismatch': price_errors.sum(),
'volume_mismatch': vol_errors.sum(),
'price_error_rate': price_errors.mean(),
'volume_error_rate': vol_errors.mean()
}
return results
个人建议:交叉验证最好做成自动化脚本,每天跑一次。我团队里有个定时任务,每天早上开盘前自动跑一遍数据一致性检查,有问题直接报警。省心很多。
知识体系总览
说了这么多,咱们用一张图把整个数据质量评估的框架串起来。
这张图把咱们今天讲的内容串起来了。从原始数据进来,经过完整性、准确性、一致性三道关卡,最终输出高质量数据。每一步都有对应的检查方法和代码实现。
最后说一句:数据质量评估不是一次性工作。市场在变,数据源在变,你的检查逻辑也要跟着迭代。我团队每季度会复盘一次数据质量报告,看看哪些检查项需要调整。这个习惯,建议你也养成。