如何获取股票实时数据?盘口重建中增量订单簿该如何落地?

用户头像sh_****447dvu
2026-08-19 发布

技术研究分享:本文主要探讨 Level‑2 深度行情的接入与本地增量订单簿的工程实现,用于量化策略研究、回测与盘口数据分析,不构成任何投资建议。

在量化策略研究过程中,经常会遇到回测结果与模拟推演出现显著偏差的情况。除去策略逻辑本身的因素,行情数据的颗粒度与本地盘口状态维护不当,是很容易被忽略的诱因。

仅依靠 Level‑1 基础行情,只能获取最新成交价、涨跌幅、累计成交量等聚合指标,无法观察盘口档位的委托增减、撤单改单等微观行为。对于需要盘口深度作为输入的短线模型、订单流分析类策略,这类信息缺失会直接影响模型有效性。因此需要接入 Level‑2 深度行情,并在本地维护状态可靠的增量订单簿,为回测与实盘模拟提供高质量的底层数据支撑。

Level‑2 深度行情的核心数据维度

基础行情接口开发成本低,适合一般性行情观测,但无法支撑细粒度的量化建模。Level‑2 深度行情提供盘口多维度原始信息,主要包含:

  1. 买卖盘各档位的委托报价
  2. 各价格档位对应的委托数量
  3. 盘口深度档位明细
  4. 行情事件时间戳

时间戳是维持本地订单簿正确性的关键字段,用于校验数据包的先后顺序,很多研究在开发阶段容易忽视该字段,最终造成盘口状态漂移。

在早期调试中我曾采用全量快照存储模式:每收到一次行情推送,完整保存全部盘口数据。单标的测试时没有明显异常,但订阅多只标的之后,内存占用、计算开销快速上升,系统延迟增加,不利于策略的低延迟运算。

增量更新模式可以有效缓解该问题:不重复存储完整盘口,仅针对发生变动的价格档位做更新。

举个实例:买盘某档位原有 500 手委托,新的行情推送该档位剩余 300 手,本地仅更新该价位的挂单数量;若某档位委托量归零,则直接移除该档位记录。该方案降低冗余计算开销,也便于后续开展订单流、盘口冲击等量化研究。

行情传输方案选择:WebSocket 替代 HTTP 轮询

股票深度行情属于高频持续更新数据流。HTTP 轮询模式需要客户端循环发起请求获取数据,高频场景下会产生大量无效请求,同时引入不可控的网络延迟,并不适合盘口的实时重建。

WebSocket 完成握手后,服务端可主动推送行情增量,无需客户端反复轮询请求。业务侧接收推送载荷,解析档位变动,持续迭代维护本地订单簿状态。以下为基础可运行示例代码,用于行情订阅与本地订单簿更新演示:

import websocket
import json

# 初始化本地订单簿,区分买卖盘
order_book = {
    "bids": {},
    "asks": {}
}

def on_message(ws, message):
    """接收服务端推送消息,更新本地订单簿"""
    data = json.loads(message)
    symbol = data.get("symbol")
    bids = data.get("bids", [])
    asks = data.get("asks", [])

    # 更新买方挂单档位
    for item in bids:
        price = item["price"]
        volume = item["volume"]
        order_book["bids"][price] = volume

    # 更新卖方挂单档位
    for item in asks:
        price = item["price"]
        volume = item["volume"]
        order_book["asks"][price] = volume

    print(symbol, order_book)

def on_open(ws):
    """连接成功后,发起深度行情订阅请求"""
    subscribe_req = {
        "id": 1,
        "cmd": "subscribe",
        "symbol": "AAPL",
        "type": "depth"
    }
    ws.send(json.dumps(subscribe_req))

if __name__ == "__main__":
    ws = websocket.WebSocketApp(
        "wss://api.alltick.co/stock/websocket",
        on_open=on_open,
        on_message=on_message
    )
    ws.run_forever()

说明:示例仅演示基础接收与更新逻辑。用于回测、模型仿真等正式研究场景时,需要对照接口文档,对字段解析逻辑做适配修改。

构建增量订单簿需要重点处理的工程问题

代码能够运行,不代表订单簿状态可以稳定对齐市场真实盘口,以下三点会直接影响回测、模拟研究的数据可信度:

  1. 基于时间戳做时序校验

    网络传输存在数据包乱序到达的可能性。如果不通过时间戳区分新旧数据,过期行情会覆盖最新盘口,造成本地订单簿错乱,基于该数据输出的模型信号、回测结论都会失真。

  2. 断线重连配合完整快照同步

    WebSocket 连接可能受网络环境影响断开。连接中断后内存中的订单簿不再具备参考价值。重连完成不能直接消费增量数据,需要先获取一份完整盘口快照对齐本地状态,再继续接收后续增量推送。

  3. 跨市场的行情规格适配

    不同市场的 Level‑2 行情在最小报价单位、字段命名、返回档位数量上存在差异,不能直接一套代码通用于全部标的,需要根据数据源的规格做针对性适配。

研究小结

获取股票实时数据只是量化研究工作的起始环节。不少策略研究者将重心放在寻找数据源,却忽略数据处理、状态维护这类底层工程环节,而这部分恰恰决定了回测与仿真的数据质量。

Level‑2 深度行情的价值,不在于多输出几组价格,而是为模型提供订单动态变化的微观信息。通过增量方式维护本地订单簿,可以为盘口特征挖掘、订单流建模、策略回测、模拟仿真提供可靠的数据基础。行情接口接入只是工具层面的实现,严谨的数据处理流程,才可以保障后续模型研究的可靠性。在开展相关研究时,也可以借助 AllTick API 获取 Level‑2 深度行情,将更多精力投入策略模型与回测分析工作。

评论