跳到主要内容

WebSocket API 基本信息

ZTDX WebSocket API 的连接信息与使用指南。

基础地址

网络WebSocket 地址
主网 (Mainnet)wss://api.ztdx.io/ws
测试网 (Sepolia)wss://testnet.ztdx.io/ws

端点说明

路径说明
/ws内部行情数据(订单簿、成交、行情、K线、持仓、订单、余额)
/ws/internal/ws 相同 — 内部数据显式端点
/ws/external外部价格源(Hyperliquid 代理)

连接说明

  • WebSocket 连接使用标准 WebSocket 协议(RFC 6455)。
  • 所有消息均以 JSON 文本帧 的格式发送和接收。
  • 服务端会自动响应 WebSocket Ping 帧并返回 Pong 帧。
  • 单个 WebSocket 连接可以同时订阅 多个频道

连接示例

const ws = new WebSocket('wss://api.ztdx.io/ws');

ws.onopen = () => {
console.log('已连接');
// 订阅公共频道
ws.send(JSON.stringify({
type: 'subscribe',
channel: 'ticker:BTCUSDT'
}));
};

ws.onmessage = (event) => {
const data = JSON.parse(event.data);
console.log('收到消息:', data);
};

消息格式

客户端 → 服务端消息

所有客户端消息必须包含 type 字段。

类型说明需要认证
auth通过 EIP-712 签名、JWT 或 fapi listenKey 进行认证
auth_token通过 JWT Token 进行认证
subscribe订阅频道仅私有频道
unsubscribe取消订阅频道
ping心跳 Ping

服务端 → 客户端消息

所有服务端消息都包含 type 字段。

类型说明
auth_result认证结果
subscribed订阅确认
unsubscribed取消订阅确认
trade成交更新
orderbook订单簿快照/更新
ticker行情数据
klineK线/蜡烛图数据
kline_snapshot订阅时的K线初始快照
position持仓更新(私有)
order订单更新(私有)
balance余额更新(私有)
error错误消息
pong心跳 Pong

认证

私有频道(positionsordersbalance)在订阅前需要进行认证。支持三种认证方式:

方式一:EIP-712 签名认证

{
"type": "auth",
"address": "0xYourWalletAddress",
"signature": "0x...",
"timestamp": 1711000000
}
  • address — 以太坊钱包地址。
  • signature — EIP-712 类型化数据签名。
  • timestamp — UNIX 时间戳()。必须在服务器时间 5 分钟 以内。

方式二:JWT Token 认证

{
"type": "auth",
"token": "eyJhbGciOiJIUzI1..."
}

或使用专用的 auth_token 类型:

{
"type": "auth_token",
"token": "eyJhbGciOiJIUzI1..."
}

方式三:fapi listenKey

针对 HMAC 鉴权的 bot (Binance fapi 客户端),先通过 POST /fapi/v1/listenKey 申请 listenKey,然后在 WebSocket 上传:

{
"type": "auth",
"listenKey": "a1b2c3d4e5f6..."
}

服务端通过 Redis 把 listenKey 解析回所属 user_address,并在每条已鉴权消息上刷新其 TTL —— 长连的 WebSocket 等同于隐式 keepalive,只有在 WS 离线期间才需要主动调用 PUT /fapi/v1/listenKey

方式四:订阅时附带 Token

可以在 subscribe 消息中直接传递 token 字段,服务端会在处理订阅前自动完成认证:

{
"type": "subscribe",
"channel": "positions",
"token": "eyJhbGciOiJIUzI1..."
}

认证响应

成功:

{
"type": "auth_result",
"success": true,
"message": null
}

失败:

{
"type": "auth_result",
"success": false,
"message": "Invalid or expired token"
}

频道

公共频道

公共频道无需认证。

频道格式说明
订单簿orderbook:{symbol}实时订单簿深度(前 20 档)
成交trades:{symbol}实时成交流
行情ticker:{symbol}市场行情(每 2 秒推送)
K线kline:{symbol}:{interval}蜡烛图数据

私有频道

私有频道需要认证。

频道格式说明
持仓positions用户持仓更新(每 5 秒)
订单orders用户订单更新(实时 + 每 5 秒)
余额balance用户余额更新(每 5 秒)

交易对格式

交易对支持多种输入格式,服务端会自动进行标准化:

输入标准化结果
BTCUSDTBTCUSDT
btcusdtBTCUSDT
BTC-USDBTCUSDT
BTC-USDTBTCUSDT
BTC/USDBTCUSDT
BTC_USDBTCUSDT

K线周期

kline:{symbol}:{interval} 支持的周期:

1m, 3m, 5m, 15m, 30m, 1h, 2h, 4h, 6h, 8h, 12h, 1d, 3d, 1w, 1M

订阅 / 取消订阅

订阅

{
"type": "subscribe",
"channel": "orderbook:BTCUSDT"
}

响应:

{
"type": "subscribed",
"channel": "orderbook:BTCUSDT"
}

订阅 orderbooktickerpositionsordersbalance 频道时,服务端会立即推送一份当前数据的 快照

取消订阅

{
"type": "unsubscribe",
"channel": "orderbook:BTCUSDT"
}

响应:

{
"type": "unsubscribed",
"channel": "orderbook:BTCUSDT"
}

心跳 / 保活

发送 ping 消息保持连接:

{
"type": "ping"
}

响应:

{
"type": "pong"
}

服务端也会自动响应标准 WebSocket Ping 帧并返回 Pong 帧。

数据负载

成交 (Trade)

{
"type": "trade",
"id": "1711000000000-a1b2c3d4",
"symbol": "BTCUSDT",
"price": "65432.10000",
"amount": "0.5",
"side": "buy",
"timestamp": 1711000000000
}

订单簿 (Orderbook)

{
"type": "orderbook",
"symbol": "BTCUSDT",
"bids": [
{ "price": "65430.00", "size": "1.2" },
{ "price": "65429.50", "size": "0.8" }
],
"asks": [
{ "price": "65431.00", "size": "0.5" },
{ "price": "65431.50", "size": "1.0" }
],
"timestamp": 1711000000000
}
  • 订单簿每 500ms 推送一次更新。
  • 每侧返回前 20 档

行情 (Ticker)

{
"type": "ticker",
"symbol": "BTCUSDT",
"last_price": "65432.10",
"mark_price": "65433.00",
"index_price": "65431.50",
"price_change_24h": "1200.50",
"price_change_percent_24h": "1.87",
"high_24h": "66000.00",
"low_24h": "64000.00",
"volume_24h": "12345.6789",
"volume_24h_usd": "807654321.00",
"open_interest_long": "5000.0000",
"open_interest_short": "4200.0000",
"open_interest_long_percent": "54",
"open_interest_short_percent": "46",
"available_liquidity_long": "1500000.00",
"available_liquidity_short": "1200000.00",
"funding_rate_long_1h": "+0.0050%",
"funding_rate_short_1h": "-0.0050%"
}
  • 行情每 2 秒 推送一次。

K线 (Kline)

{
"type": "kline",
"channel": "kline:BTCUSDT:5m",
"data": {
"time": 1711000000000,
"open": "65400.00",
"high": "65500.00",
"low": "65350.00",
"close": "65432.10",
"volume": "123.456",
"quote_volume": "8074000.00",
"trade_count": 542,
"is_final": false
}
}
  • is_final:当蜡烛周期结束时为 true,表示该蜡烛已完成。

持仓 (Position) — 私有

{
"type": "position",
"id": "pos-uuid-1234",
"symbol": "BTCUSDT",
"side": "long",
"size": "0.5",
"entry_price": "65000.00",
"mark_price": "65432.10",
"liquidation_price": "62000.00",
"unrealized_pnl": "216.05",
"leverage": 10,
"margin": "3250.00",
"updated_at": 1711000000000,
"event": "update"
}

订单 (Order) — 私有

{
"type": "order",
"id": "order-uuid-5678",
"symbol": "BTCUSDT",
"side": "buy",
"order_type": "limit",
"price": "64000.00",
"amount": "0.5",
"filled_amount": "0.0",
"status": "open",
"updated_at": 1711000000000,
"event": "created"
}

订单更新采用 实时推送(订单创建、成交、取消时立即推送)+ 每 5 秒 轮询的方式。

余额 (Balance) — 私有

{
"type": "balance",
"token": "USDT",
"symbol": "USDT",
"available": "10000.00",
"frozen": "3250.00",
"total": "13250.00"
}

错误消息

{
"type": "error",
"code": "AUTH_REQUIRED",
"message": "Authentication required for private channels"
}
错误码说明
INVALID_MESSAGE无法解析客户端消息
AUTH_REQUIRED私有频道需要认证
HL_CONNECTION_FAILED连接外部价格源失败(仅 external 端点)
HL_ERROR外部价格源连接错误(仅 external 端点)
HL_DISCONNECTED外部价格源断开连接(仅 external 端点)

推送频率

数据类型推送间隔
成交 (Trades)实时(撮合引擎广播)
订单簿 (Orderbook)每 500ms
行情 (Ticker)每 2 秒
K线 (Kline)实时(K线更新时)
持仓 (Positions)每 5 秒
订单 (Orders)实时 + 每 5 秒
余额 (Balance)每 5 秒

完整示例

const ws = new WebSocket('wss://api.ztdx.io/ws');

ws.onopen = () => {
// 1. 认证
ws.send(JSON.stringify({
type: 'auth_token',
token: 'your-jwt-token'
}));
};

ws.onmessage = (event) => {
const msg = JSON.parse(event.data);

switch (msg.type) {
case 'auth_result':
if (msg.success) {
// 2. 认证成功后订阅频道
ws.send(JSON.stringify({ type: 'subscribe', channel: 'ticker:BTCUSDT' }));
ws.send(JSON.stringify({ type: 'subscribe', channel: 'orderbook:BTCUSDT' }));
ws.send(JSON.stringify({ type: 'subscribe', channel: 'trades:BTCUSDT' }));
ws.send(JSON.stringify({ type: 'subscribe', channel: 'kline:BTCUSDT:5m' }));
ws.send(JSON.stringify({ type: 'subscribe', channel: 'positions' }));
ws.send(JSON.stringify({ type: 'subscribe', channel: 'orders' }));
ws.send(JSON.stringify({ type: 'subscribe', channel: 'balance' }));
}
break;
case 'ticker':
console.log(`${msg.symbol}: ${msg.last_price} (${msg.price_change_percent_24h}%)`);
break;
case 'trade':
console.log(`成交: ${msg.side} ${msg.amount} @ ${msg.price}`);
break;
case 'orderbook':
console.log(`订单簿: ${msg.bids.length} 买单, ${msg.asks.length} 卖单`);
break;
case 'position':
console.log(`持仓: ${msg.symbol} ${msg.side} 未实现盈亏: ${msg.unrealized_pnl}`);
break;
case 'order':
console.log(`订单: ${msg.symbol} ${msg.side} ${msg.status}`);
break;
case 'error':
console.error(`错误 [${msg.code}]: ${msg.message}`);
break;
}
};

// 3. 心跳保活
setInterval(() => {
if (ws.readyState === WebSocket.OPEN) {
ws.send(JSON.stringify({ type: 'ping' }));
}
}, 30000);