Advanced 套餐专属。连接地址 wss://marilux.dev/stocks,协议和 Polygon 官方 WebSocket 完全一致:连上先鉴权,鉴权成功后按需订阅,之后行情会持续推过来,直到你退订或断开。
1. 连接后会先收到:
[{"ev":"status","status":"connected","message":"Connected Successfully"}]
2. 发送鉴权消息:
{"action":"auth","params":"mh_live_your_key"}成功返回 auth_success;套餐不是 Advanced、Key 已停用/过期、或超出套餐的并发连接数上限都会返回 auth_failed,原因见 message(连接数超限时会带上你的上限)。连接建立后须在 10 秒内鉴权成功,否则服务端会以关闭码 1008 断开连接,鉴权失败的连接同样会被断开,请修正原因后重新连接。
[{"ev":"status","status":"auth_success","message":"authenticated"}]
3. 订阅标的:params 是"事件类型.股票代码",逗号分隔可以一次订阅多个,事件类型 T=逐笔成交、Q=逐笔报价。
{"action":"subscribe","params":"T.AAPL,Q.AAPL,T.MSFT"}订阅成功返回:
[{"ev":"status","status":"success","message":"subscribed to: T.AAPL,Q.AAPL"}]订阅数超出套餐上限时,超出的部分会被拒绝,已订阅的部分不受影响,并额外收到一条错误消息列出未订阅的标的:
[{"ev":"status","status":"error","message":"已达到套餐订阅股票数上限(200 只),未订阅: T.MSFT"}]
4. 行情推送——数组形式,可能一次包含多条:
[{"ev":"T","sym":"AAPL","x":12,"i":"133121","p":334.8,"s":5,"c":[12,14,37,41],"t":1789775989256756500}]
订阅上限按股票数计算:同一只股票同时订阅成交(T.AAPL)和报价(Q.AAPL)只算 1 只。暂不支持通配符(*)订阅全市场。各档位上限:
- 高级版体验:1 个连接,10 只股票
- 高级版月付/季付:2 个连接,200 只股票
- 高级版半年付:3 个连接,500 只股票
- 高级版年付:5 个连接,500 只股票
断线重连:如果你的程序处理消息太慢、服务端待发送的数据积压超过 2MB,连接会以关闭码 1013 断开,以免拖累其他客户;服务器维护重启时连接也会断开。请务必实现自动重连,重连后重新发送 auth 和 subscribe。
退订用 {"action":"unsubscribe","params":"T.AAPL"}。不再需要某个标的记得退订,不退订不会额外收费,但会一直占着你套餐的订阅数配额。
Node.js 示例:
const ws = new WebSocket("wss://marilux.dev/stocks");
ws.onmessage = (event) => {
const msgs = JSON.parse(event.data);
for (const m of msgs) {
if (m.status === "connected") ws.send(JSON.stringify({ action: "auth", params: "mh_live_your_key" }));
if (m.status === "auth_success") ws.send(JSON.stringify({ action: "subscribe", params: "T.AAPL" }));
if (m.ev === "T") console.log("成交:", m.sym, m.p, m.s);
}
};
Python 示例:(pip install websockets)
import asyncio, json, websockets
async def main():
async with websockets.connect("wss://marilux.dev/stocks") as ws:
async for raw in ws:
for m in json.loads(raw):
if m.get("status") == "connected":
await ws.send(json.dumps({"action": "auth", "params": "mh_live_your_key"}))
elif m.get("status") == "auth_success":
await ws.send(json.dumps({"action": "subscribe", "params": "T.AAPL"}))
elif m.get("ev") == "T":
print("成交:", m["sym"], m["p"], m["s"])
asyncio.run(main())