Hyperliquid 实时订单簿订阅
-
hyperliquid orderbook websocket
-
real time hyperliquid api
-
hyperliquid 实时订单簿
-
hyperliquid websocket 订阅
-
hyperliquid l2 book
locale: zh-CN
订单簿是交易所的核心数据结构,它实时反映了市场上所有未成交买卖挂单的价格与数量分布。对于量化交易机器人、套利程序和行情分析系统而言,能够以毫秒级延迟获取最新订单簿状态,往往是策略成败的关键。Hyperliquid 提供了完整的 WebSocket 接口,允许订阅者实时接收 L2 订单簿的快照与增量更新。本文将深入讲解订阅方式、消息格式、本地订单簿维护,以及断线重连等生产级别的工程细节。对于不想自建基础设施的交易者,OneKey Perps 已经集成了实时行情显示,开箱即用。
WebSocket 与 REST 轮询的对比
在深入技术细节之前,先理解为什么要用 WebSocket 而非 REST API 轮询:
对于需要实时订单簿的场景,REST 轮询几乎无法替代 WebSocket。参考 Hyperliquid 官方文档 了解完整的 WebSocket 接口规范。
WebSocket 连接建立
端点地址
Hyperliquid 的 WebSocket 端点(截至本文,以官方文档为准):
wss://api.hyperliquid.xyz/ws
基础连接代码
import asyncio
import json
import websockets
WS_URL = "wss://api.hyperliquid.xyz/ws"
async def connect_and_subscribe():
async with websockets.connect(WS_URL) as ws:
发送订阅消息
subscribe_msg = {
"method": "subscribe",
"subscription": {
"type": "l2Book",
"coin": "BTC"
}
}
await ws.send(json.dumps(subscribe_msg))
持续接收消息
async for raw_msg in ws:
msg = json.loads(raw_msg)
handle_message(msg)
asyncio.run(connect_and_subscribe())
订阅消息格式
L2 订单簿订阅
订阅 BTC 的 L2 订单簿:
{
"method": "subscribe",
"subscription": {
"type": "l2Book",
"coin": "BTC"
}
}
Hyperliquid 支持同时订阅多个交易对,只需重复发送订阅消息即可,每个交易对独立推送更新。
取消订阅
{
"method": "unsubscribe",
"subscription": {
"type": "l2Book",
"coin": "BTC"
}
}
消息类型:快照与增量更新
初始快照(Snapshot)
订阅后,服务器首先推送完整的订单簿快照,包含当前所有价位的挂单量:
{
"channel": "l2Book",
"data": {
"coin": "BTC",
"time": 1714500000000,
"levels": [
[
[{"px": "64000.0", "sz": "0.5", "n": 3}, ...], // bids(买单)从高到低
[{"px": "64010.0", "sz": "0.3", "n": 2}, ...] // asks(卖单)从低到高
]
]
}
}
px:价格
sz:该价位的挂单总量(为 0 表示该价位已清空)
n:该价位的挂单笔数
增量更新(Delta)
快照之后,服务器只推送发生变更的价位:
{
"channel": "l2Book",
"data": {
"coin": "BTC",
"time": 1714500000100,
"levels": [
[
[{"px": "63990.0", "sz": "0.0", "n": 0}], // 该买单价位被清空
[{"px": "64010.0", "sz": "0.8", "n": 4}] // 卖单价位量增加
]
]
}
}
当 sz 为 "0" 或 0 时,表示该价位的挂单已全部成交或撤销,需要从本地订单簿中删除该价位。
维护本地订单簿状态
正确维护本地订单簿是使用 WebSocket 数据的核心挑战:
from sortedcontainers import SortedDict
class LocalOrderBook:
def __init__(self, coin):
self.coin = coin
self.bids = SortedDict(lambda x: -float(x)) # 买单:价格从高到低
self.asks = SortedDict(lambda x: float(x)) # 卖单:价格从低到高
self.last_time = None
def apply_snapshot(self, data):
self.bids.clear()
self.asks.clear()
levels = data["levels"][0]
for bid in levels[0]:
if float(bid["sz"]) > 0:
self.bids[bid["px"]] = float(bid["sz"])
for ask in levels[1]:
if float(ask["sz"]) > 0:
self.asks[ask["px"]] = float(ask["sz"])
self.last_time = data["time"]
def apply_delta(self, data):
levels = data["levels"][0]
for bid in levels[0]:
px, sz = bid["px"], float(bid["sz"])
if sz == 0:
self.bids.pop(px, None)
else:
self.bids[px] = sz
for ask in levels[1]:
px, sz = ask["px"], float(ask["sz"])
if sz == 0:
self.asks.pop(px, None)
else:
self.asks[px] = sz
self.last_time = data["time"]
@property
def best_bid(self):
return next(iter(self.bids.items()), None)
@property
def best_ask(self):
return next(iter(self.asks.items()), None)
@property
def mid_price(self):
bid = self.best_bid
ask = self.best_ask
if bid and ask:
return (float(bid[0]) + float(ask[0])) / 2
return None
@property
def spread(self):
bid = self.best_bid
ask = self.best_ask
if bid and ask:
return float(ask[0]) - float(bid[0])
return None
消息处理逻辑
区分快照消息和增量消息,应用到本地状态:
order_book = LocalOrderBook("BTC")
is_initialized = False
def handle_message(msg):
global is_initialized
if msg.get("channel") != "l2Book":
return
data = msg["data"]
if not is_initialized:
order_book.apply_snapshot(data)
is_initialized = True
print(f"订单簿初始化完成,共 {len(order_book.bids)} 档买单,{len(order_book.asks)} 档卖单")
else:
order_book.apply_delta(data)
打印盘口信息
print(f"最优买价: {order_book.best_bid}, 最优卖价: {order_book.best_ask}, 价差: {order_book.spread}")
断线重连处理
WebSocket 连接在网络波动或服务端主动断开时会中断,生产系统必须实现自动重连:
import asyncio
import websockets
async def subscribe_with_reconnect(coin, handle_fn, max_retries=None):
retries = 0
while max_retries is None or retries < max_retries:
try:
async with websockets.connect(WS_URL, ping_interval=20, ping_timeout=10) as ws:
retries = 0 # 连接成功,重置重试计数
is_initialized = False
await ws.send(json.dumps({
"method": "subscribe",
"subscription": {"type": "l2Book", "coin": coin}
}))
async for raw_msg in ws:
handle_fn(json.loads(raw_msg))
except (websockets.ConnectionClosed, ConnectionError, OSError) as e:
retries += 1
wait = min(2 retries, 60) # 指数退避,最长等待 60 秒
print(f"连接断开({e}),{wait} 秒后重试(第 {retries} 次)")
is_initialized = False # 重置状态,下次重新接收快照
await asyncio.sleep(wait)
重连时必须重置 is_initialized 标志,因为重连后服务器会重新推送完整快照,而非从断点继续推送增量。
序列号与消息顺序
Hyperliquid 的 WebSocket 消息包含时间戳字段,可以用于检测消息乱序。生产系统建议:
记录上一条消息的时间戳,若新消息时间戳早于已处理消息,视为过期消息丢弃
如发现长时间无消息推送,主动发送 ping 或重新连接
在高频策略中,考虑使用专线或地理位置更近的节点减少网络延迟
多币对并发订阅
单个 WebSocket 连接可以同时订阅多个交易对,推荐使用异步架构管理并发:
coins = ["BTC", "ETH", "SOL"]
order_books = {coin: LocalOrderBook(coin) for coin in coins}
async def multi_subscribe():
async with websockets.connect(WS_URL) as ws:
for coin in coins:
await ws.send(json.dumps({
"method": "subscribe",
"subscription": {"type": "l2Book", "coin": coin}
}))
async for raw_msg in ws:
msg = json.loads(raw_msg)
if msg.get("channel") == "l2Book":
coin = msg["data"]["coin"]
if coin in order_books:
order_books[coin].apply_delta(msg["data"])
实际应用场景
实时订单簿数据的典型用途包括:
交易机器人:根据盘口价差动态调整挂单价格
套利系统:监控 Hyperliquid 与其他交易所(如 dYdX、GMX)之间的价差
行情分析看板:可视化订单簿深度、价差历史、流动性分布
风控系统:当价差异常扩大或流动性骤降时触发报警
OneKey Perps:无需自建基础设施
自建 WebSocket 订单簿系统需要相当的工程投入。如果你的目标是进行永续合约交易而非开发量化系统,OneKey Perps 提供了完整的实时行情展示和交易功能,结合 OneKey 硬件钱包的安全签名保障,让你专注于交易决策本身。
对于希望通过 WalletConnect 连接去中心化应用的用户,WalletConnect 文档提供了完整的集成指引,OneKey 支持标准的 WalletConnect 协议,可以安全地与 Hyperliquid 等 Web3 应用交互。
常见问题
Q1:WebSocket 连接有并发上限吗?
答:参考 Hyperliquid 官方文档 了解连接数限制。一般建议单个 IP 不要建立过多并发连接,多交易对订阅优先复用同一连接而非创建多条。
Q2:增量更新消息中如果漏收了一条,订单簿状态会错误吗?
答:会。如果增量消息因网络原因丢失,本地状态将与服务器实际状态出现偏差。推荐的做法是:当怀疑状态不一致时(如价差异常、最优价格跳变),主动关闭连接并重新订阅以获取最新快照。
Q3:实时订单簿数据能用于回测吗?
答:直接用于回测不太实际,因为回测需要历史数据而非实时流。建议将实时订单簿数据按时间存储(tick data),积累足够历史后再用于回测研究。也可以结合 Hyperliquid 的历史 K 线 API 进行初步回测。
Q4:如何判断 WebSocket 连接是否健康?
答:建议定期检测以下指标:上次收到消息的时间距今不超过预定阈值(如 5 秒)、连接的 ping/pong 往返延迟在合理范围内。若检测到连接异常,触发主动重连流程。
Q5:OneKey 钱包是否会影响交易延迟?
答:OneKey 硬件钱包的签名操作通常在数百毫秒内完成,对于绝大多数交易策略可以忽略不计。超高频策略(如每秒数十次下单)可以使用 API Agent 子账户热钱包处理高频签名,主账户资金管理由 OneKey 保护,两者职责分离。
结语
实时订单簿订阅是高质量量化交易系统的核心数据来源。Hyperliquid 的 WebSocket API 设计清晰,文档详尽,结合本文的代码框架,开发者可以快速搭建起可靠的订单簿维护系统。无论是做市机器人、套利系统还是实时分析看板,都可以在这一基础上构建。如果你希望在不涉及底层工程的情况下直接参与链上永续合约交易,OneKey Perps 是最值得信赖的入口——安全的硬件签名,加上流畅的交易体验,让你的每一笔交易都有保障。
风险提示:实时订单簿数据仅反映特定时刻的市场状态,不能作为交易决策的唯一依据。基于订单簿数据的自动化交易策略可能因市场剧烈波动、技术故障或策略设计缺陷而造成重大亏损。永续合约交易存在高风险,可能导致全部本金损失。本文内容仅供技术参考,不构成任何投资建议,请在充分了解风险后审慎操作。



