很多刚接触行情监控的小伙伴第一反应都是:能不能用requests循环请求每个股票的接口,把最新的价格取出来?我曾经也是这样想的。结果呢,五千多只股票轮一圈要好几分钟,拿到的价格早就失真了。就算起多线程并发请求,也很快会被数据源限制频率,还容易把自己的IP拉黑。
后来我换了一种思路:不再主动去“要”数据,而是让数据“送”上门。借助WebSocket长连接和批量订阅功能,我只需要建立一个连接,就能同时接收多只甚至全市场的实时成交信息。今天我把这个方案拆解出来,手把手带你上手。
轮询的硬伤在哪里?
轮询的本质是客户端定期发起查询,服务端被动应答。想象一下,全班50个同学挨个问你“现在几点”,你回答完第50个的时候,时间早就变了。A股市场的tick变化可比秒针快多了,高峰期一秒钟可能有数百笔成交。如果用轮询去捕捉这些瞬间,大概率会漏掉绝大部分的波动。
WebSocket推送则相反,它建立了一个持久的双向通道,服务端一旦发现有新的成交,就主动把消息推给你,不管你现在有没有开口问。这种模式下,无论你关心的是10只还是5000只股票,只需要维护一条连接,资源占用稳定,时效性却能提升好几个量级。
行情接口的两种订阅姿势
不同接口的订阅参数格式可能略有不同,但万变不离其宗,常见的就两种:
| 订阅方式 | 数据格式 | 适合场景 |
|---|---|---|
| 数组列表 | ["000001","000002","600036"] |
代码中动态生成订阅列表 |
| 逗号分隔字符串 | "000001,000002,600036" |
简洁,方便通过URL参数传递 |
更高级的接口还支持全市场通配符,你只需要声明“订阅A股全部品种”,后端就会把所有的tick推送给你。当然,这种大权限通常需要单独申请,且对客户端的处理能力有一定要求。
动手:用Python实现多股实时订阅
我们以市面上一个支持WebSocket批量推送的接口(比如ALLTICK API提供的方案)为例。下面这段代码展示了如何用一个连接同时订阅10只A股,并实时打印出每一笔成交。
import websocket
import json
# WebSocket服务地址,用于订阅逐笔成交
url = "wss://apis.alltick.co/websocket-api/stock-websocket-interface-api/transaction-quote-subscription"
def on_message(ws, message):
# 把收到的JSON字符串解析成字典
data = json.loads(message)
# 遍历本次推送的所有tick数据
for tick in data.get("ticks", []):
print(f"代码:{tick['code']} 价格:{tick['price']} 时间:{tick['time']}")
def on_open(ws):
# 构建订阅消息,一次性传入10只A股代码
sub_msg = {
"action": "subscribe",
"symbols": ["000001", "000002", "600036", "600519", "000858",
"002415", "300750", "601318", "000333", "002594"]
}
ws.send(json.dumps(sub_msg))
ws = websocket.WebSocketApp(url, on_message=on_message)
ws.on_open = on_open
ws.run_forever()
运行脚本后,只要这些股票有新的成交,控制台就会实时刷出价格和时间,不用再担心轮询的延迟和遗漏。
数据太多怎么办?几个处理技巧
当行情活跃时,一秒内涌入的tick可能成千上百条。如果处理不及时,程序很容易变卡甚至崩溃。下面这些方法是我在项目中常用的:
- 分通道并行处理:按股票代码的哈希值把tick分到不同的处理队列,启动多个消费者线程同时干活。
- 维护最新价缓存:在内存里用一个字典保存每只股票最新的价格,比如
last_price["000001"]=12.34,需要查询时直接读缓存,不用每次遍历历史。 - 批量写入数据库:不要来一条tick就执行一次INSERT。攒够一定数量(比如50条)或者达到时间间隔(比如100毫秒)再统一写入,能显著降低磁盘IO。
- 按需刷新界面:如果数据是给前端K线或报价表用的,可以设置一个最小变化阈值,只有价格变动超过设定值时才触发界面更新,减轻前端渲染压力。
开启全市场订阅的注意事项
如果你要做全市场扫描或者量化选股,可能会用到全市场通配订阅。这时要注意两点:
一是本地带宽和CPU要足够强。我实测在高峰时段每秒能收到三四百条tick,如果计算能力跟不上,可以先把数据放入消息队列(比如Redis List),让下游服务慢慢消费。
二是利用好数据过滤。很多接口允许设置“仅推送有成交的标的”,无交易时段的大部分股票就不会产生流量,能节省大量开销。
学习建议
对于想批量获取A股实时行情的同学,我强烈建议直接上手WebSocket订阅方案,而不是自己折腾多线程轮询。一条长连接、一组订阅指令,就能让市场数据源源不断地流进来,无论是做监控、回测还是量化交易,这都是一个靠谱的基础设施。
选接口的时候,优先看它是否支持批量订阅和全市场推送,推送的延迟和稳定性如何。我自己在新手阶段就是用类似AllTick这样接口的压测环境,先拿一小撮股票跑通整个数据链,确认没问题后再扩展。这种稳扎稳打的方式,能帮你避开很多不必要的坑。
共同学习,写下你的评论
评论加载中...
作者其他优质文章
