1. 课程导入与数据基础
在逐笔成交与逐笔委托构成的微观结构数据体系中,撤单往往被当作“没有发生的交易”而被忽略。但在真实的撮合市场里,撤单是订单生命周期中信息含量极高的一环:它既可能是做市商在报价被吃掉前的主动收缩,也可能是大单在价格即将穿越时的紧急避险,还可能是算法在队列位置不利时的策略性退出。研究逐笔撤单,本质上是在研究“谁在什么价位、什么时刻、以多大规模放弃了原本愿意成交的意愿”,而这种意愿的撤回,往往先于价格的移动发生。
本课程的核心问题可以归纳为一条主线:撤单行为是否携带对未来成交与价格响应的可预测信息,以及这种信息如何被量化、关联与验证。围绕这条主线,我们需要回答三个层次的问题。第一层是描述层:某只标的在特定时段内的撤单在价格、数量、方向上呈现什么分布,撤单率与成交率如何随时间变化。第二层是关联层:同一订单号从委托到撤单的存活时间、撤单前的盘口状态、撤单与随后成交的方向是否一致,这些关联特征能否区分不同类型的撤单动机。第三层是响应层:撤单事件发生后,未来若干秒或若干笔内的成交强度、买卖压力与价格漂移如何变化,从而判断撤单是“噪声”还是“信号”。
数据字段解析:从原始记录到订单生命周期
逐笔数据通常以“逐笔委托”和“逐笔成交”两张表呈现,撤单信息一般出现在逐笔成交表中以特定成交类型标识,或在独立的撤单表中给出。无论哪种形式,研究撤单都必须先明确字段语义。以下字段是构建订单生命周期的关键:
| 字段 | 含义 | 在撤单研究中的作用 |
|---|---|---|
| 订单号 | 交易所为每笔委托分配的唯一标识 | 主键,用于把委托、撤单、成交记录关联为同一订单 |
| 撤单时间 | 撤单被撮合系统接受的时刻,精确到毫秒或微秒 | 计算订单存活时间、构造事件时间轴 |
| 价格 | 委托价或撤单对应的原委托价 | 判断撤单位于买盘还是卖盘、距盘口多远 |
| 数量 | 撤单数量(可能为部分撤单) | 区分全撤与部撤,衡量撤单规模 |
| 方向 | 买或卖 | 判断撤单对买卖压力的影响方向 |
| 委托时间 | 原始委托进入系统的时刻 | 与撤单时间相减得到存活时长 |
需要特别强调两个容易出错的细节。其一是部分撤单:一笔委托可能先成交一部分,剩余部分再被撤回,此时撤单数量小于原始委托数量,若直接用撤单数量当作委托规模会低估订单意图。其二是时间参照系:本文所有时间差均以“撤单时间减委托时间”为正方向,单位为毫秒,若数据源使用交易所本地时钟,需先确认两张表时间戳口径一致,否则存活时间会出现负值或系统性偏移。
下面给出一段示例性的字段对齐与生命周期重建代码,用于说明实际操作方式。示例参数与输出均为教学假设,不代表真实市场数据。
import pandas as pd
# 假设已读入逐笔委托与逐笔成交(含撤单标识)
orders = pd.read_csv("order.csv") # order_id, order_time, price, qty, side
trades = pd.read_csv("trade.csv") # order_id, trade_time, trade_type, qty
# 1) 分离撤单记录:trade_type == 'C' 表示撤单
cancels = trades[trades["trade_type"] == "C"].copy()
cancels = cancels.rename(columns={"trade_time": "cancel_time"})
# 2) 以订单号关联委托信息
life = cancels.merge(orders, on="order_id", how="left")
# 3) 计算存活时间(毫秒),并标记全撤/部撤
life["alive_ms"] = (life["cancel_time"] - life["order_time"]).dt.total_seconds() * 1000
life["cancel_ratio"] = life["qty_x"] / life["qty_y"] # 撤单量 / 原始委托量
life["is_full"] = life["cancel_ratio"] >= 0.999
print(life[["order_id", "alive_ms", "cancel_ratio", "is_full"]].head())
这段代码的关键不在语法,而在于它体现了研究的基本纪律:任何撤单特征都必须回到订单号这一主键上,任何统计都必须先确认撤单是全部撤回还是部分撤回。完成这一步后,我们才拥有了一张“订单级撤单事件表”,后续的价格距离、盘口状态、成交响应都可以在这张表上继续扩展。
上图把本节的知识结构压缩为一条可执行的链路:左侧三类原始记录通过订单号汇聚到“订单生命周期重建”,再向右扩展为撤单特征与成交响应变量,最终进入关联分析与验证。图中底部的三层问题对应研究目标,而时间参照约定则提醒我们,所有涉及时间差的特征都必须先统一口径。
研究目标的具体化与首轮观察
把目标落到可操作的层面,本节建议先完成三项基础工作。第一,统计撤单率的时间序列,即每分钟撤单笔数占委托笔数的比例,观察是否存在开盘、收盘或特定事件前后的聚集。第二,按存活时间分桶,例如 0–50ms、50–500ms、0.5–5s、5s 以上,比较不同桶内的撤单比例与方向分布,初步判断哪些撤单更像“瞬时反悔”,哪些更像“长时间挂单后的策略调整”。第三,对每笔撤单计算其价格相对当时最优买价或最优卖价的距离,距离越近的撤单对盘口压力的边际影响越大。