做外汇量化或者给客户实时报价的朋友,应该都纠结过同一个问题:WebSocket订阅行情,到底能同时扛多少个货币对?说实话,“能扛多少”这个问题看起来简单,但答案藏在API配额、解析速度、带宽、心跳机制好几层里,不是单纯数个数就行。这篇文章我打算把WebSocket订阅外汇行情的整套逻辑拆开,从订阅协议、性能瓶颈、压测方法到常见的529、断流报错,一次性说清楚,帮你找到自己这套系统的真实上限。
无论你是刚接触API的量化新手,还是已经在生产环境里跑行情的老手,这篇文章都值得花十分钟看完。我会用实际项目里踩过的坑和跑过的数据来说明,尽量让你看完就能照着做。
1. 先弄明白:WebSocket订阅外汇行情,你到底在订阅什么
1.1 一次典型的行情订阅请求长什么样
很多人一上来就问“能订阅多少个货币对”,其实连API的订阅模型都没搞清楚。不同行情服务商的WebSocket协议长得完全不一样,我见过比较常见的是两类:一类是“按symbol订阅”,比如发送 {"action":"subscribe","symbols":["EUR/USD","GBP/USD"]},服务端把订阅成功的列表返回给你,之后这俩货币对的tick就源源不断推过来;另一类是“按频道订阅”,需要你先把货币对映射到频道ID,再订阅频道,比如某家服务商的格式是 {"op":"subscribe","channel":"ticker","symbol":"EURUSD"}。
这里要提醒一句:很多API文档里写的“支持100个货币对”,指的是REST接口可以查询的数量,不等于WebSocket同时订阅的数量。REST是一次性请求响应,服务端临时查一下返回就完了;WebSocket是服务端保持长连接持续推送,每增加一个货币对,意味着服务端的推送线程、缓冲区、序列化负载都增加。所以WebSocket的订阅上限往往比REST查询上限低一个档次,一定要去文档里找WebSocket专用的限制说明。
订阅报文里还会带上一些参数,比如部分服务商要求指定数据粒度(tick、1秒、1分钟K线),有的要求开启快照推送,有的要求带上session token做鉴权。这些参数会影响后续推送的消息内容,订阅时写错字段,服务端可能不会报错,只是不推数据。实操中我建议订阅成功后,把服务端返回的确认消息打印出来,逐字段核对,而不是肉眼猜。
1.2 为什么大家都选WebSocket而不是REST轮询
这其实是个老话题,但放在外汇场景里值得多说两句。外汇行情是所有金融行情里跳动最频繁的类型之一,EUR/USD这种主流直盘在活跃时段每秒能跳动几十次,个别情况下甚至上百次。如果用REST去轮询,假设你每秒请求一次获取20个货币对的报价,每次请求的HTTP头、TLS握手、鉴权参数加一起,光请求开销就吃掉一大截带宽,而且你永远拿不到两次轮询之间的瞬时价格。做高频策略的人对价格延迟极其敏感,REST的几百毫秒延迟在行情剧变时会导致成交价和看到的价格偏差很大。
WebSocket的优势在于一次握手后保持长连接,数据从服务端主动推送到客户端,延迟通常在几十毫秒甚至更低,而且消息体比REST响应精简很多,不需要每次请求都带上冗长的HTTP头。实际项目里我用过同样一家数据源的REST和WebSocket两套接口对比,同样订阅10个货币对,REST每秒轮询的流量是WebSocket推送的十几倍,数据新鲜度还差着一截。所以只要你的业务允许保持长连接,WebSocket基本是最优解。
不过WebSocket也不是没有代价。长连接意味着连接状态需要维护,断线重连、心跳保活、消息时序这些都要自己处理,这恰恰是很多人踩坑的地方。后面我会专门用一节讲断流和重连的问题。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 决定“能扛多少货币对”的,其实有四层天花板
2.1 服务端配额:第一道很现实的门槛
第一个天花板来自服务端配额,这个最直接,也最容易被忽略。很多行情API是按订阅连接数和订阅symbol数双重计费的。常见模式是:免费账号只能开1-2条WebSocket连接,每条连接最多订阅10-30个symbol;付费入门档可以开5条连接,每条约100个symbol;更高级别的机构账号才支持上千个symbol的订阅。
这里有个容易踩的坑:很多API服务商的“订阅数量”是按“同一连接内同时订阅的数量”算的,不是按账号总订阅量。比如文档写“单连接最多100个symbol”,你可能会想开10条连接订阅1000个,但服务商可能还有“单账号同时最多10条连接”的限制,两条叠加下来实际上限还是1000,甚至因为连接数超限直接拒绝握手。我建议在写代码之前,先给服务商客服或者文档里的配额表格截图留底,搞清楚三件事:单连接symbol上限、单账号连接数上限、推送频率有没有隐含QPS限制。
除了显式的配额,还要注意隐形的“限流”。有一些数据源虽然写着不限制,但当你一条连接里订了太多交易量小的冷门货币对时,服务端会悄悄降低这些symbol的推送频率,或者在你订阅请求频率过高时返回限流错误。我遇到过最无语的情况是:50个货币对在一条连
