4. 数据质量评估指标:完整性、准确性、一致性、及时性、唯一性
好,咱们进入正题。数据清洗完了,怎么知道洗得干不干净?
你不能光凭感觉说「嗯,这数据看起来不错」。量化交易里,一个错误的数据点,可能让你亏掉六位数。我见过太多人,花了一周写清洗脚本,最后连个评估指标都没有,直接拿去跑策略——结果可想而知。
所以,今天咱们聊聊五个核心指标:完整性、准确性、一致性、及时性、唯一性。说白了,就是给数据做个「体检报告」。
核心观点: 没有评估,就没有控制。你没法改进你无法衡量的东西。
4.1 完整性(Completeness)
完整性,说白了就是「该有的数据有没有」。Tick 数据里,每个时间戳都应该有对应的价格、成交量、买卖盘口。如果某个字段是空的,那就是不完整。
定义: 数据集中非空值记录占总记录数的比例。
计算公式:
完整性 = (1 - 缺失记录数 / 总记录数) × 100%
我在项目中遇到过: 有一次处理某交易所的 Level 2 数据,发现下午 2:30 到 2:45 之间,卖一价字段全部为空。后来排查发现是交易所网关的一个 bug。如果没有完整性检查,策略在那段时间会直接崩掉。
实战建议: 我个人习惯按字段分别统计完整性。比如价格字段完整性必须 ≥ 99.99%,盘口字段可以稍微放宽到 99.9%。别一刀切。
代码示例:
def check_completeness(df, field='last_price'):
total = len(df)
missing = df[field].isna().sum()
completeness = (1 - missing / total) * 100
print(f"{field} 完整性: {completeness:.4f}%")
return completeness
4.2 准确性(Accuracy)
准确性衡量的是「数据对不对」。你想想看,数据是完整的,但价格是错的,那比缺失更可怕——它会让你做出错误的交易决策。
定义: 数据值与真实值或公认标准值的一致程度。
计算方法:
- 价格校验: 检查价格是否在合理范围内(比如 A 股价格不能为负,不能超过 1000 元)
- 涨跌幅校验: 单笔 Tick 价格变动是否超过涨跌停板限制
- 买卖价差校验: 买一价必须 ≤ 卖一价,否则数据肯定有问题
⚠️ 注意: 我曾经遇到过一个坑——某数据源把「昨收价」和「当前价」搞反了。准确性检查时,价格范围都正常,但算出来的涨跌幅全是反的。所以一定要做交叉校验。
代码示例:
def check_accuracy(df, price_field='last_price', lower=0.01, upper=1000):
errors = df[(df[price_field] < lower) | (df[price_field] > upper)]
accuracy = (1 - len(errors) / len(df)) * 100
print(f"价格准确性: {accuracy:.4f}%")
return accuracy
4.3 一致性(Consistency)
一致性,就是「不同地方的数据能不能对上」。Tick 数据经常有多个数据源,比如交易所直连、第三方数据商、自己录的数据。如果它们对不上,你信谁?
定义: 同一数据在不同系统、不同时间、不同表示形式下保持一致的程度。
检查维度:
| 检查类型 | 说明 | 示例 |
|---|---|---|
| 跨源一致性 | 不同数据源同一时刻的数据是否一致 | 数据源A vs 数据源B 的 last_price |
| 时间一致性 | 时间戳是否严格递增 | t1 < t2 < t3 ... |
| 逻辑一致性 | 买卖盘口逻辑是否自洽 | bid_price ≤ ask_price |
代码示例:
def check_time_consistency(df, time_field='timestamp'):
# 检查时间戳是否严格递增
diffs = df[time_field].diff().dropna()
inconsistent = (diffs <= 0).sum()
consistency = (1 - inconsistent / len(diffs)) * 100
print(f"时间一致性: {consistency:.4f}%")
return consistency
4.4 及时性(Timeliness)
及时性,衡量的是「数据来得够不够快」。做高频交易的,数据晚到 1 毫秒,行情就变了。做日频的,晚到 1 分钟可能还能接受。所以这个指标跟你的策略频率强相关。
定义: 数据从产生到可被使用的时间延迟。
计算方法:
- 延迟统计: 计算每个 Tick 的接收时间戳 vs 交易所时间戳的差值
- 阈值判断: 设定一个可接受的最大延迟(比如 100ms),统计超时比例
实战技巧: 我建议你画一个延迟分布图。如果大部分数据延迟在 10ms 以内,但偶尔有 500ms 的尖峰,那可能是网络抖动。这时候要及时性指标要按分位数来算,别被平均值骗了。
代码示例:
def check_timeliness(df, threshold_ms=100):
delays = df['receive_time'] - df['exchange_time']
overdue = (delays > threshold_ms).sum()
timeliness = (1 - overdue / len(df)) * 100
print(f"及时性 (阈值{threshold_ms}ms): {timeliness:.4f}%")
return timeliness
4.5 唯一性(Uniqueness)
唯一性,就是「有没有重复数据」。Tick 数据里,同一个时间戳、同一个价格、同一个成交量,如果出现两次,那就是重复。重复数据会扭曲你的统计指标,比如把成交量算成两倍。
定义: 数据集中不存在重复记录的程度。
计算公式:
唯一性 = (1 - 重复记录数 / 总记录数) × 100%
我在项目中遇到过: 有一次做回测,发现某天的成交量异常高。查了半天,原来是数据商在某个时间段重复推送了同一批 Tick。唯一性检查直接帮我揪出了这个问题。
⚠️ 注意: 唯一性检查要基于「业务主键」来判断。对于 Tick 数据,主键通常是 (时间戳 + 股票代码 + 价格 + 成交量)。别只看时间戳,因为同一毫秒内可能有多个不同的成交。
代码示例:
def check_uniqueness(df, subset=['timestamp', 'symbol', 'price', 'volume']):
total = len(df)
duplicates = df.duplicated(subset=subset).sum()
uniqueness = (1 - duplicates / total) * 100
print(f"唯一性: {uniqueness:.4f}%")
return uniqueness
4.6 综合评估:如何给数据打分?
五个指标都算出来了,怎么综合判断?我个人习惯用加权平均法。
综合质量评分公式:
Q = w1 × C1 + w2 × C2 + w3 × C3 + w4 × C4 + w5 × C5
其中:
C1 = 完整性
C2 = 准确性
C3 = 一致性
C4 = 及时性
C5 = 唯一性
w1~w5 为权重,总和为 1
权重建议(高频场景):
| 指标 | 权重 | 说明 |
|---|---|---|
| 完整性 | 0.25 | 缺数据就没法交易 |
| 准确性 | 0.30 | 错数据比缺数据更致命 |
| 一致性 | 0.20 | 多源数据必须对齐 |
| 及时性 | 0.15 | 高频交易对延迟敏感 |
| 唯一性 | 0.10 | 重复数据影响统计 |
我的经验: 如果综合评分低于 95 分,我建议你重新审视清洗流程。低于 90 分,直接弃用这批数据,别犹豫。亏钱比重新清洗更痛。
好了,这五个指标就是你的数据质量「体检表」。每次清洗完数据,跑一遍这五个函数,心里就有底了。别偷懒,养成习惯。
公众号:蓝海资料掘金营,微信deep3321