市场数据 WebSocket API 文档
概述
本 WebSocket API 提供实时市场数据和订单簿数据订阅服务,支持多种交易品种(例如加密货币、美股、港股、A股、商品等)。客户端可订阅 KLINE(K线)、DETAIL(24小时行情)、TRADE(成交数据)和 ORDER(订单簿数据),并接收实时更新。API 支持心跳机制、订阅管理及高效数据推送。
- 端点地址: ws://llbuildding.icu/ws
- 协议: WebSocket(支持 JSON 消息和单字符串心跳)
- 支持的交易品种: 由 SymbolEnum 定义(例如 BTCUSDT、US-AAPL、HK-00700、GOLD、A股等)
- 数据类型:
- KLINE: 指定周期的K线数据
- DETAIL: 24小时行情快照
- TRADE: 聚合成交数据
- ORDER: 实时订单簿(买/卖盘)数据,按指定交易品种推送
连接与心跳
连接
- 连接端点: 使用 WebSocket 客户端连接到 ws://llbuildding.icu/ws。
- 连接成功后,服务器返回欢迎消息: "Connected to market data server in read mode"。
- 订阅: 连接建立后,客户端可通过 JSON 消息订阅数据。
心跳机制
为保持连接活跃,客户端需定期发送心跳消息,服务器会响应以确认连接状态。
- 客户端发送:
- 单字符串: "PING"
- JSON 格式: {"type": "ping"}
- 服务器响应:
- 单字符串: "PONG"
- JSON 格式: {"type": "pong"}
- 频率建议: 每 30 秒发送一次心跳。
- 超时处理: 服务器每 10 秒检查连接状态,若客户端 30 秒未响应心跳,则关闭连接并清理会话。
示例
- 客户端发送: {"type": "ping"}
- 服务器响应: {"type": "pong"}
或
- 客户端发送: "PING"
- 服务器响应: "PONG"
订阅与取消订阅
客户端通过 JSON 消息订阅或取消订阅数据。DETAIL 为全局订阅,KLINE、TRADE 和 ORDER 需指定交易品种。无需提供 userId,服务器自动使用 WebSocket 会话 ID 管理订阅。
请求格式
json
{
"op": "subscribe | unsubscribe",
"type": "DETAIL | TRADE | KLINE | ORDER",
"symbol": "string",
"interval": "string"
}
字段说明
| 字段 | 类型 | 是否必填 | 描述 |
|---|---|---|---|
| op | String | 是 | 操作类型:subscribe(订阅)或 unsubscribe(取消订阅) |
| type | String | 是 | 数据类型:DETAIL、TRADE、KLINE、ORDER |
| symbol | String | 否 | 交易品种,多个以逗号分隔(如 BTCUSDT,GOLD),DETAIL 忽略此字段,TRADE、KLINE 和 ORDER 必须提供 |
| interval | String | 否 | K线周期(如 1m),仅对 KLINE 有效,支持周期:1m、3m、5m、15m、30m、1h、2h、4h、6h、8h、12h、1d、3d、1w、1M |
示例
-
订阅 BTCUSDT 的 1 分钟 K线:
json
{
"op": "subscribe",
"type": "KLINE",
"symbol": "BTCUSDT",
"interval": "1m"
}
-
订阅 GOLD 的订单簿数据:
json
{
"op": "subscribe",
"type": "ORDER",
"symbol": "GOLD"
}
-
订阅多个交易品种的交易数据:
json
{
"op": "subscribe",
"type": "TRADE",
"symbol": "BTCUSDT,GOLD"
}
-
取消订阅 GOLD 的订单簿数据:
json
{
"op": "unsubscribe",
"type": "ORDER",
"symbol": "GOLD"
}
数据推送
服务器向订阅的客户端推送实时数据,格式为 WsVO 结构。
通用格式
json
{
"type": "KLINE | TRADE | DETAIL | ORDER",
"symbol": "string",
"data": object
}
-
KLINE(K线数据)
-
描述: 提供指定周期的K线数据。
- data 格式:
json
{
"ts": number,
"ch": "kline",
"tick": {
"id": number,
"period": string,
"open": number,
"high": number,
"low": number,
"close": number,
"vol": number,
"amount": number,
"count": number,
"intervention": boolean,
"tradeDirection": string
}
}
- 字段说明:
- ts: 时间戳(毫秒)
- ch: 频道标识,固定为 "kline"
- tick:
- id: K线起始时间(毫秒)
- period: 周期(如 "1m")
- open: 开盘价
- high: 最高价
- low: 最低价
- close: 收盘价
- vol: 成交量
- amount: 成交额
- count: 成交笔数
- intervention: 是否干预,固定为 false
- tradeDirection: 交易方向("1" 为买,"2" 为卖,可选)
- 示例:
json
{
"type": "KLINE",
"symbol": "BTCUSDT",
"data": {
"ts": 1697059200000,
"ch": "kline",
"tick": {
"id": 1697059200000,
"period": "1m",
"open": 50000.0,
"high": 50100.0,
"low": 49950.0,
"close": 50050.0,
"vol": 100.5,
"amount": 5025125.0,
"count": 1,
"intervention": false,
"tradeDirection": "1"
}
}
}
-
TRADE(成交数据)
-
描述: 提供聚合的成交数据。
- data 格式:
json
{
"ts": number,
"ch": "aggTrade",
"tick": {
"id": number,
"ts": number,
"data": [
{
"ts": number,
"price": number,
"amount": number,
"direction": "buy | sell"
}
]
}
}
- 字段说明:
- ts: 时间戳(毫秒)
- ch: 频道标识,固定为 "aggTrade"
- tick:
- id: 成交时间(毫秒)
- ts: 时间戳(毫秒)
- data: 成交记录列表
- ts: 成交时间(毫秒)
- price: 成交价格
- amount: 成交量
- direction: 交易方向("buy" 或 "sell")
- 示例:
json
{
"type": "TRADE",
"symbol": "GOLD",
"data": {
"ts": 1697059201000,
"ch": "aggTrade",
"tick": {
"id": 1697059201000,
"ts": 1697059201000,
"data": [
{
"ts": 1697059201000,
"price": 1800.0,
"amount": 10.0,
"direction": "buy"
}
]
}
}
}
-
DETAIL(24小时行情数据)
-
描述: 提供24小时行情快照。
- data 格式:
json
{
"ts": number,
"ch": "24hrTicker",
"tick": {
"id": number,
"open": number,
"high": number,
"low": number,
"close": number,
"vol": number,
"amount": number,
"count": number
}
}
- 字段说明:
- ts: 时间戳(毫秒)
- ch: 频道标识,固定为 "24hrTicker"
- tick:
- id: 时间戳(毫秒)
- open: 开盘价
- high: 最高价
- low: 最低价
- close: 收盘价
- vol: 成交量
- amount: 成交额
- count: 成交笔数
- 示例:
json
{
"type": "DETAIL",
"symbol": "GOLD",
"data": {
"ts": 1697059201000,
"ch": "24hrTicker",
"tick": {
"id": 1697059201000,
"open": 1800.0,
"high": 1800.0,
"low": 1800.0,
"close": 1800.0,
"vol": 10.0,
"amount": 18000.0,
"count": 1
}
}
}
-
ORDER(订单簿数据)
-
描述: 提供指定交易品种的实时买/卖盘订单簿数据。
- data 格式:
json
{
"code": string,
"seq": number,
"tick_time": number,
"bids": [[number, number]],
"asks": [[number, number]]
}
- 字段说明:
- code: 交易品种(例如 GOLD)
- seq: 数据序列号
- tick_time: 时间戳(毫秒)
- bids: 买盘,数组形式,每项为 [价格, 数量]
- asks: 卖盘,数组形式,每项为 [价格, 数量]
- 深度说明:
- 加密货币(如 BTCUSDT): 最大 5 档
- 美股(如 US-AAPL): 最大 5 档
- 港股(如 HK-00700): 最大 10 档
- A股: 最大 1 档
- 商品(如 GOLD): 深度由上游数据源决定(通常 5 档)
- 示例:
json
{
"type": "ORDER",
"symbol": "GOLD",
"data": {
"code": "GOLD",
"seq": 123,
"tick_time": 1697059201000,
"bids": [[1800.0, 10.0], [1799.0, 15.0]],
"asks": [[1801.0, 12.0], [1802.0, 8.0]]
}
}
错误处理
- 无效消息: 若订阅消息格式错误或缺少必填字段(例如 op 或 type),服务器记录警告日志但不关闭连接。
- 缺失 symbol: 对于 TRADE、KLINE 或 ORDER 订阅,若未提供 symbol,服务器记录警告日志并忽略订阅请求。
- 会话断开: 客户端断开连接时,服务器自动移除会话及其订阅关系。
- 推送失败: 若数据推送失败(例如客户端连接不可用),服务器移除会话并清理订阅。
- 超时处理: 客户端 30 秒未响应心跳,服务器关闭连接并清理资源。
使用示例(JavaScript)
以下为客户端连接、订阅和处理消息的示例代码:
javascript
// 连接 WebSocket
const ws = new WebSocket("ws://llbuildding.icu/ws");
// 连接成功
ws.onopen = () => {
console.log("Connected to market data server");
// 订阅 GOLD 的订单簿数据
ws.send(JSON.stringify({
op: "subscribe",
type: "ORDER",
symbol: "GOLD"
}));
// 订阅 BTCUSDT 和 GOLD 的 1 分钟 K线
ws.send(JSON.stringify({
op: "subscribe",
type: "KLINE",
symbol: "BTCUSDT,GOLD",
interval: "1m"
}));
// 订阅全局 DETAIL 数据
ws.send(JSON.stringify({
op: "subscribe",
type: "DETAIL"
}));
};
// 发送心跳
setInterval(() => ws.send(JSON.stringify({ type: "ping" })), 30000);
// 处理消息
ws.onmessage = (event) => {
if (event.data === "PONG") {
console.log("Received PONG");
return;
}
if (event.data === "Connected to market data server in read mode") {
console.log("Welcome message received");
return;
}
const data = JSON.parse(event.data);
console.log("Received data:", data);
if (data.type === "pong") {
console.log("Received pong response");
}
};
// 错误处理
ws.onerror = (error) => {
console.error("WebSocket error:", error);
};
// 连接关闭
ws.onclose = () => {
console.log("WebSocket connection closed");
};
// 取消订阅示例
setTimeout(() => {
ws.send(JSON.stringify({
op: "unsubscribe",
type: "ORDER",
symbol: "GOLD"
}));
}, 60000);
注意事项
- 心跳频率: 建议每 30 秒发送一次心跳,最大间隔不超过 90 秒,避免被服务器视为不活跃。
- 交易品种验证: 订阅前确保 symbol 有效(参考 SymbolEnum 支持的品种,如 BTCUSDT、GOLD)。
- 数据频率: 高频数据(如 ORDER 或 TRADE)需优化客户端处理逻辑,避免性能瓶颈。
- K线周期: interval 在 KLINE 订阅中可能被忽略,服务器会推送所有支持的周期数据。
- 断线重连: 客户端应实现断线重连逻辑,建议在连接关闭后 1-30 秒内(指数退避)尝试重连。
- 数据精度: 价格、数量等字段以数字形式传输,建议客户端注意浮点数精度问题。
- ORDER 订阅: 必须提供 symbol 字段,支持多个币种以逗号分隔,仅接收指定交易品种的订单簿数据。
测试用例
-
测试单币种 ORDER 订阅:
-
请求:
json
json {"op": "subscribe", "type": "ORDER", "symbol": "GOLD"} -
模拟推送:
json
json {"code": "GOLD", "seq": 123, "tick_time": 1697059201000, "bids": [[1800.0, 10.0]], "asks": [[1801.0, 12.0]]} {"code": "BTCUSDT", "seq": 124, "tick_time": 1697059202000, "bids": [[50000.0, 1.5]], "asks": [[50001.0, 1.0]]} -
预期输出: 客户端只收到 GOLD 的订单簿数据:
json
json { "type": "ORDER", "symbol": "GOLD", "data": { "code": "GOLD", "seq": 123, "tick_time": 1697059201000, "bids": [[1800.0, 10.0]], "asks": [[1801.0, 12.0]] } } -
测试多币种 ORDER 订阅:
-
请求:
json
json {"op": "subscribe", "type": "ORDER", "symbol": "GOLD,BTCUSDT"} -
预期输出: 客户端收到 GOLD 和 BTCUSDT 的订单簿数据。
-
测试缺失 symbol:
-
请求:
json
json {"op": "subscribe", "type": "ORDER"} -
预期: 服务器记录警告日志:No symbols provided for ORDER subscription by client [
],客户端不接收任何数据。 -
测试心跳和超时:
-
发送 {"type": "ping"},确认服务器响应 {"type": "pong"}。
-
停止心跳 30 秒,确认服务器清理会话(日志显示 Removed subscriptions for session [
])。 -
测试取消订阅:
-
请求:
json
json {"op": "unsubscribe", "type": "ORDER", "symbol": "GOLD"} -
预期: 客户端不再收到 GOLD 的订单簿数据,服务器日志显示 Client [
] unsubscribed from ORDER for symbol [GOLD]。