实时行情#
实时行情有两条路径,用途不同:
方式 |
入口 |
什么时候用 |
|---|---|---|
快照查询 |
偶尔问一次”现在什么价”。一次请求一个回答 |
|
订阅推送 |
持续接收行情。有变化就推给你 |
两条路径是独立的:订阅走行情网关,用的是另一个地址和端口,和取历史数据的
服务不是一回事。它们只是共用同一个
Quote 数据类型。
快照查询#
>>> from libfinance import get_last_quotes
>>> get_last_quotes(["600000.XSHG"])
{'600000.XSHG': Quote(...)}
返回一个字典,键是代码。
备注
某个代码当前没有可用快照时,它的值是 None(比如非交易时段,或者这个部署
没有接实时源):
>>> get_last_quotes(["600000.XSHG"])
{'600000.XSHG': None}
所以用之前先判空,不要直接 .last_price。
订阅推送#
订阅是回调式的:你实现一个回调类,注册进去,行情到了会调用你的方法。
from libfinance.subscribe.quote_api import QuoteApi, QuoteSpi
class MySpi(QuoteSpi):
def on_rsp_login(self, rsp, request_id):
if rsp.error_id == 0:
# 订阅写在这里,不要写在 main 里 —— 见下面的说明
api.subscribe(["600519.XSHG", "000001.XSHE"])
def on_depth_market_data(self, quote, envelope):
print(quote.order_book_id, quote.last_price)
api = QuoteApi()
api.register_spi(MySpi())
api.connect() # 不必登录:自动向服务取行情票据,网关地址也由服务给出
不需要登录。 SDK 自动向 libfinance 服务取一张短期票据去连行情网关,到期前自动续期,订阅不中断。 没登录时按IP给一份基础额度(可订阅的合约数、市场、连接数、每秒消息数);登录后按账号等级给更大的额度。
重要
订阅要写在 ``on_rsp_login`` 里。
网关断线后客户端会自动重连并重新登录,登录成功会再次触发 on_rsp_login——
订阅写在这里,重连后会自动重放,断线期间的数据按序号补发、不重不漏。写在主流程里的话,断线重连之后订阅就悄悄没了,
程序还在跑,只是再也收不到数据。
这是这套订阅接口约定的用法,不是可选的风格问题。
订阅的两种模式#
模式 |
行为 |
|---|---|
不指定 |
网关按健康状况和优先级自动选源,源掉线自动切换到备用源 |
指定 |
只接收该源的数据,不自动切换;该源不可用时明确失败 |
同一个合约在网关侧只有一条路由,不能同时混用两种模式,冲突的请求会在
on_rsp_subscribe 里明确失败。
行情帧本身不带来源信息。要知道数据来自哪个源,看订阅回执的 rsp.source,或者用
query_sources() 查源目录。
Quote 有哪些字段#
字段 |
含义 |
|---|---|
|
证券代码,如 |
|
行情时间戳 |
|
最新价 |
|
今开、最高、最低、收盘 |
|
昨收 |
|
成交量、成交额 |
|
涨停价、跌停价 |
|
买十档、卖十档价格,均为长度 10 的列表 |
|
对应档位的量 |
|
委买、委卖总量 |
|
成交笔数 |
|
交易阶段 |
|
期货与基金相关字段,股票上通常为 0 |
警告
回调是在后台的接收线程里执行的。不要在回调里做耗时操作——那会阻塞整条行情流。 重活扔进队列,交给另一个线程处理。
可直接运行的完整示例见 接收实时行情。