一、WebSocket 实时行情
1.1 连接、订阅与心跳
一条长连接,按产品或按市场订阅,订阅成功后持续收到实时行情。
连接地址
WS
ws://hk.psbangu.cn:9017/websocket/json/{key}- 把地址里的
{key}换成你的密钥。 - 服务端发来的消息都是 JSON 文本;客户端发出的命令是一行文本。
连接结果
{
"Cmd": "connect", // connect 是连接结果
"State": 0, // 0 表示连接成功
"Msg": "ok"
}
- 收到这条消息(
State为 0)之后再发送订阅命令。 - 密钥无效时连接会被直接关闭,不会收到任何消息。
命令一览
| 命令 | 作用 | 结果消息的 Cmd |
|---|---|---|
| /sub/{产品} | 订阅产品 | bind |
| /unsub/{产品} | 取消订阅产品 | UnSub |
| /submkt/{市场} | 订阅整个市场 | bind |
| /unsubmkt/{市场} | 取消订阅市场 | UnSubmkt |
| /heartbeat/PING | 心跳 | ping |
订阅产品
发送
/sub/NASDAQ:AAPL,NASDAQ:TSLA产品写成 市场:代码,多个用英文逗号隔开。每个产品各回一条结果:
{
"Cmd": "bind", // bind 是订阅命令的结果
"Msg": [
{
"type": "symbol", // symbol 产品订阅,exchange 市场订阅
"res": true, // true 订阅成功,false 订阅失败
"message": "[NASDAQ:AAPL] symbol subscription success." // 结果说明
}
]
}
res为 true 表示这个产品订阅成功;type为 symbol 表示这是产品订阅的结果。- 市场代码和产品代码用产品列表接口返回的原值,照原样写;代码里有
&等符号时不要像 HTTP 那样转义。 - 也可以只写代码(如
/sub/NVDA),但这样别的市场里代码相同的产品会一起订阅上(实测只写 AAPL,除了 NASDAQ 的,还会收到其它市场里代码同为 AAPL 的产品),所以建议带上市场。 - 一条命令可以带很多个产品(实测一条命令 60 个产品全部订阅成功),结果是一条一条陆续返回的。
- 一条命令里可能部分成功、部分失败,要逐条看
res。代码不存在或没有权限时:
{
"Cmd": "bind", // bind 是订阅命令的结果
"Msg": [
{
"type": "symbol", // symbol 产品订阅,exchange 市场订阅
"res": false, // true 订阅成功,false 订阅失败
"message": "[ZZZNOTEXIST] symbol subscription failed: Insufficient permissions." // 结果说明
}
]
}
取消订阅产品
发送
/unsub/NASDAQ:TSLA{
"Cmd": "UnSub", // UnSub 是取消订阅产品的结果
"Msg": [
{
"code": "NASDAQ:TSLA", // 产品
"res": true, // 是否成功
"message": "[NASDAQ:TSLA] Unsubscription symbol successful." // 结果说明
}
]
}
订阅整个市场
发送
/submkt/NASDAQ{
"Cmd": "bind", // bind 是订阅命令的结果
"Msg": [
{
"type": "exchange", // symbol 产品订阅,exchange 市场订阅
"res": true, // true 订阅成功,false 订阅失败
"message": "[NASDAQ] exchange subscription success." // 结果说明
}
]
}
- 订阅后会收到这个市场里全部产品的行情,数据量比按产品订阅大得多,客户端要持续读取、及时处理。
- 多个市场用英文逗号隔开。取消订阅后立刻不再推送:
发送
/unsubmkt/NASDAQ{
"Cmd": "UnSubmkt", // UnSubmkt 是取消订阅市场的结果
"Msg": [
{
"code": "NASDAQ", // 市场代码
"res": true, // 是否成功
"message": "[NASDAQ] Unsubscription exchange successful." // 结果说明
}
]
}
行情推送
{
"State": 1,
"Msg": { // 行情内容,字段含义见「行情字段说明」
"code": "AAPL", // 产品代码
"name": "Apple Inc.", // 名称
"Market": "NASDAQ", // 市场代码
"varieties": "XNAS_CS", // 品种
"price": 333.69, // 最新价
"open": 333.26, // 今开
"high": 334.54, // 今高
"low": 330.61, // 今低
"volume": 61650.184844, // 成交量,当日累计
"close": 330.32, // 昨收:昨日收盘价,而非当前收盘价
"average": 332.702, // 均价
"amount": "20511139.7980", // 成交额,当日累计
"up": "1.020", // 涨跌幅(%)
"change": "3.370", // 涨跌
"LP": 332.79, // 盘前、盘中、盘后最新价
"odd": 332.82, // 碎股交易
"NV": 15, // 现量,最近一笔成交的量
"MT": "2",
"MRTA": "1", // 交易方向:1 买,2 卖
"dealTransaction": "1791195347,332.82,15,1,", // 逐笔交易:时间(秒),价格,量,方向,序号,时间(毫秒)
"B1": 332.73, // 买一价
"B1V": 280, // 买一量
"S1": 332.85, // 卖一价
"S1V": 200, // 卖一量
"ticks": 1791195347848, // 时间,毫秒
"tick": 1791195347, // 时间,Unix 秒
"a": "12,37",
"T": "2026-10-05" // 是否正常交易:日期,和当前时间相差 7 天可能已退市
},
"Code": "AAPL", // 产品代码
"Cmd": "rm" // rm 表示行情
}
Cmd为 rm 的是行情,内容在Msg里;用Msg.Market和Msg.code认产品。Msg里各字段的含义见「行情字段说明」。同一个字段可能是数字也可能是字符串,使用前先转换。- 订阅成功后要等这个产品有新的行情才会推送;休市时可能长时间没有推送。
心跳
| 方向 | 内容 | 说明 |
|---|---|---|
| 客户端 → 服务端 | /heartbeat/PING | 建议每 10 秒发一次 |
| 服务端 → 客户端 | {"Cmd":"ping","Msg":"ok"} | 对客户端心跳的应答 |
| 服务端 → 客户端 | {"Cmd":"heartbeat","Msg":"ping"} | 客户端没有发心跳时,服务端大约每 10 秒发一次 |
断线与重连
- 订阅只对当前这条连接有效,重连后要重新发送全部订阅命令。
- 长时间收不到任何消息(包括心跳)时,关掉这条连接重新连。
- 密钥无效时不要反复重连。