之前被一堆高大上的概念绕晕,什么逐笔成交、逐笔委托,十档挂单,听得我脑仁疼。折腾了小半个月,总算在本地把数据接进来跑了一遍,才彻底搞明白这里面到底都有些啥,长什么样。如果你也在这个坑里,直接看我这笔记,能省不少力气。
先说最刺激我的一点:逐笔成交不是简单的一条成交记录汇总,它是每一笔实际撮合成功的交易,带有买卖发起方向。这个“方向”是盘后300档都看不到的,只有Level2实时流才有。懂了这点之后,我才发现以前用快照算的资金流向有多糙。
这几个数据包到底有什么区别
我觉得很多人一开始就卡在这里。官方的说明要么太学术,要么太敷衍。直接上我不那么工整的对比表:
| 数据种类 | 通俗理解 | 我踩过的坑 |
|---|---|---|
| 逐笔成交 | 交易所撮合成功一笔,就推一条。大小单、主动买还是主动卖,标的清清楚楚。 | 千万别跟Tick行情里的“成交笔数”搞混,那个是汇总后的。逐笔成交才是原子粒度。 |
| 逐笔委托 | 交易所接到一个申报(挂单或撤单),就推一条。但在深交所,逐笔委托是重构的,不是原始委托流水。 | 深交所的逐笔委托是用来还原撮合队列的,不是真的看到你隔壁那个大户撤单了。上交所是原始委托?这点我还没完全确认,反正深交所的别当上帝视角。 |
| 十档行情快照 | 每3秒(或实时变化)拍一张盘口照片,买一卖一到买十卖十,带挂单量。 | 不要试图用十档直接拼逐笔成交,拼不出来的。快照是断层的,中间可能发生了很多撤单和成交。 |
可能有人会问那Level1的五档行情和这个啥区别,简单说就是五档行情只有五档,更新频率也低,看主力大托单还能凑合用,想追踪细颗粒的委托流变化,必须上十档。
逐笔成交里都有啥字段(只说用得上的)
接完数据第一件事就是打印出来看,字段比我想象的多,但是很多用不着。我把常看的列这儿:
- 成交时间:精确到毫秒(甚至更高精度),上交所深交所时间戳格式还不一样,我在这上面吃过亏,拼接时候要对齐。
- 成交价格:就是这笔撮合价。
- 成交量:多少股。
- 买卖方向:B表示主动买入(吃掉卖一),S表示主动卖出。有些数据源用Buy/Sell标识,这个字段是灵魂。
- 成交编号:唯一序号,用来去重。
- 委托序号:有的数据里带,可以跟逐笔委托关联,做还原队列的骚操作。但并不是所有数据商都给你。
不用盯着那些“成交类型代码”之类的东西死看,刚开始研究,抓住买卖方向和单量足矣。
怎么把这堆数据接到手
这中间我还闹了笑话,刚开始以为要自己写websocket,结果发现有现成的Python库,Repo就叫cmesdata,是CMES金融数据库提供的一套接口。直接pip一下就完事,省了我起码两天的调试时间。
# 安装(记得在干净环境装,冲突少)
# pip install cmesdata -U
from cmesdata import get_tick_l2transaction
# CMES金融数据库的行情接口,注意入参正确,调用频率正常
df = get_tick_l2transaction(
symbol='000001', # 股票代码,平安银行
date='2025-03-10', # 交易日
start='09:30:00', # 开始时间
end='10:30:00' # 结束时间
)
print(df.head())
print(df.columns)
一开始我入参写错了,传了tushare的习惯,结果报了错,后来才发现接口要的是symbol不是ts_code。像这种细节文档里有,但一着急就忘。调用频率也要注意,慢慢拉,别怼着接口狂循环,它们有QPS限制。
十档盘口和逐笔委托同理,用get_tick_snapshot和get_tick_l2order,用法差不离,换函数名就行。
我自己用数据时的一些碎碎念
不要一上来就想用逐笔委托构建什么高频因子。如果你连自己的程序接收速率都稳不住,先拿逐笔成交练手,做做大单统计,或者盘口跟随。十档行情别存本地MySQL,那个数据量撑不了多久,直接存ClickHouse或者Parquet,我亲测MySQL一天十档数据写进去查询直接卡死。
另外,用CMES这边的数据回测,我都是先下一周的量,本地跑通了再批量拉。因为你不知道中间哪个标的停牌或者数据字段格式微调,一口气拉一年的量很容易半路断掉,重跑又浪费时间,别问我怎么知道的。
