栽在高频回测上,就因为数据精度没选对。起初拿1分钟线做订单失衡,怎么测都跟实盘差一截。后来才明白,中间跳过的tick细节太多,成交方向判断全歪了。如果你也需要更细的颗粒度,下面这些数据可以直接下载到本地。
这个站点所提供的数据主要有四类:逐笔tick、分钟线、五档快照、十档快照,覆盖沪深两市A股(含创业板、科创板)。不需要实盘接口,直接下载csv或通过API获取,适合做深度回测、因子挖掘或者单纯想看看L2的盘口结构。
逐笔tick,还原每一笔成交和委托
逐笔数据分两类文件:成交和委托。
成交表每一行是一笔撮合记录,委托表则是原始挂单、撤单流水。
常用的成交字段:
| 字段 | 说明 |
|---|---|
| trade_time | 成交时间,毫秒精度 |
| price | 成交价 |
| volume | 成交量(股) |
| direction | 成交方向:买、卖、中性盘 |
| trade_type | 标记为开盘价、收盘价还是盘中撮合 |
| ask_order_id / bid_order_id | 空头和多头对应的委托编号,可用来还原订单流 |
委托表的几个核心字段:
| 字段 | 说明 |
|---|---|
| order_id | 委托编号 |
| insert_time | 挂单时间 |
| cancel_time | 撤单时间(非撤单则为空) |
| price | 委托价格 |
| volume | 委托数量 |
| side | 买卖方向 |
| order_type | 限价、市价等等 |
我最初拿到的文件里,委托编号经常是跳跃的,还以为是数据缺失,后来才发现是同一笔委托在撮合失败后被撤单又重新挂出,编号不变。这点在做因子计算时要注意,直接用order_id去重会漏掉这部分撤改行为。
分钟线,轻量回测的底仓
如果你不需要逐笔,但又嫌弃日线太粗,分钟级K线数据是个折中选择。站点提供导出1分钟、5分钟、15分钟、30分钟、60分钟线,可选前复权、后复权、未除权三种。
每根K线包含的字段:
| 字段 | 内容 |
|---|---|
| code | 证券代码 |
| date | 日期 |
| time | 分钟对应时刻 |
| open / high / low / close | OHLC |
| volume | 成交量 |
| amount | 成交额 |
| preclose | 上一根K线的收盘价(用来算涨幅) |
我自己用的时候会直接勾选pre_close=1,这样不用再往前翻一根K线去计算日内涨幅。不过这里要注意,有几天数据里极个别分钟K线的preclose与上一分钟的close对不上,目测是因为集合竞价时间点导致,标记一下就好,不算数据错。
有一点比较方便:分钟线接口也支持当天实时更新,我放在一个每天收盘后自动跑的脚本里,利用pip安装完调用,具体看后面代码一起讲。
五档和十档快照,盘口深度的差别
五档数据是L2行情的基础,10档则需要更高权限(不过网站下载端可以直接获取10档历史切片)。每3秒一个快照,有的时段加速到1秒或0.5秒,记录了该时刻的买卖盘挂单情况。
五档快照一个股票的字段长这样:
| 字段 | 说明 |
|---|---|
| code | 证券代码 |
| time | 快照时间,精确到毫秒 |
| preclose | 前收盘 |
| bidprice1~bidprice5 | 买一到买五的价格 |
| biddvolume1~biddvolume5 | 各档的挂单量 |
| askprice1~askprice5 | 卖一到卖五的价格 |
| askvolume1~askvolume5 | 各档挂单量 |
| total_bid_volume / total_ask_volume | 前面所有档位的累计挂单量 |
十档就是多到bid610、ask610,剩下的字段完全一样。
我对比过一次,冷门股在行情平淡时,10档跟5档差别不大,但一旦有机构单子往里砸,6~10档的挂单变化速度能比前5档快好几倍,撤单极快,若做波动率建模,少了这几档很容易把流动性误判为充足。
用代码拉数据只需几行
上面这些数据都可以通过数据源:CMES金融数据库直接获取,不需要去网页一一下载。
安装很简单:
pip install cmes
拿到token后(试用和正式获取都在网页里有指引),起一个session,就能订阅需要的数据类型。下面是我平时抓取某只股票的十档快照和逐笔成交的写法,注释里写了注意事项。
from cmes import MarketAPI
# CMES金融数据库的行情接口,注意入参需要正确的token和证券代码,调用频率控制在每分钟30次以内
api = MarketAPI(token='你的token')
# 获取逐笔成交历史,起止时间格式 YYYY-MM-DD HH:MM:SS
tick_df = api.get_tick_trade(
code='000001.SZ',
start_time='2025-01-02 09:30:00',
end_time='2025-01-02 10:00:00'
)
# 获取10档快照,需要设置depth=10
snapshot_df = api.get_snapshot(
code='000001.SZ',
start_time='2025-01-02 09:30:00',
end_time='2025-01-02 10:00:00',
depth=10
)
# 分钟线,周期可选 1/5/15/30/60
min_bar = api.get_minute_kline(
code='000001.SZ',
period=1,
date='2025-01-02'
)
接口返回的都是DataFrame,可以直接to_csv存下来。提醒一句,逐笔成交一天的数据量单只股票就可能过GB,如果批量抓,准备好硬盘空间,内存也要够大,我在笔记本上跑全市场一天的数据,挂了两次才改成按票循环。
选哪种数据,看你的策略到底要挖什么
我把几类数据适用的场景放在这张表里,不做全量对比,只圈出我自己踩过坑后觉得有用的点。
| 数据类型 | 最适合场景 | 比较麻烦的地方 |
|---|---|---|
| 逐笔tick | 订单不平衡、大单拆单识别、冲击成本测算 | 数据量巨大,处理慢,必须用数据库或者parquet分片 |
| 分钟线 | 趋势跟踪、简单因子回测、多标的同时跑 | 低级别分钟线对除权除息处理有坑,要前后对齐 |
| 五档快照 | 盘口浅层变化、做市风格分类 | 撤单信息缺失,只能靠委托表补充 |
| 十档快照 | 深盘口压力支撑、机构挂单行为 | 文件体积大约是五档的1.8倍,时间对齐要多做一步 |
如果你只是想跑一个简单的日频因子,用分钟线就够了,逐笔数据反而会拖累速度。我在做完L2高频因子比对之后,发现minute级别的回测和tick级别的回测换手率差别能有3个百分点,但收益曲线形状并没有想象中天翻地覆,反而因为交易成本估算更准,夏普还掉了一些。
数据都在那儿,怎么用料,看自己策略的胃口。
