2. Tick数据结构解析:Level1/Level2行情Tick字段详解
高频交易与风控系统的基石是Tick数据。不同交易所、不同数据等级(Level1/Level2)的Tick结构存在显著差异。本章将逐字段拆解Tick数据包,明确每个字段在坏账率监控中的实际用途。
2.1 Level1 vs Level2 行情核心差异
| 对比维度 | Level1(基础行情) | Level2(深度行情) |
|---|---|---|
| 数据频率 | 通常3秒或1秒快照 | 逐笔成交 + 逐笔委托,毫秒级推送 |
| 盘口深度 | 仅最优买卖5档(买一~买五,卖一~卖五) | 全量委托队列(50档/100档/全档位) |
| 成交量信息 | 累计成交量 + 单笔成交量 | 逐笔成交明细(每笔成交价、量、方向) |
| 时间戳精度 | 秒级或百毫秒级 | 微秒级或纳秒级(交易所撮合时间) |
| 坏账监控价值 | 可发现分钟级异常 | 可发现秒级/毫秒级异常,精准定位坏账 |
实战建议:坏账率监控必须依赖Level2数据。Level1的快照频率不足以捕捉闪电崩盘、虚假流动性、对倒交易等高频坏账行为。
2.2 Tick核心字段详解
一个标准的Level2 Tick数据包通常包含以下字段组。每个字段在坏账率计算中都有明确的角色。
2.2.1 时间戳字段
- Exchange Timestamp(交易所时间戳):撮合引擎生成时间,精度微秒/纳秒。用于计算订单延迟、成交间隔、流动性突变时间点。
- Received Timestamp(接收时间戳):本地网关收到数据的时间。用于评估网络延迟、数据乱序、重复包。
- Sequence Number(序列号):交易所或网关分配的递增序号。用于检测丢包、乱序、重复推送。
坏账风险点:如果交易所时间戳与接收时间戳偏差超过阈值(如>100ms),可能表明数据经过缓存或重路由,该Tick的成交价/量不可信,应标记为“时间戳坏账”。
2.2.2 价格字段
- Last Price(最新成交价):最后一笔成交价格。用于计算实时价差、价格突变。
- Bid Price[1..N](买盘价格):各档位买入价格。Level2可提供全档位。
- Ask Price[1..N](卖盘价格):各档位卖出价格。
- Open / High / Low / Close(开盘/最高/最低/收盘):用于计算日内价格区间,辅助判断价格是否异常。
2.2.3 成交量与持仓量字段
- Volume(累计成交量):当日累计成交合约/股数。用于计算换手率、成交量突变。
- Turnover(成交额):当日累计成交金额。
- Open Interest(持仓量):期货/期权未平仓合约数。持仓量异常增减常伴随对倒或逼仓。
- Bid Volume[1..N] / Ask Volume[1..N](各档位委托量):Level2核心字段,用于计算订单簿不平衡、虚假挂单。
2.2.4 买卖盘口(Order Book)字段
- Bid/Ask Queue(委托队列):每个价格档位上的委托单明细(部分交易所提供)。用于识别大单撤单、冰山订单。
- Trade Direction(成交方向):主动买/主动卖标记。用于计算资金流向、识别对倒。
- Trade Flag(成交标记):是否为FOK(Fill or Kill)、FAK(Fill and Kill)等特殊订单。特殊订单占比过高可能暗示操纵。
2.3 Tick数据结构示意图
下图展示了一个标准Level2 Tick数据包在内存中的字段布局,以及各字段在坏账率监控中的角色映射。
2.4 Tick数据坏账率计算流程
基于上述字段,坏账率监控的典型处理流程如下:
- 数据接入:接收Level2 Tick流,解析各字段到结构化对象。
- 字段校验:检查时间戳单调性、价格非负、成交量非负、序列号连续性。
- 坏账判定:对每个Tick,根据预设规则(如价格超过前收盘±10%、成交量突增100倍、时间戳间隔>500ms)标记坏账。
- 坏账聚合:按时间窗口(1分钟/5分钟/1小时)统计坏账Tick数,计算坏账率。
- 告警输出:当坏账率超过阈值(如>0.1%)时,触发风控告警。
关键指标:坏账率 = (坏账Tick数量 / 总Tick数量) × 100%。Level2数据下,正常市场坏账率应低于0.01%;超过0.1%需立即排查数据源或市场异常。
2.5 常见坏账场景与对应字段
| 坏账场景 | 涉及字段 | 判定逻辑示例 |
|---|---|---|
| 时间戳回退 | Exchange Timestamp, Sequence Number | 当前时间戳 < 前一条时间戳,或序列号不连续 |
| 价格零值或负值 | Last Price, Bid/Ask Price | 价格 ≤ 0 |
| 成交量异常暴增 | Volume, Bid/Ask Volume | 单Tick成交量 > 前N个Tick均值 × 阈值 |
| 盘口倒挂 | Bid Price, Ask Price | 买一价 > 卖一价(正常市场不可能) |
| 虚假挂单后撤单 | Bid/Ask Queue, Sequence Number | 大单出现后快速撤单,且无成交 |
2.6 代码示例:Tick字段解析与坏账标记
以下Python代码演示如何解析一个简化的Level2 Tick字典,并执行基础坏账判定。
import time
from typing import Dict, List
class TickValidator:
"""Tick数据坏账校验器"""
def __init__(self, price_threshold: float = 0.1, vol_multiplier: float = 100.0):
self.last_timestamp = 0
self.last_seq = 0
self.price_threshold = price_threshold # 价格变动阈值(比例)
self.vol_multiplier = vol_multiplier # 成交量暴增倍数
self.volume_history: List[float] = []
def validate_tick(self, tick: Dict) -> Dict:
"""
校验单个Tick,返回坏账标记和类型
:param tick: 包含字段的字典
:return: {'is_bad': bool, 'bad_type': str, 'reason': str}
"""
result = {'is_bad': False, 'bad_type': '', 'reason': ''}
# 1. 时间戳校验
ts = tick.get('exchange_timestamp', 0)
seq = tick.get('seq_num', 0)
if ts < self.last_timestamp:
result['is_bad'] = True
result['bad_type'] = 'TIME_BAD'
result['reason'] = '时间戳回退'
return result
if seq <= self.last_seq:
result['is_bad'] = True
result['bad_type'] = 'TIME_BAD'
result['reason'] = '序列号不递增'
return result
self.last_timestamp = ts
self.last_seq = seq
# 2. 价格校验
price = tick.get('last_price', 0)
if price <= 0:
result['is_bad'] = True
result['bad_type'] = 'PRICE_BAD'
result['reason'] = '价格非正'
return result
# 3. 成交量校验
volume = tick.get('volume', 0)
if volume > 0 and len(self.volume_history) >= 10:
avg_vol = sum(self.volume_history[-10:]) / 10
if volume > avg_vol * self.vol_multiplier:
result['is_bad'] = True
result['bad_type'] = 'VOL_BAD'
result['reason'] = f'成交量暴增: {volume} vs 均值 {avg_vol:.2f}'
return result
self.volume_history.append(volume)
# 4. 盘口校验
bid = tick.get('bid_price_1', 0)
ask = tick.get('ask_price_1', 0)
if bid > 0 and ask > 0 and bid > ask:
result['is_bad'] = True
result['bad_type'] = 'ORDER_BOOK_BAD'
result['reason'] = '盘口倒挂'
return result
return result
# 使用示例
validator = TickValidator()
sample_tick = {
'exchange_timestamp': int(time.time() * 1_000_000),
'seq_num': 1001,
'last_price': 5000.0,
'volume': 10,
'bid_price_1': 4999.5,
'ask_price_1': 5000.5
}
result = validator.validate_tick(sample_tick)
print(f"坏账标记: {result['is_bad']}, 类型: {result['bad_type']}, 原因: {result['reason']}")
生产环境注意:实际Level2数据流每秒可达数千笔,校验逻辑必须使用C++或高性能Python(如Cython、Numba)实现,避免在Python层逐笔同步校验导致延迟堆积。
2.7 本章小结
- Level2 Tick数据包含时间戳、价格、成交量、盘口四大字段组,每个组都对应特定的坏账风险。
- 坏账率监控的核心是逐字段校验 + 聚合统计,Level2的细粒度数据让秒级异常无处遁形。
- 时间戳回退、价格异常、成交量暴增、盘口倒挂是最常见的四种坏账类型。
- 代码实现时需注意性能,高频场景下校验逻辑必须接近零开销。