我接触美股tick数据已经有一段时间了,起初只是单纯想拿数据做一些小实验,慢慢地开始尝试把这些零散的成交、委托信息,重构成一个完整的订单簿,用于高频回测。你会发现,和你想象的那种直接拉数据就能用的情况差得很远——tick数据本身是离散的,需要一点耐心去拼接成连续的订单簿快照。
美股tick数据,顾名思义,是每一笔成交或者报价的记录。一个标准的tick通常包含时间戳、价格、成交量、买卖方向等字段。这里面最关键的就是“动作”和“价格深度”,因为订单簿的核心是买卖双方的挂单队列。
举个例子,你可能会拿到类似这样的数据:
| 时间戳 | 类型 | 价格 | 数量 |
|---|---|---|---|
| 10:00:00.123 | Bid | 100.5 | 200 |
| 10:00:00.125 | Ask | 101.0 | 150 |
| 10:00:00.130 | Trade | 100.5 | 50 |
如果你只是简单把这些tick堆叠起来,你会得到一个列表,但这并不是我们能直接回测的订单簿快照。我们需要把这些tick变成一个“层级化的买卖队列”,实时反映市场深度。
重建订单簿,我通常从两个方面入手:
买卖队列的维护
用两个有序字典分别存储买盘和卖盘,key是价格,value是挂单量。每条tick进来,就判断它是新增挂单、撤单还是成交,然后更新对应队列。
快照输出
高频回测需要的是连续快照而不是单条tick。可以设置时间间隔(比如1ms或10ms),把当前买卖队列的状态存下来。这样后续的回测就能直接用快照模拟撮合。
用Python简单表示就是:
from collections import OrderedDict buy_book = OrderedDict() sell_book = OrderedDict() def update_order_book(tick): if tick['type'] == 'Bid': buy_book[tick['price']] = tick['size'] elif tick['type'] == 'Ask': sell_book[tick['price']] = tick['size'] elif tick['type'] == 'Trade': # 按成交价格减少对应挂单 if tick['price'] in buy_book: buy_book[tick['price']] -= tick['size'] if buy_book[tick['price']] <= 0: del buy_book[tick['price']] elif tick['price'] in sell_book: sell_book[tick['price']] -= tick['size'] if sell_book[tick['price']] <= 0: del sell_book[tick['price']]
这个逻辑很简化,但足够展示核心思想:订单簿的本质就是对买卖挂单的动态维护,而tick只是触发变化的事件流。
在实际操作中,你会发现tick数据有漏掉、乱序或者延迟问题。尤其是高频回测,1毫秒的差距都可能影响策略结果。我个人会做两件事:
排序和补充:按时间戳对tick排序,缺失的价格层可以用上一条快照填充。
并发处理:如果是实时回测,建议用队列异步处理tick,避免阻塞导致快照丢失。
我在项目中用过 AllTick API 来拿美股tick数据。以Python为例,订阅某只股票的成交和报价信息非常方便:
import websocket
import json
def on_message(ws, message):
tick = json.loads(message)
update_order_book(tick)
# 可以定期输出快照或直接用于回测
ws = websocket.WebSocketApp("wss://api.alltick.co/stock",
on_message=on_message)
ws.run_forever()
这里的tick直接进入我们维护的买卖队列,实时生成订单簿快照,非常适合高频回测使用。
实际回测时,不一定要记录全深度。常见做法是只保留前5~10档价格,因为大部分策略都集中在最优买卖档位。这样不仅减少内存占用,也能更快地模拟撮合逻辑。
在策略模拟阶段,可以按照快照顺序逐步推进时间,模拟每条tick的成交情况。记住,tick数据的时间间隔并不均匀,所以快照和事件推进一定要同步。
我在处理美股tick数据时发现,订单簿重建比想象中更依赖数据结构和逻辑设计。简单的列表堆叠是没法直接用的,高频回测需要的是连续、可复现的快照。用好字典、堆或者有序队列,再结合合理的快照策略,效果就会非常接近真实市场。
其实,这里面最关键的不是用多复杂的算法,而是对tick事件流的理解和对订单簿动态的把控。一旦习惯了这个思路,很多策略回测都可以直接套用,甚至可以快速扩展到多股同时处理。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70038549/viewspace-3173157/ ,如需转载,请注明出处,否则将追究法律责任。