第1章:冲击成本与订单簿重建
大家好,我是老张。今天咱们聊聊冲击成本和订单簿重建这个话题。
说实话,我刚入行那会儿,对冲击成本的理解特别肤浅。就觉得——我下单量大,价格就会往不利方向跑,这就是冲击成本呗。但后来在实盘中被市场狠狠教育了几次,才明白事情远没那么简单。
1.1 冲击成本到底是什么?
冲击成本,说白了就是你的订单对市场价格造成的影响。你买,价格涨;你卖,价格跌。这个价差,就是冲击成本。
但这里有个关键点:冲击成本不是固定的。它取决于很多因素:
- 你的订单大小(相对于市场深度)
- 市场的流动性状况
- 订单簿的微观结构
- 你下单的速度和方式
我记得有一次做回测,策略在模拟环境里年化收益30%,实盘一跑直接变成负的。查了半天,问题就出在冲击成本上。模拟环境里我假设每笔交易冲击成本是1个tick,但实际市场里,大单进去直接打穿好几层深度,冲击成本翻了5倍。
核心观点:冲击成本不是线性增长的。当你的订单量超过订单簿第一档深度时,冲击成本会呈指数级上升。
1.2 订单簿重建:为什么需要重建?
订单簿重建,就是把逐笔委托数据还原成完整的订单簿状态。你可能会问:交易所不是实时推送订单簿吗?为什么还要重建?
嗯,这里有个坑。交易所推送的快照数据,更新频率有限。比如深交所的Level-2行情,快照是每3秒推送一次。但在这3秒内,可能发生了成百上千笔委托和成交。如果你只看快照,中间的价格波动和深度变化就全丢了。
我做过一个统计:在快照间隔的3秒内,订单簿的变化量平均在200-500笔。这意味着什么?意味着你看到的订单簿,其实是3秒前的「历史遗迹」。
注意:使用快照数据做高频策略,相当于闭着眼睛开车。你必须重建订单簿,才能看到真实的市场状态。
1.3 事件驱动重建:核心逻辑
订单簿重建有两种方式:
- 全量重建:每次收到快照,重新构建整个订单簿
- 事件驱动重建:基于逐笔委托事件,增量更新订单簿
我个人更推荐事件驱动重建。为什么?因为效率高。全量重建每次都要处理几千条记录,而事件驱动只需要处理增量变化。
事件驱动重建的核心逻辑是这样的:
# 伪代码示例
class OrderBook:
def __init__(self):
self.bids = {} # 买单,key=价格,value=数量
self.asks = {} # 卖单,key=价格,value=数量
def on_order(self, order_event):
# 处理委托事件
if order_event.side == 'buy':
self.bids[order_event.price] = order_event.quantity
else:
self.asks[order_event.price] = order_event.quantity
def on_trade(self, trade_event):
# 处理成交事件
# 成交意味着订单被部分或全部吃掉
if trade_event.side == 'buy':
self.asks[trade_event.price] -= trade_event.quantity
else:
self.bids[trade_event.price] -= trade_event.quantity
# 清理空档
self._clean_empty_levels()
def on_cancel(self, cancel_event):
# 处理撤单事件
if cancel_event.side == 'buy':
del self.bids[cancel_event.price]
else:
del self.asks[cancel_event.price]
你看,逻辑其实不复杂。但实际实现时,有几个坑要注意:
- 时间戳对齐:不同事件的时间戳精度可能不同,需要统一处理
- 事件顺序:同一时刻发生的事件,处理顺序会影响结果
- 数据缺失:逐笔数据偶尔会丢包,需要做校验和补偿
小技巧:我习惯在重建时维护一个「校验和」。每处理1000笔事件,就和快照数据做一次对比。如果偏差超过阈值,就触发全量重建。这样既保证了效率,又防止了误差累积。
1.4 逐笔委托数据的应用
重建订单簿只是第一步。真正有价值的是,基于重建后的数据做分析。我常用的几个应用场景:
| 应用场景 | 说明 | 我的经验 |
|---|---|---|
| 冲击成本估算 | 基于实时深度,估算不同订单量的冲击成本 | 比固定比例法准确3-5倍 |
| 流动性预测 | 分析订单簿变化趋势,预测未来流动性 | 对高频策略特别有用 |
| 订单流分析 | 识别大单、算法单、散户单的行为模式 | 能提前发现机构动向 |
| 市场微观结构研究 | 分析价差、深度、订单到达率等指标 | 做市商策略的核心输入 |
举个例子。我曾经用逐笔数据做过一个「大单预警」模型。逻辑很简单:当订单簿的某一侧突然出现大量限价单,且这些单子很快被吃掉,说明有大资金在进场。这时候,冲击成本会急剧上升。我的策略就会暂停交易,等市场稳定后再出手。
1.5 知识体系总览
下面这张图,是我对本章知识体系的总结。你看一眼,就能明白各个概念之间的关系:
这张图把整个知识体系串起来了。你看,冲击成本分析是核心目标,订单簿重建和逐笔委托数据是两大支撑。重建提供了「状态」,逐笔数据提供了「过程」。两者结合,才能准确估算冲击成本。
1.6 避坑指南
最后,分享几个我踩过的坑:
- 别信快照数据:快照只是「参考」,逐笔数据才是「真相」
- 注意数据延迟:逐笔数据也有延迟,尤其是跨市场套利时
- 别忽略撤单:很多策略只关注委托和成交,但撤单同样重要——它反映了市场情绪的变化
- 做好异常处理:数据偶尔会乱序、重复、缺失,代码要能容错
一句话总结:冲击成本不是算出来的,是「重建」出来的。没有准确的订单簿重建,一切冲击成本分析都是空中楼阁。
好了,这一章就到这里。下一章我们会深入讨论如何用逐笔数据做更精细的冲击成本建模。到时候我会分享一个我实际用过的模型,以及它的代码实现。