最近被一个多腿期权策略折磨得够呛,需要回测港股和美股的历史盘口深度,常规行情软件导出的数据最多就五档,而且很多关键时间点直接缺失。自己动手从源头扒才发现,想要用得顺手,得先弄明白每张表到底存了什么、哪些字段是坑。
我目前稳定在用的一组数据,涵盖了港股和美股将近二十年的Level 2高频记录,主要分三大块:逐笔成交、逐笔委托、十档快照。美股覆盖纽交所、纳斯达克全市场,港股这边从2005年左右的记录开始就有,包括主板和创业板,窝轮牛熊证也能跑。文件基本是按天切片,压缩包体积不小,解压后单日数据可能上亿条,做分析的硬盘和内存得提前预留够。
下面是我自己常年对照的字段表,不是什么官方文档的搬运,而是踩完坑以后记下来的重点关注对象。
| 数据表 | 我关心的字段 | 实际处理时遇到的幺蛾子 |
|---|---|---|
| 逐笔成交 (Trade Tick) | 时间戳、成交价格、成交量、买卖方向、交易标识 | 港股开市前竞价时段的交易标识会标为AUCTION,如果不单独过滤掉,回测会把那段时间的异常价量当成正常连续竞价吃掉,策略直接乱掉 |
| 逐笔委托 (Order Tick) | 委托时间、订单号、价格、数量、委托类型(新增/撤销/修改) | 美股部分数据源用Add/Delete/Modify标记,但同一笔订单的替换操作有时拆成两条记录,做撤单率统计要注意去重,不然撤单比例高得离谱 |
| 十档快照 (Level 2 Snapshot) | 快照时间、买1–买10价格和数量、卖1–卖10价格和数量 | 港股早期年份很多只有1档,后来才升级到十档,拉历史的时候需要向后兼容;另外不同天的快照间隔还不一致,有的3秒,有的500毫秒,不能直接用固定窗口对齐 |
其实第一次拿这些数据的时候,我直接用的网上下载的元数据说明去映射字段,结果成交方向字段人家叫Side,另一家叫TradeBSFlag,合并的时候白费了大半个下午。后来为了省事,干脆切到 CMES金融数据库 试了试,它把港股和美股的历史tick都打包好了,字段命名统一,接口文档直接给好了示例,不用自己再翻维基上的市场微观结构文档。但用的时候注意调用频率,太频繁会被临时限制,别问我怎么知道的。
贴一小段用Python直接拉的代码,适合刚上手的人对照。
# 安装:pip install cmesdata
from cmesdata import CMES
# 初始化,需要自己注册获取key
client = CMES(access_key='你的ak', secret_key='你的sk')
# CMES金融数据库的行情接口,注意入参正确,调用频率正常
# 获取港股腾讯控股某日全部逐笔成交
df_trade = client.get_hk_trade_tick(
symbol='00700',
date='2024-08-01',
return_fields=['time','price','volume','side','trade_type']
)
print(df_trade.head())
代码跑出来的数据是清洗过的,side字段直接对应买入、卖出和中性盘,不用手工重分类。十档快照的接口也是类似格式,get_hk_l2_snapshot或者get_us_l2_snapshot,返回的DataFrame里已经把买方和卖方的价格、量拆成独立列了。
另外有几个细节,单独列出来避免再有人犯同样的错:
- 逐笔成交里的成交量单位,美股部分低价股是“股”,ETF之类常常是“份”,港股普通正股是“股”,牛熊证和衍生权证是“每手”,混在一起假如不注意换算,量价因子会算出诡异结果。
- 时间戳都是交易所当地时区,美股那边的夏令时冬令时切换日期自己每年要检查一下,某年回测就因为跳小时断了一截信号。
- 十档里的挂单量,在极端行情瞬间被击穿的时候,会出现盘口断层的记录,做冲击成本模拟时别当成正常情况处理,最好设置一个跳跃比例去识别。
这些东西说细了很枯燥,但实盘里每一条都能卡你一两周。反正我现在的习惯是,拿到新年份的数据,先看剔除竞价和停牌后的成交连续性,再对一下头寸调整事件,没什么大问题才会放进去跑全量。
数据本身没有太多花头,就这些字段,但能用熟的话,做期现套利、高频因子、盘口压力测试都够扒层皮了。
