量化路上的数据需求演变
作为一名跨境量化策略开发者,我的工作流通常分为回测和实盘两块。回测阶段数据需求很明确:需要什么区间、什么频率的 K 线,通过 REST 一次性拉取下来,干净利落。但策略一旦上线实盘,对行情的要求就从“完整”变成“及时”。任何毫秒级的延迟都会让信号失真,直接影响成交滑点和策略表现。
轮询 REST 遇到的实盘痛点
实盘初期我用定时器每隔 800 毫秒请求一次最新价,跑了两周发现两个致命问题:一是请求洪峰导致 CPU 占用过高,尤其在订阅多只股票时,并发请求让网络带宽捉襟见肘;二是“定时采样”的本质意味着我永远只能拿到离散的时间点价格,盘口发生的瞬时跳价可能被完全跳过。这种数据层面的失真,让许多原本优秀的日内动量策略实盘表现大打折扣。
从机制上理解两种接口的数据流
REST 是“请求-应答”同步模式,每次通信都需要完整的三次握手、请求、响应、断开。WebSocket 则是在一次 HTTP 升级后建立起全双工通道,此后服务端主动推送数据,客户端无需再发送请求。反映在行情场景中,一个是“人工间歇采样”,一个是“事件驱动连续流”。
功能拆解:回测用 REST,实盘靠 WebSocket
回测所需的历史行情——REST 的战场
策略回测对数据的要求是大批量、一次性加载。我用 REST 拉取历史分钟线作为特征计算的输入:
import requests
url = "//api.example.com/stock/history"
params = {
"symbol": "AAPL",
"interval": "1m",
"limit": 200
}
res = requests.get(url, params=params)
data = res.json()
print(data)
实盘实时 tick 流——WebSocket 的主场
进入实盘后,我会立即切换到 WebSocket 模式,订阅所有持仓标的的实时成交数据。AllTick API 提供的 WebSocket 通道可以同时订阅多只股票,推送结构统一,非常容易接入现有策略框架:
import websocket
import json
def on_message(ws, message):
data = json.loads(message)
ticks = data.get("ticks", [])
for tick in ticks:
print(tick["symbol"], tick["price"], tick["volume"])
def on_open(ws):
msg = {
"action": "subscribe",
"symbols": ["AAPL", "MSFT", "TSLA"]
}
ws.send(json.dumps(msg))
ws = websocket.WebSocketApp(
"wss://apis.alltick.co/websocket-api/stock/transaction-quote",
on_message=on_message
)
ws.on_open = on_open
ws.run_forever()
策略代码只需注册回调,接收到 tick 后立刻进行信号计算,真正做到了事件驱动。
差异速览表
| 维度 | REST | WebSocket |
|---|---|---|
| 数据方式 | 请求响应 | 持续推送 |
| 连接状态 | 短连接 | 长连接 |
| 延迟表现 | 相对较高 | 更低 |
| 适用内容 | 历史数据、查询 | 实时行情、tick |
| 系统角色 | 数据补充层 | 实时数据层 |
跨境量化系统的行业应用落地
在我的跨境量化架构中,REST 和 WebSocket 被明确分工:离线回测模块仅依赖 REST 历史数据;实盘交易引擎则完全挂载在 WebSocket 推送之上,同时额外使用 REST 做定时的账户、持仓查询。两者数据统一经过标准化的行情对象封装,使策略可以无感切换回测与实盘。
对于我们这类管理多市场、多标的的跨境量化团队,选择一套稳定、低延迟的实时行情源至关重要。我目前在用的 AllTick API WebSocket 服务,在开盘高峰期的推送稳定性与低延迟表现都经受住了考验,帮助我将策略滑点控制在理想范围内。


