3. 高频行情数据特征:数据频率、噪声、缺失与异常值处理
高频行情数据是量化交易系统最底层的“燃料”。与日线或分钟线数据不同,高频数据在毫秒甚至微秒级别采集,其质量直接决定坏账率告警阈值的可信度。本节从数据频率、噪声、缺失与异常值三个维度展开,帮助架构师建立数据质量评估与清洗的工程化标准。
3.1 数据频率:毫秒级与微秒级的工程差异
高频行情的数据频率通常分为两个层级:毫秒级(1-1000ms) 和 微秒级(1-1000μs)。不同频率对存储、计算和告警逻辑的要求差异显著。
| 维度 | 毫秒级(Tick) | 微秒级(Ultra-Tick) |
|---|---|---|
| 典型数据量 | 约 3-5 万条/日/品种 | 约 50-200 万条/日/品种 |
| 时间戳精度 | 毫秒(3位小数) | 微秒(6位小数) |
| 存储开销 | 较低(可存关系型数据库) | 高(需时序数据库或列存) |
| 坏账率计算窗口 | 秒级窗口(如 5s) | 毫秒级窗口(如 100ms) |
| 告警阈值抖动 | 较小,可容忍 | 较大,需平滑滤波 |
工程建议: 微秒级数据在计算坏账率时,建议先做时间桶聚合(如 10ms 桶),再计算滑动窗口均值,避免单笔微秒级抖动触发误告警。
3.2 数据噪声:来源、类型与滤波策略
高频行情中的噪声主要来自三个方面:网络抖动(延迟尖刺)、撮合引擎微结构(订单簿短暂失衡)、数据源时钟不同步。噪声会导致坏账率计算出现“假阳性”或“假阴性”。
3.2.1 噪声分类
| 噪声类型 | 典型表现 | 对坏账率的影响 |
|---|---|---|
| 价格毛刺 | 单笔价格偏离正常范围 > 5% | 瞬间拉高坏账率,触发误告警 |
| 时间戳乱序 | 后一笔时间戳小于前一笔 | 导致窗口计算逻辑混乱 |
| 重复数据 | 同一笔行情被推送多次 | 重复计入坏账,放大指标 |
| 买卖价差异常 | 价差突然扩大 10 倍以上 | 流动性假象,误导阈值判断 |
3.2.2 常用滤波方法
- 中值滤波: 对连续 N 笔价格取中位数,适合剔除单点毛刺,延迟约 N/2 笔。
- 卡尔曼滤波: 适用于已知运动模型的高频数据,能同时估计真实价格和噪声方差,计算开销较大。
- 限幅滤波: 设定最大变化率(如每毫秒价格变化不超过 0.1%),超出则用前值替代。
- 时间桶均值: 将微秒级数据聚合到固定时间桶(如 10ms),桶内取 VWAP(成交量加权均价)。
避坑提示: 滤波会引入延迟。在微秒级场景下,中值滤波的窗口不宜超过 5 笔,否则坏账率告警的实时性会下降,可能错过真正的风险事件。
3.3 数据缺失与异常值处理
高频数据流中,缺失和异常是常态而非例外。缺失可能由网络丢包、交易所限流、数据源切换引起;异常值则可能来自撮合引擎的“试单”或“闪电崩盘”前的极端报价。
3.3.1 缺失处理策略
| 缺失场景 | 推荐策略 | 适用条件 |
|---|---|---|
| 单笔缺失(< 10ms) | 前值填充(Last-Value Carry Forward) | 流动性好的品种,价格变化小 |
| 连续缺失(10ms - 1s) | 线性插值或 VWAP 插值 | 有成交量辅助,避免价格跳跃 |
| 长时间缺失(> 1s) | 标记为“数据中断”,暂停坏账率计算 | 必须人工确认数据源状态 |
3.3.2 异常值检测与处理
异常值检测通常采用 统计阈值法 或 机器学习隔离森林法。在坏账率告警场景下,推荐使用轻量级的 Z-Score 动态阈值:
// 伪代码:Z-Score 异常值检测
double mean = rollingMean(prices, window=50);
double std = rollingStd(prices, window=50);
double zScore = abs(currentPrice - mean) / std;
if (zScore > 3.0) {
// 标记为异常值,不参与坏账率计算
markAsOutlier(currentTimestamp);
// 使用前值或插值替代
currentPrice = lastValidPrice;
}
关键指标: 在实盘环境中,建议将 Z-Score 阈值设为 3.0-3.5(对应 99.7% 置信区间)。对于微秒级数据,窗口大小建议为 100-200 笔,过小则误判率高,过大则响应慢。
3.4 数据质量监控与告警联动
高频行情的数据质量本身就应该纳入坏账率告警体系。建议在系统中设置 数据质量健康分,当健康分低于阈值时,自动降低坏账率告警的敏感度或暂停告警。
| 质量指标 | 计算方式 | 健康分权重 | 触发暂停告警的阈值 |
|---|---|---|---|
| 数据到达率 | 实际到达笔数 / 期望笔数 | 40% | < 95% |
| 时间戳乱序率 | 乱序笔数 / 总笔数 | 25% | > 1% |
| 异常值占比 | 标记异常笔数 / 总笔数 | 25% | > 2% |
| 重复数据率 | 重复笔数 / 总笔数 | 10% | > 0.5% |
最佳实践: 将数据质量健康分作为坏账率告警阈值的一个动态乘数因子。例如:
实际告警阈值 = 基础阈值 × (1 + (1 - 健康分))。当健康分从 1.0 降到 0.9 时,阈值自动上浮 10%,避免在数据质量差时频繁误告。