本文手把手拆解如何用 Python WebSocket API 稳定获取 OKEx 实时交易数据,包含代码结构、心跳机制、异常处理与实盘可落地的调优细节。阅读完毕你将立刻拥有一套可“开箱即用”的自建量化数据通道。
为什么我选择重写 WebSocket 客户端
OKEx 官方文档迭代频繁,早期社区里的 SDK 很多已失效;不开源的项目又难免黑盒。为了彻底掌控数据质量与延迟,决定用 150 行纯 Python 自建一套精简、可维护的 自动交易 数据采集脚本。
👉 想一键下载维护活跃的开源示例?点这里即可跳过阅读直接拉取最新代码。
核心关键词
OKEx WebSocket、Python 自动交易、实时交易数据、心跳包、量化策略、数据结构解析。
接入逻辑拆解
1. 连接与订阅:一句 send
搞定多渠道
使用 websocket-client
库,三行代码即可连上 wss://real.okex.com:10441/ws/v1
。
ws = websocket.WebSocketApp(
host,
on_open=on_open,
on_message=on_message
)
在 on_open()
里集中发送订阅指令,可同时监听现货、永续合约、期权等不同频道:
def on_open(ws):
ws.send(ws_subscribe('ok_sub_futureusd_btc_quarter'))
ws.send(ws_subscribe('ok_sub_spot_etc_usdt_ticker'))
提示
所有频道名称和所需参数都在官方文档“行情频道总览”页,务必用最新版本,避免返回{"error": "60012"}
导致订阅失败。
2. 消息三类与解析要点
服务器推送的全部 JSON 可归纳为三类:
消息类型 | 触发场景 | 简明特征 |
---|---|---|
Heartbeat pong | 回应客户端 ping |
{"event":"pong"} |
订阅确认 | 成功注册频道 | channel 与请求一致 |
行情/成交数据 | 每有新数据 | data 字段内含数组 |
解码时 OKEx 启用了 per-message-deflate
压缩,需要 zlib.decompress()
:
def inflate(data):
return zlib.decompress(data, -zlib.MAX_WBITS)
msg = inflate(message).decode()
3. 被动防止掉线:心跳线程保活
实测最稳策略是 每 30 秒主动 ping
一次。
def heartbeat(ws):
while True:
try:
ws.send('{"event":"ping"}')
time.sleep(30)
except Exception as e:
logging.error(e)
time.sleep(5) # 异常后尝试重连
threading.Thread(target=heartbeat, args=(ws,)).start()
FAQ:心跳间隔能否 60 秒?
60 秒极容易被服务端判定为静默关闭,一般不超过 35 秒。
4. 异常与重连:实战踩坑合集
on_error()
里捕获ConnectionRefusedError
,独立记录日志便于回溯。- 回调里一旦检测到
{"event":"login"}
返回非 0,可直接ws.close()
并触发重连。 - 策略小贴士:先解耦心跳线程与主线程,可避免
websocket._exceptions.WebSocketConnectionClosedException
导致的死锁。
完整代码仓库结构
okex-websocket/
├─ okex_ws.py # 核心脚本
├─ requirements.txt
└─ README.md
常见疑难解答(FAQ)
Q1:返回 { "error" : 30040 }
是什么原因?
A:频道订阅签名错误。检查 api_key, secret_key, passphrase
是否对应 Classic 账户 而非统一账户。
Q2:能一次拿到全币种深度吗?
A:WebSocket 按频道隔离,需要逐笔订阅;可自定义队列在本地拼接 depth_full
表。
Q3:心跳报错“Broken pipe”怎么办?
A:通常是网络瞬断引起,用 run_forever(ping_interval=0, ping_timeout=None)
参数包裹,结合自动重连逻辑即可。
Q4:用pandas写入内存变慢?
A:WebSocket 线程与计算线程分离,采用 queue.Queue
缓存,再启动批量写入协程可有效降低 GIL 阻塞。
Q5:有没有现成的 Python async 版本?
A:可参考社区 async 分支,但长链场景下官方并不建议,权衡 IO 密集与 CPU 密集再决策。
附加性能与合规要点
- 延迟
结束前实测主流云机房 < 30 ms,可使用ws.ping()
计算往返延迟并动态切换线路。 - 合规
所有数据仅用于 量化回测 及策略研究,切勿用于暗池撮合或市场操纵。 - 版本回退
OKEx 偶尔强制升级 WS 协议,把run_forever()
更新到websocket-client>=1.3.2
可避免 TLS 握手错误。