Day 10 - Subscribe 订阅盘中报价资讯(Stocks)

本篇重点

  • api.quote.subscribe简介
  • 订阅个股盘中tick资讯
  • 订阅个股盘中bidask资讯

api.quote.subscribe简介

官方说明文件:https://sinotrade.github.io/tutor/market_data/streaming/stocks/
对於程序交易,会需要在盘中的时候取得盘中的报价或成交资讯。虽然在盘中,也是可以用snapshots或kbars来取得盘中资讯,但在取得这类资讯时,不管对服务器端或是客户端,都是比较占用资源的。透过subscribe,你可以订阅多个金融商品的报价或成交资讯,也可以针对回传的内容,撰写对应的执行动作(程序)。
另外,跟其它报价资讯相比,目前subscribe是一个连线最多可以订阅200个内容。

api.quote.subscribe(
    contract: shioaji.contracts.Contract, #contract金融商品资讯
    quote_type: shioaji.constant.QuoteType = <QuoteType.Tick: 'tick'>, #报价类型,预设为tick资料
    intraday_odd: bool = False, #盘中零股,预设为False,即现股资料
    version: shioaji.constant.QuoteVersion = <QuoteVersion.v0: 'v0'>, #报价资讯类型,预设为v0版
)

若要取消订阅,可呼叫api.quote.unsubscribe,使用方式及参数与subscribe相同

subscribe在使用上,stock跟future没有差别,但在回传的资讯上有些微的不同,所以此部份会把stock跟future分开说明,此篇先说明stock个股的部份。
而QuoteVersion有分v1和v0版,v0版是简易的报价内容,v1版是详细的报价内容,以下也会分别说明v0版及v1版的使用方式及报价内容。

订阅个股盘中tick资讯

如同之前所介绍的,tick是指成交的报价内容,所以只要有成交,就会回传一笔资料。
订阅个股盘中tick v1版报价资讯,范例如下:

from shioaji import TickSTKv1, Exchange #从shioaji模组,汇入TickSTKv1及Exchange物件
from threading import Event #threading模组,汇入Event物件
#订阅个股盘中tick资讯
api.quote.subscribe(
    api.Contracts.Stocks["2330"], 
    quote_type = sj.constant.QuoteType.Tick, # or 'tick'
    version = sj.constant.QuoteVersion.v1 # or 'v1'
)

Event().wait() #盘中执行程序时,若看不到quote_callback的执行结果,请加入此行
# 定义quote_callback,即回传报价资讯时所要执行的动作
@api.on_tick_stk_v1()
def quote_callback(exchange: Exchange, tick:TickSTKv1):
    print(f"Exchange: {exchange}, Tick: {tick}") #将报价资讯内容输出至console中

Tick QuoteVersion.v1,quote_callback的执行结果

Exchange.TSE Tick(code='2330', datetime=datetime.datetime(2021, 9, 24, 11, 19, 42, 535354), open=Decimal('591'), avg_price=Decimal('593.06'), close=Decimal('596'), high=Decimal('597'), low=Decimal('590'), amount=Decimal('596000'), total_amount=Decimal('5626423000'), volume=1, total_volume=9487, tick_type=1, chg_type=2, price_chg=Decimal('8'), pct_chg=Decimal('1.36'), bid_side_total_vol=7328, ask_side_total_vol=2159, bid_side_total_cnt=1654, ask_side_total_cnt=489, closing_oddlot_shares=0, fixed_trade_vol=0, suspend=0, simtrade=0, intraday_odd=0)

Tick QuoteVersion.v1的报价内容说明

属性 说明
code '2330' 股票代码
datetime datetime.datetime(2021, 9, 24, 11, 19, 42, 535354) 时间
open Decimal('591') 开盘
avg_price Decimal('593.06') 均价
close Decimal('596') 成交价
high Decimal('597') 最高
low Decimal('590') 最低
amount Decimal('596000') 成交金额
total_amount Decimal('5626423000') 总成交金额
volume 1 成交量
total_volume 9487 总成交量
tick_type 1 tick类型
chg_type 2 变动类型
price_chg Decimal('8') 变动金额
pct_chg Decimal('1.36') 变动百分比
bid_side_total_vol 7328 买盘成交总量,单位:张
ask_side_total_vol 2159 卖盘成交总量,单位:张
bid_side_total_cnt 1654 买盘成交笔数
ask_side_total_cnt 489 卖盘成交笔数
closing_oddlot_shares 0 盘後零股成交股数
fixed_trade_vol 0 盘後定价成交量
suspend 0 是否为暂停交易
simtrade 0 是否为试撮
intraday_odd 0 是否为盘中零股

订阅个股盘中tick v0版报价资讯,范例如下:

api.quote.subscribe(
    api.Contracts.Stocks["2330"], 
    quote_type = sj.constant.QuoteType.Tick, # 报价类型为Tick
    version = sj.constant.QuoteVersion.v0 # 回传资讯版本为v0
)
# 定义quote_callback,即回传报价资讯时所要执行的动作
@api.quote.on_quote
def quote_callback(topic: str, quote: dict):
    print(f"Topic: {topic}, Quote: {quote}")

Tick QuoteVersion.v0,quote_callback的执行结果

MKT/idcdmzpcr01/TSE/2330 {'AmountSum': [5641317000.0], 'Close': [596.0], 'Date': '2021/09/24', 'TickType': [1], 'Time': '11:23:30.154501', 'VolSum': [9512], 'Volume': [2]}

Tick QuoteVersion.v0的报价内容说明

属性 说明
AmountSum [5641317000.0] 总成交金额
Close [596.0] 成交价
Date '2021/09/24' 日期
TickType [1] Tick类型
Time '11:23:30.154501' 时间
VolSum [9512] 总成交量
Volume [2] 成交量

订阅个股盘中bidask资讯

bidask是指委买委卖的资讯,也就是看盘软件中最佳五档的资料内容
订阅个股盘中bidask v1版报价资讯,范例如下:

api.quote.subscribe(
    api.Contracts.Stocks["2330"], 
    quote_type = sj.constant.QuoteType.BidAsk, #报价类型为BidAsk
    version = sj.constant.QuoteVersion.v1 # 回传资讯版本为v1
)
Event().wait()
# 定义quote_callback,即回传报价资讯时所要执行的动作
@api.on_bidask_stk_v1()
def quote_callback(exchange: Exchange, bidask:BidAskSTKv1):
    print(f"Exchange: {exchange}, BidAsk: {bidask}")

BidAsk QuoteVersion.v1,quote_callback的执行结果

Exchange.TSE BidAsk(code='2330', datetime=datetime.datetime(2021, 9, 24, 11, 27, 11, 42526), bid_price=[Decimal('595'), Decimal('594'), Decimal('593'), Decimal('592'), Decimal('591')], bid_volume=[405, 245, 746, 454, 260], diff_bid_vol=[0, 0, 0, 0, 0], ask_price=[Decimal('596'), Decimal('597'), Decimal('598'), Decimal('599'), Decimal('600')], ask_volume=[121, 364, 359, 415, 657], diff_ask_vol=[-1, 0, 0, 0, 0], suspend=0, simtrade=0, intraday_odd=0)

Tick QuoteVersion.v1的报价内容说明

属性 说明
code '2330' 股票代码
datetime datetime.datetime(2021, 9, 24, 11, 27, 11, 42526) 时间
bid_price [Decimal('595'), Decimal('594'), Decimal('593'), Decimal('592'), Decimal('591')] 委买价
bid_volume [405, 245, 746, 454, 260] 委买量
diff_bid_vol [0, 0, 0, 0, 0] 委买量差异(增减)
ask_price [Decimal('596'), Decimal('597'), Decimal('598'), Decimal('599'), Decimal('600')] 委卖价
ask_volume [121, 364, 359, 415, 657] 委卖量
diff_ask_vol [-1, 0, 0, 0, 0] 委卖量差异(增减)
suspend 0 是否为暂停交易
simtrade 0 是否为试撮
intraday_odd 0 是否为盘中零股

订阅个股盘中bidask v0版报价资讯,范例如下:

api.quote.subscribe(
    api.Contracts.Stocks["2330"], 
    quote_type = sj.constant.QuoteType.BidAsk, #报价类型为BidAsk
    version = sj.constant.QuoteVersion.v0 # 回传资讯版本为v0
)
Event().wait()
@api.quote.on_quote
def quote_callback(topic: str, quote: dict):
    print(f"Topic: {topic}, Quote: {quote}")

BidAsk QuoteVersion.v0,quote_callback的执行结果

QUT/idcdmzpcr01/TSE/2330 {'AskPrice': [596.0, 597.0, 598.0, 599.0, 600.0], 'AskVolume': [124, 381, 358, 416, 656], 'BidPrice': [595.0, 594.0, 593.0, 592.0, 591.0], 'BidVolume': [407, 246, 745, 454, 260], 'Date': '2021/09/24', 'Time': '11:28:01.797097'}

Tick QuoteVersion.v0的报价内容说明

属性 说明
AskPrice [596.0, 597.0, 598.0, 599.0, 600.0] 委卖价
AskVolume [124, 381, 358, 416, 656] 委卖量
BidPrice [595.0, 594.0, 593.0, 592.0, 591.0] 委买价
BidVolume [407, 246, 745, 454, 260] 委买量
Date '2021/09/24' 日期
Time '11:28:01.797097' 时间

<<:  【PHP Telegram Bot】Day16 - 基础(5):档案读取与写入、cURL

>>:  DAY25 搞样式--用CSS Gird来搞个万年历吧(下)

RWD
杂谈    

[Day04] 空降主管的战地生存术

在一场由执行长主持的月会上,HR 念了一个同事提出的疑问:「公司对工程师的面试标准这麽高,却对管理职...

第 53 天 - 研究 shell 解释器 - for each 批量停用没有用到服务

今天进度 : 鸟哥的 Linux 私房菜 -- 区域网路的环境设定 测试开放外网的时候,使用 net...

Day11回圈(Ⅰ)

当我们需要程序1.重复执行2.判断对错就需要用到回圈,像是算面积,算完一个想再算一个可以利用回圈让使...

Day 07:我今天想不到标题之整合 tmux 和 zsh

我把从第一天到现在每天的 Home 目录都放上 GitHub 了,README.md 里面有说明 ...

[Day 30] 最後的行动装置

那个行动装置 虽然我们都概括说是手机版,但 Media Query 其实支援更多装置的呈现,只是,应...