为了账号安全,请及时绑定邮箱和手机立即绑定

实时“复印”交易所深度:一步步用 Python 重建订单簿状态

标签:
API

我们在做量化策略教学和回测演示时,经常遇到一个问题:历史数据里只有成交记录,没有挂单深度,很多微观策略根本无法复现。为了弥补这一缺失,我所在的团队决定动手在本地完整同步一份交易所订单簿——就像给市场拍一部不间断的电影。这篇文章会一步一步带你完成这个过程,代码都能跑通,读完你也能立刻上手。

项目起点:为什么要本地保存订单簿?

不管是想实时计算买卖压力,还是回测时需要精确的冲击成本,单纯的成交数据远远不够。我们需要知道每个价位上挂着多少筹码。如果直接从交易所 REST 接口全量拉取,更新频率太低;改用 WebSocket 实时推送,就能让本地簿始终紧贴交易所的真实状态。

拆解两个关键概念:快照和增量

行情数据一般分成两种形态:

  • 快照:某一瞬间的完整订单簿,通常包含前几十档的买卖价格和数量。
  • 增量更新:快照之后每一笔导致订单簿变化的动作,比如新订单、取消或部分成交。

本地重建的思路很朴素:先用快照填充本地的买卖结构,然后随着增量消息一条一条地修改结构。就像你拿着一份完整的初始库存清单,每发生一次出库入库就记一笔,余额永远最新。

用什么数据结构管理深度?

Python 自带的 dict 虽然可以存放价格和数量,但无法在插入时保持有序。我们需要能按价格自动排序的容器。sortedcontainers 库里的 SortedDict 正好满足需求:

from sortedcontainers import SortedDict

# 买单按价格从高到低排序
bids = SortedDict(lambda x: -x)
# 卖单按价格从低到高排序
asks = SortedDict()

这样随时可以取出最优买价和卖价,画图或计算深度也非常方便。

用 WebSocket 接收实时更新

实际的代码连接很简单。我们定义一个消息处理函数,每当 WebSocket 推送数据时,就用它更新全局的 bidsasks

import websocket
import json
from sortedcontainers import SortedDict

bids = SortedDict(lambda x: -x)
asks = SortedDict()

def on_message(ws, message):
    data = json.loads(message)
    # 处理买单和卖单的增量更新
    process_orderbook(data)

def process_orderbook(data):
    global bids, asks
    for update in data.get("bids", []):
        price, size = update
        if size == 0:
            bids.pop(price, None)
        else:
            bids[price] = size
    for update in data.get("asks", []):
        price, size = update
        if size == 0:
            asks.pop(price, None)
        else:
            asks[price] = size

ws = websocket.WebSocketApp("wss://api.alltick.co/crypto/orderbook",
                            on_message=on_message)
ws.run_forever()

在真实开发中,我们使用 ALLTICK API 等成熟的数据 API 来获取稳定的快照与增量,数据格式规范,推送及时,减少了大量底层对接成本。

处理网络中断:让系统更健壮

WebSocket 总有断线的可能。我们通常会设计一套自我保护机制:

  • 保留最近一次成功处理的序列号,发现跳跃就重新获取快照。
  • 设置心跳包,配合自动重连逻辑。
  • 启动时优先请求当前完整快照,再用增量追赶。

这套策略能有效避免本地簿出现“空洞”。

数据可视化:从数字到洞察

订单簿维护好后,你能直接画出一张深度图,直观感受多空实力:

import matplotlib.pyplot as plt

def plot_orderbook():
    plt.plot(list(bids.keys()), list(bids.values()), color='green', label='Bids')
    plt.plot(list(asks.keys()), list(asks.values()), color='red', label='Asks')
    plt.legend()
    plt.show()

绿色买单、红色卖单的分布一目了然。这项能力可以嵌入你的策略研究流程,例如实时监控挂单厚薄、提前预判支撑阻力。

从练习到实战

这套方案代码量不大,但思想非常通用。掌握后,你可以很方便地把它扩展到多个交易对,加入异步处理,甚至把订单簿状态存入数据库做历史回放。对我们而言,这个项目不只是技术练习,更是理解市场微观结构的窗口。
图片描述

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号

举报

0/150
提交
取消