Market Data Subscription
Subscription and callback data format currently supports two ways, Protobuf and STOMP, we recommend using Protobuf. The current version uses STOMP by default, and will switch to the default Protobuf method in future versions.
Modify the PushClient initialization parameter use_protobuf
, set to True to enable the Protobuf method: use_protobuf
, set to True to enable the Protobuf method:
push_client = PushClient(host, port, use_ssl=(protocol == 'ssl'), use_protobuf=True)
Protobuf
protocol version: proto3
Subscribe quote
PushClient.subscribe_quote(symbols)
Unsubscribe
PushClient.unsubscribe_quote(symbols)
Description
Stock quote subscription and cancellation interface, the returned data is updated in real time, that is, every time the price or pending order data update will have data pushed Callback interface returns the result type for the basic quote QuoteBasicData (tigeropen.push.pb.QuoteBasicData_pb2.QuoteBasicData) object Best Quote QuoteBBOData (tigeropen.push.pb.QuoteBasicData_pb2.QuoteBBOData) object
this interface is returned asynchronously, using PushClient.quote_changed
in response to the basic quote QuoteBasicData object; Use PushClient.quote_bbo_changed
to respond to the best quote QuoteBBOData object
Agruments
Name | Type | Description |
---|---|---|
symbols | list[str] | list of securities codes, e.g. ['AAPL', 'BABA'], English codes should be in upper case |
Unsubscribe Arguments
Name | Type | Description |
---|---|---|
symbols | list[str] | list of securities codes, e.g. ['AAPL', 'BABA'] |
Return
Refer to:Quote change
CAUTION
There are two types of stock quote callback data: trading data and intraday data, and the fields returned by the two types of data are not the same
Example
from tigeropen.push.push_client import PushClient
from tigeropen.tiger_open_config import get_client_config
from tigeropen.push.pb.QuoteBBOData_pb2 import QuoteBBOData
from tigeropen.push.pb.QuoteBasicData_pb2 import QuoteBasicData
client_config = get_client_config(private_key_path='private key path', tiger_id='your tiger id', account='your account')
protocol, host, port = client_config.socket_host_port
push_client = PushClient(host, port, use_ssl=(protocol == 'ssl'), use_protobuf=True)
def on_quote_changed(frame: QuoteBasicData):
"""
"""
print(f'quote basic change: {frame}')
def on_quote_bbo_changed(frame: QuoteBBOData):
"""ask/bid
"""
print(f'quote bbo changed: {frame}')
# bind callback method
push_client.quote_changed = on_quote_changed
push_client.quote_bbo_changed = on_quote_bbo_changed
push_client.connect(client_config.tiger_id, client_config.private_key)
push_client.subscribe_quote(['AAPL', 'BABA'])
push_client.unsubscribe_quote(['AAPL', 'BABA'])
push_client.disconnect()
Callback data example
tigeropen.push.pb.QuoteBasicData_pb2.QuoteBasicData example:
symbol: "00700"
type: BASIC
timestamp: 1677742483530
serverTimestamp: 1677742483586
avgPrice: 365.37
latestPrice: 363.8
latestPriceTimestamp: 1677742483369
latestTime: "03-02 15:34:43"
preClose: 368.8
volume: 12674730
amount: 4630947968
open: 368.2
high: 369
low: 362.4
marketStatus: "Trading"
mi {
p: 363.8
a: 365.37
t: 1677742440000
v: 27300
h: 364
l: 363.6
}
tigeropen.push.pb.QuoteBasicData_pb2.QuoteBBOData Example:
symbol: "01810"
type: BBO
timestamp: 1677741267291
serverTimestamp: 1677741267329
askPrice: 12.54
askSize: 397600
askTimestamp: 1677741266304
bidPrice: 12.52
bidSize: 787400
bidTimestamp: 1677741266916
Subscribe depth quote
Push_client.subscribe_depth_quote(symbols)
Unsubscribe
PushClient.unsubscribe_depth_quote(symbols)
Description
Subscribe to depth quotes, ** U.S. depth quotes push frequency of 300ms, Hong Kong depth quotes push frequency of 2s, return up to 40 files of pending buy and sell orders data **, the data returned for real-time updates, that is, pending orders data updates will have data pushed. This interface is asynchronous return, using PushClient.quote_depth_changed
response depth quotes QuoteDepthData (tigeropen.push.pb.QuoteDepthData_pb2.QuoteDepthData) object;
Arguments
Name | Type | Description |
---|---|---|
symbols | list[str] | list of symbols,such as ['AAPL', 'BABA'] |
Unsubscribe Arguments
Name | Type | Description |
---|---|---|
symbols | list[str] | list of symbols,such as ['AAPL', 'BABA'] |
Example
from tigeropen.push.push_client import PushClient
from tigeropen.tiger_open_config import get_client_config
client_config = get_client_config(private_key_path='private key path', tiger_id='your tiger id', account='your account')
# Initialize PushClient
protocol, host, port = client_config.socket_host_port
push_client = PushClient(host, port, use_ssl=(protocol == 'ssl'), use_protobuf=True)
def on_quote_depth_changed(frame: QuoteDepthData):
print(f'quote depth changed: {frame}')
push_client.quote_depth_changed = on_quote_depth_changed
push_client.connect(client_config.tiger_id, client_config.private_key)
push_client.subscribe_depth_quote(['AMD', 'MSFT'])
push_client.unsubscribe_depth_quote(['AMD', 'MSFT'])
push_client.disconnect()
Callback Data Example
tigeropen.push.pb.QuoteDepthData_pb2.QuoteDepthData
CAUTION
This interface will only push a maximum of the first 40 ask/bid
data structure:
Field | Type | Description |
---|---|---|
symbol | str | symbol |
timestamp | int | depth quote time |
ask | OrderBook | ask data |
bid | OrderBook | bid data |
OrderBook structure:
Field | Type | Description |
---|---|---|
price | list[float] | price |
volume | list[int] | order volume |
orderCount | list[int] | order count(HK stock only) |
Callback data example
depth quote items example,The price of adjacent slots may be the same, where count is optional
symbol: "00700"
timestamp: 1677742734822
ask {
price: 363.8
price: 364
price: 364.2
price: 364.4
price: 364.6
price: 364.8
price: 365
price: 365.2
price: 365.4
price: 365.6
volume: 26900
volume: 14800
volume: 15200
volume: 31500
volume: 15800
volume: 7700
volume: 29400
volume: 6300
volume: 6000
volume: 5500
orderCount: 27
orderCount: 20
orderCount: 19
orderCount: 22
orderCount: 14
orderCount: 10
orderCount: 20
orderCount: 12
orderCount: 10
orderCount: 11
}
bid {
price: 363.6
price: 363.4
price: 363.2
price: 363
price: 362.8
price: 362.6
price: 362.4
price: 362.2
price: 362
price: 361.8
volume: 9400
volume: 19900
volume: 35300
volume: 74200
volume: 26300
volume: 16700
volume: 22500
volume: 21100
volume: 40500
volume: 5600
orderCount: 16
orderCount: 23
orderCount: 36
orderCount: 79
orderCount: 30
orderCount: 32
orderCount: 31
orderCount: 34
orderCount: 143
orderCount: 26
}
Subscribe tick
Push_client.subscribe_tick(symbols)
Unsubscribe
PushClient.unsubscribe_tick(symbols)
Description
The transaction-by-transaction subscription push interface is an asynchronous interface, and the results of asynchronous requests can be obtained by implementing the PushClient.tick_changed interface. The callback data type is tigeropen.push.pb.TradeTickData_pb2.TradeTickData This method is used for both stocks and futures.
Push frequency is 200ms, using snapshot push, each time pushing the latest 50 records per tick.
Arguments
Name | Type | Description |
---|---|---|
symbols | list[str] | list of symbols,like ['AAPL', 'BABA'] |
Unsubscribe Arguments
Name | Type | Description |
---|---|---|
symbols | list[str] | list of symbols, like ['AAPL', 'BABA'] |
Example
from tigeropen.push.pb.trade_tick import TradeTick
from tigeropen.push.push_client import PushClient
from tigeropen.tiger_open_config import get_client_config
client_config = get_client_config(private_key_path='private key path', tiger_id='your tiger id', account='your account')
protocol, host, port = client_config.socket_host_port
push_client = PushClient(host, port, use_ssl=(protocol == 'ssl'), use_protobuf=True)
def on_tick_changed(frame: TradeTick):
print(f'tick changed: {frame}')
push_client.tick_changed = on_tick_changed
push_client.connect(client_config.tiger_id, client_config.private_key)
# subscribe stock
push_client.subscribe_tick(['AMD', 'MSFT'])
# subscribe future
push_client.subscribe_tick(['HSImain', 'CNmain'])
time.sleep(10)
push_client.unsubscribe_tick(['AMD', 'MSFT'])
push_client.disconnect()
Callback data tigeropen.push.pb.trade_tick.TradeTick
TradeTick data structure:
Field | Type | Description |
---|---|---|
symbol | str | stock or future code |
secType | str | STK/FUT |
quoteLevel | str | The level of authority of the ticker from which the data comes (for US stocks, usQuoteBasic has less data per tick than usStockQuote); there is no level distinction for futures |
timestamp | int | timestamp in millisecond |
ticks | list[TradeTickItem] | tick data list |
ticks data structure:
Field | Type | Description |
---|---|---|
sn | int | serial number |
volume | int | volume |
tickType | str | * means no change, + means up, - means down (not available for futures) |
price | double | transaction price |
time | int | transaction time stamp |
cond | str | The list of transaction conditions for each data, if the array is empty, it means that each transaction of the current batch is an automatic transaction (futures are not available on a per-transaction basis) |
partCode | str | Exchange code of each transaction (US stocks only) |
partName | str | Exchange name of each transaction (U.S. stocks only) |
Callback Example
TradeTick<{'symbol': '00700', 'sec_type': 'STK', 'quote_level': 'hkStockQuoteLv2', 'timestamp': 1685602618145, 'ticks': [TradeTickItem<{'tick_type': '+', 'price': 316.6, 'volume': 100, 'part_code': None, 'part_code_name': None, 'cond': None, 'time': 1685602617046, 'sn': 42055}>, TradeTickItem<{'tick_type': '-', 'price': 316.4, 'volume': 600, 'part_code': None, 'part_code_name': None, 'cond': None, 'time': 1685602617639, 'sn': 42056}>, TradeTickItem<{'tick_type': '-', 'price': 316.4, 'volume': 200, 'part_code': None, 'part_code_name': None, 'cond': None, 'time': 1685602617639, 'sn': 42057}>]}>
Subscribe full tick
Push_client.subscribe_tick(symbols)
Unsubscribe
PushClient.unsubscribe_tick(symbols)
Description
The full-tick subscription push interface is an asynchronous interface, and the results of asynchronous requests can be obtained by implementing the PushClient.tick_changed interface. The callback data type is tigeropen.push.pb.TickData_pb2.TickData
Arguments
Name | Type | Description |
---|---|---|
symbols | list[str] | list of symbols,like ['AAPL', 'BABA'] |
At the same time, change the configuration client_config.use_full_tick = True
, enable full tick mode, and pass in client_config=client_config
when PushClient
is initialized.
Unsubscribe Arguments
Name | Type | Description |
---|---|---|
symbols | list[str] | list of symbols, like ['AAPL', 'BABA'] |
Example
from tigeropen.push.pb.TickData_pb2 import TickData
from tigeropen.push.push_client import PushClient
from tigeropen.tiger_open_config import get_client_config
client_config = get_client_config(private_key_path='private key path', tiger_id='your tiger id', account='your account')
client_config.use_full_tick = True
# init PushClient
protocol, host, port = client_config.socket_host_port
push_client = PushClient(host, port, use_ssl=(protocol == 'ssl'), use_protobuf=True, client_config=client_config)
def on_full_tick_changed(frame: TickData):
print(f'full tick changed: {frame}')
push_client.full_tick_changed = on_full_tick_changed
push_client.connect(client_config.tiger_id, client_config.private_key)
push_client.subscribe_tick(['AMD', 'MSFT', '00700'])
time.sleep(10)
push_client.unsubscribe_tick(['AMD', 'MSFT'])
push_client.disconnect()
Callback data tigeropen.push.pb.TickData_pb2.TickData
TickData data structure:
field | type | desc |
---|---|---|
symbol | str | security code |
source | str | STK/FUT |
timestamp | int | data timestamp |
ticks | list[Tick] | tick datas |
each item of ticks data structure:
Field | Type | Description |
---|---|---|
sn | int | serial number |
volume | int | volume |
type | str | * means no change, + means up, - means down (not available for futures) |
price | double | transaction price |
time | int | transaction time stamp |
partCode | str | Exchange code of each transaction (US stocks only) |
Example
symbol: "NVDA"
ticks {
sn: 2381
time: 1712669401076
price: 874.1
volume: 10
type: "*"
partCode: "t"
}
ticks {
sn: 2382
time: 1712669401076
price: 874.1
volume: 11
type: "*"
partCode: "t"
}
ticks {
sn: 2383
time: 1712669401076
price: 874.1
volume: 3
type: "*"
partCode: "t"
}
timestamp: 1712669403808
source: "NLS"
Subscribe kline
PushClient.subscribe_kline(symbols=None)
Unsubscribe
PushClient.unsubscribe_kline(symbols)
Description Subscribe to minute kline.
Parameters
Field | Type | Description |
---|---|---|
symbols | list[str] | list of security codes |
Callback data Need to use PushClient.kline_changed
to respond to the return result
Example
from tigeropen.push.push_client import PushClient
from tigeropen.tiger_open_config import get_client_config
client_config = get_client_config(private_key_path='private key path', tiger_id='your tiger id', account='your account')
protocol, host, port = client_config.socket_host_port
push_client = PushClient(host, port, use_ssl=(protocol == 'ssl'), use_protobuf=True)
def on_kline_changed(frame: KlineData):
print(f'kline changed: {frame}')
push_client.kline_changed = on_kline_changed
push_client.connect(client_config.tiger_id, client_config.private_key)
symbols = ['AAPL']
push_client.subscribe_kline(symbols)
Callback Example
{
"time":"1712584560000",
"open":168.9779,
"high":169.0015,
"low":168.9752,
"close":169.0,
"avg":168.778,
"volume":"3664",
"count":114,
"symbol":"AAPL",
"amount":617820.6508,
"serverTimestamp":"1712584569746"
}
Query Subscribed Symbols
PushClient.query_subscribed_quote()
Description Query the list of subscribed labels
This interface is asynchronous return, you need to use PushClient.query_subscribed_callback
response to return the results
Arguments None
Callback data Need to use PushClient.query_subscribed_callback
to respond to the return result
The callback data structure is as follows:
Field | Type | Description |
---|---|---|
limit | int | Maximum number of subscribed tickers (stocks, options, futures) |
used | int | Number of subscribed tickers (stocks, options, futures) |
subscribedSymbols | list | subscribedSymbols (stocks, options, futures) |
askBidLimit | int | subscribed to the depth of the stock limit maximum number |
askBidUsed | int | Number of subscribed stocks |
subscribedAskBidSymbols | list | subscribed deep ticker symbols |
tradeTickLimit | int | subscribed to the maximum number of trade-by-trade stock limits |
tradeTickUsed | int | subscribedAskBidSymbols |
subscribedTradeTickSymbols | list | subscribed trade-by-trade stock symbols |
Example
from tigeropen.push.push_client import PushClient
from tigeropen.tiger_open_config import get_client_config
client_config = get_client_config(private_key_path='private key path', tiger_id='your tiger id', account='your account')
protocol, host, port = client_config.socket_host_port
push_client = PushClient(host, port, use_ssl=(protocol == 'ssl'), use_protobuf=True)
def query_subscribed_callback(data):
"""
data example:
{'subscribed_symbols': ['QQQ'], 'limit': 1200, 'used': 1, 'symbol_focus_keys': {'qqq': ['open', 'prev_close', 'low', 'volume', 'latest_price', 'close', 'high']},
'subscribed_quote_depth_symbols': ['NVDA'], 'quote_depth_limit': 20, 'quote_depth_used': 1,
'subscribed_trade_tick_symbols': ['QQQ', 'AMD', '00700'], 'trade_tick_limit': 1200, 'trade_tick_used': 3}
"""
print(f'subscribed data:{data}')
print(f'subscribed symbols:{data["subscribed_symbols"]}')
push_client.query_subscribed_callback = query_subscribed_callback
push_client.connect(client_config.tiger_id, client_config.private_key)
push_client.subscribe_quote(['QQQ'])
push_client.subscribe_depth_quote(['NVDA'])
push_client.subscribe_tick(['QQQ'])
push_client.subscribe_tick(['HSImain'])
push_client.query_subscribed_quote()
time.sleep(10)
Callback Example
{'subscribed_symbols': ['QQQ'], 'limit': 1200, 'used': 1,
'subscribed_ask_bid_symbols': ['NVDA'], 'ask_bid_limit': 20, 'ask_bid_used': 1,
'subscribed_trade_tick_symbols': ['QQQ', 'AMD', '00700'], 'trade_tick_limit': 1200, 'trade_tick_used': 3
}
Subscribe Option Quote
Arguments
Name | Type | Description |
---|---|---|
symbols | list[str] | consists of four elements of the option, separated by spaces: underlying code, expiration date (YYYYMMDD), strike price, and option type (call CALL/put PUT) |
Callback Data
Need to bind the callback method through push_client.quote_changed
, the callback method is the same as the stock
Examplepush_client.subscribe_option(['AAPL 20230120 150.0 CALL', 'SPY 20220930 470.0 PUT'])
or push_client.subscribe_quote(['AAPL 20230120 150.0 CALL', 'SPY 20220930 470.0 PUT'])
from tigeropen.push.push_client import PushClient
from tigeropen.tiger_open_config import get_client_config
client_config = get_client_config(private_key_path='private key path', tiger_id='your tiger id', account='your account')
protocol, host, port = client_config.socket_host_port
push_client = PushClient(host, port, use_ssl=(protocol == 'ssl'), use_protobuf=True)
def on_quote_changed(frame: QuoteBasicData):
"""
"""
print(f'quote basic change: {frame}')
def on_quote_bbo_changed(frame: QuoteBBOData):
"""ask/bid
"""
print(f'quote bbo changed: {frame}')
push_client.quote_changed = on_quote_changed
push_client.quote_bbo_changed = on_quote_bbo_changed
push_client.connect(client_config.tiger_id, client_config.private_key)
push_client.subscribe_option(['AAPL 20240119 155.0 PUT', 'SPY 20221118 386.0 CALL'])
push_client.unsubscribe_quote(['AAPL 20240119 155.0 PUT', 'SPY 20221118 386.0 CALL'])
push_client.disconnect()
Subscribe Future Quote
Arguments
name | type | description |
---|---|---|
symbols | list[str] | future code list,like 'CLmain', 'ES2209' |
Callback data
Need to bind callback method through push_client.quote_changed
Example
push_client.subscribe_future(['CLmain', 'CN2209'])
# or
push_client.subscribe_quote(['VIXmain', 'ES2209'])
from tigeropen.push.push_client import PushClient
from tigeropen.tiger_open_config import get_client_config
client_config = get_client_config(private_key_path='private key path', tiger_id='your tiger id', account='your account')
protocol, host, port = client_config.socket_host_port
push_client = PushClient(host, port, use_ssl=(protocol == 'ssl'), use_protobuf=True)
def on_quote_changed(frame: QuoteBasicData):
"""
"""
print(f'quote basic change: {frame}')
def on_quote_bbo_changed(frame: QuoteBBOData):
"""ask/bid
"""
print(f'quote bbo changed: {frame}')
push_client.quote_changed = on_quote_changed
push_client.quote_bbo_changed = on_quote_bbo_changed6
push_client.connect(client_config.tiger_id, client_config.private_key)
push_client.subscribe_future(['BTCmain', 'CLmain'])
push_client.unsubscribe_quote(['BTCmain', 'CLmain'])
push_client.disconnect()
Callback data example basic quote
symbol: "BTCmain"
type: BASIC
timestamp: 1677571147018
avgPrice: 23562.4
latestPrice: 23355
latestPriceTimestamp: 1677571045000
latestTime: "02-28 01:57:25 -0600"
preClose: 23445
volume: 900
open: 23585
high: 23710
low: 23350
marketStatus: ""
tradeTime: 1677571045000
preSettlement: 23445
minTick: 5
mi {
p: 23355
a: 23562.4
t: 1677571020000
v: 3
o: 23350
h: 23355
l: 23350
}
ask bid
symbol: "BTCmain"
type: BBO
timestamp: 1677571147018
askPrice: 23365
askSize: 3
askTimestamp: 1677571147018
bidPrice: 23355
bidSize: 1
bidTimestamp: 1677571141150
Subscribe to stock top data
PushClient.subscribe_stock_top(market, indicators=None)
Unsubscribe methodPushClient.unsubscribe_stock_top(market, indicators=None)
Description
Subscribe to stock top data, no push during non-trading hours, push interval is 30s, each push subscribes to indicators Top30 underlying data. The push interface is an asynchronous callback, and the result of asynchronous request can be obtained by implementing the ApiComposeCallback interface. The callback interface returns the result type as StockTopData
object. The data of each indicator is sorted in reverse order by indicator value.
Support the subscription of stock indicators in the US and Hong Kong markets. The top of intraday data has all indicators of StockRankingIndicator, and the top data of only two indicators of US stocks before and after the market is up (changeRate) and up in 5 minutes (changeRate5Min)
Parameters
Parameter Name | Type | Required | Description |
---|---|---|---|
market | str or Market enum | Yes | Market, support HK, US |
indicators | list[tigeropen.common.consts.StockRankingIndicator] | No | StockRankingIndicator, default is all indicators, refer to the enumeration StockRankingIndicator's value (changeRate:day increase. changeRate5Min:5-minute increase; turnoverRate:turnover rate; amount:current day volume; volume:current day volume; amplitude:current day amplitude) |
Callback data
Need to bind the callback method via push_client.stock_top_changed
The data structure of StockTopData is as follows:
Field | Type | Description |
---|---|---|
market | str | market:US/HK |
timestamp | int | timestamp |
topData | list[TopData] | List of data for each indicator list |
The data structure of TopData is as follows:
field | type | description |
---|---|---|
targetName | str | indicatorName(changeRate, changeRate5Min, turnoverRate, amount, volume, amplitude) |
item | list[StockItem] | A list of the list data under this indicator dimension |
The data structure of StockItem is as follows:
field | type | description |
---|---|---|
symbol | str | marked |
latestPrice | float | The latest price |
targetValue | float | Corresponding indicator value |
Example
from tigeropen.push.push_client import PushClient
from tigeropen.tiger_open_config import get_client_config
from tigeropen.common.consts import OptionRankingIndicator, StockRankingIndicator
from tigeropen.push.pb.StockTopData_pb2 import StockTopData
client_config = get_client_config(private_key_path='private key path', tiger_id='your tiger id', account='your account')
protocol, host, port = client_config.socket_host_port
push_client = PushClient(host, port, use_ssl=(protocol == 'ssl'))
def on_stock_top_changed(frame: StockTopData):
print(f'stock top changed: {frame}')
push_client.stock_top_changed = on_stock_top_changed
push_client.connect(client_config.tiger_id, client_config.private_key)
push_client.subscribe_stock_top("HK", [StockRankingIndicator.Amount])
push_client.unsubscribe_stock_top("HK", [StockRankingIndicator.Amount])
Callback Data Example
topData {
targetName: "amount"
item {
symbol: "02800"
latestPrice: 19.55
targetValue: 3338633741
}
item {
symbol: "00700"
latestPrice: 338.8
targetValue: 2950736047
}
item {
symbol: "02828"
latestPrice: 66.34
targetValue: 1533436182
}
item {
symbol: "09988"
latestPrice: 85.2
targetValue: 1396707122
}
item {
symbol: "02269"
latestPrice: 37.1
targetValue: 1238930730
}
item {
symbol: "03690"
latestPrice: 127.9
targetValue: 1167532142
}
item {
symbol: "01211"
latestPrice: 262.6
targetValue: 716540400
}
item {
symbol: "03033"
latestPrice: 3.916
targetValue: 629691374
}
item {
symbol: "01357"
latestPrice: 3.29
targetValue: 589222680
}
item {
symbol: "02318"
latestPrice: 50.25
targetValue: 572686837
}
item {
symbol: "01299"
latestPrice: 80.25
targetValue: 510098294
}
item {
symbol: "09888"
latestPrice: 139.7
targetValue: 504564066
}
item {
symbol: "00388"
latestPrice: 303.8
targetValue: 488918091
}
item {
symbol: "07226"
latestPrice: 4.85
targetValue: 477161727
}
item {
symbol: "01398"
latestPrice: 4.16
targetValue: 459215853
}
item {
symbol: "02331"
latestPrice: 43.2
targetValue: 439082885
}
item {
symbol: "02015"
latestPrice: 137.8
targetValue: 407068273
}
item {
symbol: "09618"
latestPrice: 143.9
targetValue: 389690725
}
item {
symbol: "07552"
latestPrice: 6.59
targetValue: 387550625
}
item {
symbol: "01024"
latestPrice: 54.85
targetValue: 350567971
}
item {
symbol: "00981"
latestPrice: 20.65
targetValue: 349594737
}
item {
symbol: "00386"
latestPrice: 4.47
targetValue: 347819789
}
item {
symbol: "00883"
latestPrice: 11.12
targetValue: 320431605
}
item {
symbol: "09868"
latestPrice: 44.05
targetValue: 292605044
}
item {
symbol: "02020"
latestPrice: 81.95
targetValue: 285153726
}
item {
symbol: "03968"
latestPrice: 36.25
targetValue: 273604906
}
item {
symbol: "00939"
latestPrice: 5.05
targetValue: 270755731
}
item {
symbol: "01088"
latestPrice: 23.6
targetValue: 265332533
}
item {
symbol: "00020"
latestPrice: 2.14
targetValue: 256621941
}
item {
symbol: "00941"
latestPrice: 63.25
targetValue: 248440129
}
}
Subscribe to option top data
PushClient.subscribe_option_top(market, indicators=None)
Unsubscribe methodPushClient.unsubscribe_option_top(market, indicators=None)
Description
Subscribe to the option's market top data,** no push during non-trading hours, push interval is 30s, each push subscribes to the data of the indicator Top50 underlying**. The push interface is an asynchronous callback, and the result of asynchronous request can be obtained by implementing the ApiComposeCallback interface. The return result type of the callback interface is OptionTopData
object. Among them, the variation of large orders is the data of single transaction volume greater than 1000, sorted in reverse order by transaction time, and the other indicator data is the data of cumulative indicator value in reverse order on trading days.
Support for subscription to the U.S. market options indicators, the intraday data list has OptionRankingIndicator all indicators.
Parameters
Parameter Name | Type | Required | Description |
---|---|---|---|
market | str or Market enum | Yes | Market, support HK, US |
indicators | list[tigeropen.common.consts.OptionRankingIndicator] | No | Options list indicators, default is all indicators, refer to the value of the enumeration OptionRankingIndicator (bigOrder:Variable big order. volume:cumulative volume for the day, amount:cumulative volume for the day, openInt:open position) |
Callback data
The callback method should be bound by push_client.option_top_changed
.
The OptionTopData data structure is as follows:
Field | Type | Description |
---|---|---|
market | string | market:US |
timestamp | long | timestamp |
topData | list[TopData] | List of data for each indicator list |
The data structure of TopData is as follows:
field | type | description |
---|---|---|
targetName | string | Indicator name(bigOrder, volume, amount, openInt) |
bigOrder | list[BigOrder] | The list of variance bigOrder indicators (bigOrder) data |
item | list[OptionItem] | The list of data under this indicator dimension |
The data structure of BigOrder is as follows:
field | type | description |
---|---|---|
symbol | str | Stock ETF Underlying |
expiry | str | Expiration date, format: yyyyMMdd |
strike | str | Strike |
right | str | CALL/PUT |
dir | str | Buy/Sell direction: BUY/SELL/NONE |
volume | float | volume |
price | float | volume |
amount | float | volume |
tradeTime | int | transaction timestamp |
The data structure of OptionItem is as follows:
field | type | description |
---|---|---|
symbol | str | Stock ETF Underlying |
expiry | str | Expiration date, format: yyyyMMdd |
strike | str | Strike |
right | str | CALL/PUT |
totalAmount | float | volume |
totalVolume | float | volume |
totalOpenInt | float | open position volume |
volumeToOpenInt | float | Volume/open position |
latestPrice | float | Latest Price |
updateTime | int | Indicator data update timestamp |
Examples
from tigeropen.push.push_client import PushClient
from tigeropen.tiger_open_config import get_client_config
from tigeropen.common.consts import OptionRankingIndicator
from tigeropen.push.pb.OptionTopData_pb2 import OptionTopData
client_config = get_client_config(private_key_path='private key path', tiger_id='your tiger id', account='your account')
# Initialize PushClient
protocol, host, port = client_config.socket_host_port
push_client = PushClient(host, port, use_ssl=(protocol == 'ssl'))
# Define the callback method
def on_option_top_changed(frame: OptionTopData).
print(f'option top changed: {frame}')
# Binding callback method
push_client.option_top_changed = on_option_top_changed
# Establish a connection
push_client.connect(client_config.tiger_id, client_config.private_key)
# Subscribe
push_client.subscribe_option_top("US", [OptionRankingIndicator.Amount])
# Unsubscribe
push_client.unsubscribe_option_top("US", [OptionRankingIndicator.Amount])
Callback data example
{
"market":"US",
"timestamp":"1687277160445",
"topData":[
{
"targetName":"volume",
"item":[
{
"symbol":"SPY",
"expiry":"20230620",
"strike":"435.0",
"right":"PUT",
"totalAmount":5394115,
"totalVolume":212478,
"totalOpenInt":16377,
"volumeToOpenInt":0.012467,
"latestPrice":0.25,
"updateTime":"1687277254390"
},
{
"symbol":"SPY",
"expiry":"20230620",
"strike":"436.0",
"right":"PUT",
"totalAmount":7754077,
"totalVolume":194423,
"totalOpenInt":13403,
"volumeToOpenInt":0.011408,
"latestPrice":0.58,
"updateTime":"1687277213603"
},
{
"symbol":"SPY",
"expiry":"20230620",
"strike":"437.0",
"right":"PUT",
"totalAmount":10420625,
"totalVolume":182078,
"totalOpenInt":13973,
"volumeToOpenInt":0.010683,
"latestPrice":1.17,
"updateTime":"1687277213602"
},
{
"symbol":"SPY",
"expiry":"20230620",
"strike":"438.0",
"right":"CALL",
"totalAmount":4482482,
"totalVolume":181899,
"totalOpenInt":961,
"volumeToOpenInt":0.010673,
"latestPrice":0.09,
"updateTime":"1687277213603"
},
{
"symbol":"SPY",
"expiry":"20230620",
"strike":"436.0",
"right":"CALL",
"totalAmount":7331667,
"totalVolume":150604,
"totalOpenInt":238,
"volumeToOpenInt":0.008837,
"latestPrice":0.66,
"updateTime":"1687277208599"
}
// ......
]
},
{
"targetName":"amount",
"item":[
{
"symbol":"TSLA",
"expiry":"20230721",
"strike":"5.0",
"right":"CALL",
"totalAmount":34061561,
"totalVolume":1812,
"totalOpenInt":18,
"volumeToOpenInt":0.00023,
"latestPrice":259.99,
"updateTime":"1687276953360"
},
{
"symbol":"TSLA",
"expiry":"20230721",
"strike":"500.0",
"right":"PUT",
"totalAmount":30877216,
"totalVolume":1960,
"volumeToOpenInt":0.000248,
"latestPrice":234.97,
"updateTime":"1687276953360"
},
{
"symbol":"TSLA",
"expiry":"20230623",
"strike":"265.0",
"right":"CALL",
"totalAmount":27928028,
"totalVolume":66361,
"totalOpenInt":12928,
"volumeToOpenInt":0.008405,
"latestPrice":6.5,
"updateTime":"1687277264395"
},
{
"symbol":"SPY",
"expiry":"20230721",
"strike":"420.0",
"right":"CALL",
"totalAmount":21629503,
"totalVolume":11105,
"totalOpenInt":46931,
"volumeToOpenInt":0.000652,
"latestPrice":19.27,
"updateTime":"1687273142271"
},
{
"symbol":"TSLA",
"expiry":"20230623",
"strike":"270.0",
"right":"CALL",
"totalAmount":17657903,
"totalVolume":61012,
"totalOpenInt":14302,
"volumeToOpenInt":0.007728,
"latestPrice":4.52,
"updateTime":"1687277254390"
}
// ......
]
},
{
"targetName":"openInt",
"item":[
{
"symbol":"AMC",
"expiry":"20230721",
"strike":"10.0",
"right":"CALL",
"totalAmount":4933,
"totalVolume":750,
"totalOpenInt":340843,
"volumeToOpenInt":0.00022,
"latestPrice":0.1,
"updateTime":"1687276788220"
},
{
"symbol":"AMC",
"expiry":"20230721",
"strike":"10.0",
"right":"PUT",
"totalVolume":1,
"totalOpenInt":321814,
"latestPrice":6.2,
"updateTime":"1687276853278"
},
{
"symbol":"AMC",
"expiry":"20230721",
"strike":"4.0",
"right":"PUT",
"totalAmount":117982,
"totalVolume":2748,
"totalOpenInt":242101,
"volumeToOpenInt":0.000806,
"latestPrice":0.81,
"updateTime":"1687277034280"
},
{
"symbol":"ATVI",
"expiry":"20240119",
"strike":"85.0",
"right":"PUT",
"totalAmount":3500,
"totalVolume":26,
"totalOpenInt":230702,
"volumeToOpenInt":0.000016,
"latestPrice":7,
"updateTime":"1687274092822"
},
{
"symbol":"EEM",
"expiry":"20231215",
"strike":"47.0",
"right":"CALL",
"totalAmount":310,
"totalVolume":15,
"totalOpenInt":183054,
"volumeToOpenInt":0.000003,
"latestPrice":0.18,
"updateTime":"1687269619956"
}
// ......
]
},
{
"targetName":"bigOrder",
"bigOrder":[
{
"symbol":"AMC",
"expiry":"20230818",
"strike":"10.0",
"right":"PUT",
"dir":"Buy",
"volume":1000,
"price":6.94,
"amount":694000,
"tradeTime":"1687276860753"
},
{
"symbol":"GLPI",
"expiry":"20230818",
"strike":"50.0",
"right":"CALL",
"dir":"Sell",
"volume":1094,
"price":1.2,
"amount":131280,
"tradeTime":"1687276744519"
},
{
"symbol":"AMD",
"expiry":"20230818",
"strike":"140.0",
"right":"CALL",
"dir":"Buy",
"volume":1700,
"price":3.25,
"amount":552500,
"tradeTime":"1687276467421"
},
{
"symbol":"AAPL",
"expiry":"20230915",
"strike":"185.0",
"right":"PUT",
"dir":"Sell",
"volume":1500,
"price":6.65,
"amount":997500,
"tradeTime":"1687276413267"
},
{
"symbol":"BABA",
"expiry":"20240119",
"strike":"75.0",
"right":"PUT",
"dir":"Sell",
"volume":1500,
"price":4.8,
"amount":720000,
"tradeTime":"1687276036749"
}
// ......
]
}
]
}
Stomp
Subscribe to Market Data Streaming
PushClient.subscribe_quote(symbols, quote_key_type=QuoteKeyType.TRADE, focus_keys=None)
Unsubscribe
PushClient.unsubscribe_quote(symbols)
Description
Use this method to subscribe and unsubscribe to the market datat streaming service of a designated symbol. The data received needs to be processed with your own implementatioin of PushClient.on_quote_changed
. Our sever will push you the data whenever a transaction, or a change of quote occurred.
Arguments
Arguments | Type | Description |
---|---|---|
symbols | list[str] | A list of ticker symbols. The symbols are case sensitive. Example: ['AAPL', 'BABA'], |
quote_key_type | QuoteKeyType | tigeropen.common.consts.quote_keys.QuoteKeyType, The key type of the |
focus_keys | list[str] | List of keys. Ignoring this parameter is recommendeds if there is a value assigned to quote_key_type |
Possible key types in tigeropen.common.consts.quote_keys.QuoteKeyType
includes:
Attribute | Description |
---|---|
QuoteKeyType.TRADE | Transaction daata, fields: open, latest_price, high, low, prev_close, volume, timestamp |
QuoteKeyType.QUOTE | Market Quote data, fields: ask_price, ask_size, bid_price, bid_size, timestamp |
QuoteKeyType.TIMELINE | One Minute K-line, fields: p-latest price, a:average price, t:timestamp, v: volume. |
QuoteKeyType.ALL | All of the aboves |
Arguments-unsubscribe
Arguments | Type | Description |
---|---|---|
symbols | list[str] | List of ticker symbols. Example: ['AAPL', 'BABA'] |
Examples
from tigeropen.push.push_client import PushClient
from tigeropen.tiger_open_config import get_client_config
client_config = get_client_config(private_key_path='private key path', tiger_id='your tiger id', account='your account')
# Initialize PushClient
protocol, host, port = client_config.socket_host_port
push_client = PushClient(host, port, use_ssl=(protocol == 'ssl'))
#Implement your own callback function
def on_quote_changed(symbol, items, hour_trading):
"""
callback for market data push
:param symbol: list of symbols
:param items: list,each element is a tuple, each tuple correspond to the name of a data field, and its value
:param hour_trading: if the current time is within trading hour
:return:
"""
print(f'quote change: {symbol}, {items}, {hour_trading}')
# bind callback method
push_client.quote_changed = on_quote_changed
# Establish a Connection
push_client.connect(client_config.tiger_id, client_config.private_key)
# Subscribe to data streaming. You can choose a set of keys of your interest. However, the default value for key is QuoteKeyType.Trade. See tigeropen.common.consts.quote_keys.QuoteKeyType for details
push_client.subscribe_quote(['AAPL', 'BABA'], quote_key_type=QuoteKeyType.ALL)
# Unsubscribes
push_client.unsubscribe_quote(['AAPL', 'BABA'])
# Disconnect
push_client.disconnect()
Callback Data
The data pushed by the server needs to be processed with your own implementation of on_quote_changed(symbol, items, hour_trading)
. The data is structured as follows:
- symbol, represents the ticker symbol of an aseet,
str
- items, is a
list
oftuple
s that contains the acutal data. Each tuple contains the name of the data field and its value - hour_trading. The
bool
represents if it is currently in trading hour.
Callback Data Example
items:
[('latest_price', 339.8), ('ask_size', 42500), ('ask_price', 340.0), ('bid_size', 1400), ('bid_price', 339.8),
('high', 345.0), ('prev_close', 342.4), ('low', 339.2), ('open', 344.0), ('volume', 7361440),
('minute', {'p': 339.8, 'a': 341.084, 't': 1568098440000, 'v': 7000, 'h': 340.0, 'l': 339.8}),
('timestamp', '1568098469463')]
Subscribe to Market Depth Data
Push_client.subscribe_depth_quote(symbols)
Unsubscribe
PushClient.unsubscribe_depth_quote(symbols)
Description
Subscribe to market depth quote. a maximum of 40 levels of the orderbook will be returned. There will be a data push whenever there is a change of orderbook
Argument
Argument | Type | Description |
---|---|---|
symbols | list[str] | List of ticker symbols. Example: ['AAPL', 'BABA'] |
Unsubscribe
Argument | Type | Description |
---|---|---|
symbols | list[str] | List of ticker symbols. Example: ['AAPL', 'BABA'] |
Example
from tigeropen.push.push_client import PushClient
from tigeropen.tiger_open_config import get_client_config
client_config = get_client_config(private_key_path='private key path', tiger_id='your tiger id', account='your account')
# Initialize PushClient
protocol, host, port = client_config.socket_host_port
push_client = PushClient(host, port, use_ssl=(protocol == 'ssl'))
#Implement callback function
def on_quote_changed(symbol, items, hour_trading):
"""
Callback Data
:param symbol: Symbol of the subscribed security
:param items: list, each element is a tuple, corresponding to the field name and value of the subscription
:param hour_trading: Whether it is after hours trading
:return:
"""
print(f'quote change: {symbol}, {items}, {hour_trading}')
# bind callback method
push_client.quote_changed = on_quote_changed
# Establish connection
push_client.connect(client_config.tiger_id, client_config.private_key)
# Subscribe to the quote
push_client.subscribe_depth_quote(['AMD', 'MSFT'])
# Cancel subscription
push_client.unsubscribe_depth_quote(['AMD', 'MSFT'])
# Disconnect
push_client.disconnect()
Callback Data
Implement on_quote_changed(symbol, items, hour_trading)
to process the callback data, where:
- symbol stands for security ticker symbol,
str
Type - items is a
list
which contains the actual orderbook data. It contains 3list
of equal length, corresponds to: price,volume and order count - hour_trading is a
bool
represents if it is ouside regular trading hours
Callback Data Example
Example of items:
[('bid_depth',
'[[127.87,127.86,127.86,127.86,127.85,127.85,127.85,127.84,127.84,127.84,127.84,127.83,127.83, 127.83,127.83,127.83,127.82,127.81,127.8,127.8,127.8,127.8,127.8,127.8,127.8,127.79,127.79,127.78, 127.78, 127.75,127.68,127.6,127.6,127.55,127.5,127.5,127.5,127.5,127.29,127.28],[69,2,5,20,1,1,1,18,1,70,80,40,2,330,330,1,40,80,20,10,131,2,30,50,300,1,38,1,1,15,6,20,1,3,100,15,25,30,49,43]]'),
('ask_depth',
'[[127.91,127.94,127.95,127.95,127.95,127.95,127.95,127.96,127.98,127.98,127.98,127.98,127.99,127.99, 128.0,128.0,128.0,128.0,128.0,128.0,128.0,128.0,128.0,128.0,128.0,128.0,128.0,128.0,128.0,128.0,128.0, 128.0,128.0,128.0,128.0,128.0,128.0,128.0,128.0,128.0],[822,4,98,50,5,5,500,642,300,40,1,36,19,1,1,1,1,50,1,1,50,1,100,10,1,1,10,1,1,1,1,5,1,8,1,1,120,70,1,4]]'),
('timestamp', 1621933454191)]
Subscribe to Trade Tick Data
Push_client.subscribe_tick(symbols)
Unsubscribe
PushClient.unsubscribe_tick(symbols)
Description
This is an asynchronous interface and the results of asynchronous requests can be obtained by implementing the PushClient.tick_changed interface. This method is used for both stocks and futures.
Argument
Argument | Type | Description |
---|---|---|
symbols | list[str] | List of ticker symbols. Example: ['AAPL', 'BABA'] |
Unsubscribe
Argument | Type | Description |
---|---|---|
symbols | list[str] | List of ticker symbols. Example: ['AAPL', 'BABA'] |
Example
from tigeropen.push.push_client import PushClient
from tigeropen.tiger_open_config import get_client_config
client_config = get_client_config(private_key_path='private key path', tiger_id='your tiger id', account='your account')
# Initialize PushClient
protocol, host, port = client_config.socket_host_port
push_client = PushClient(host, port, use_ssl=(protocol == 'ssl'))
def on_tick_changed(symbol, items):
"""
:param symbol:
:param items:
:return:
"""
print(f'tick change:{symbol}, items:{items}')
# convert to pandas.DataFrame
# ticks = pd.DataFrame(items)
# print(ticks)
# Bind callback method
push_client.tick_changed = on_tick_changed
# connect
push_client.connect(client_config.tiger_id, client_config.private_key)
# subscribe tick data
push_client.subscribe_tick(['AMD', 'MSFT'])
# subscribe futures tick data
push_client.subscribe_tick(['HSImain', 'CNmain'])
time.sleep(10)
# unsubscribe
push_client.unsubscribe_tick(['AMD', 'MSFT'])
# disconnect
push_client.disconnect()
Callback data
callback function on_tick_changed(symbol, items) receive data:
- symbol is code of the contract,
str
- items are data list,
list
, each item isdict
item fields meanings as follows:
Field | Type | Description |
---|---|---|
symbol | str | contract code |
type | str | tick data type, always 'TradeTick' |
server_timestamp | int | server push time, unit: millisecond |
volume | int | trade volume |
price | float | trade price |
time | int | trade time, unit: millisecond |
part_code | str | exchange code |
part_code_name | str | exchange code name |
sn | int | serial number |
quote_level | str | quote permission level(For US stock,usQuoteBasic data is less than usStockQuote) |
cond | str | trade condition,if None meaning auto order matching,refer to Trade Condition |
tick_type | str | * price no change,+ price up,- price down |
Callback data example
[{'tick_type': '*', 'price': 293.87, 'volume': 102, 'part_code': 'NSDQ',
'part_code_name': 'NASDAQ Stock Market, LLC (NASDAQ)', 'cond': 'US_FORM_T', 'time': 1656405615779,
'server_timestamp': 1656405573461, 'type': 'TradeTick', 'quote_level': 'usStockQuote', 'sn': 342,
'timestamp': 1656405617385},
{'tick_type': '*', 'price': 293.87, 'volume': 102, 'part_code': 'NSDQ',
'part_code_name': 'NASDAQ Stock Market, LLC (NASDAQ)', 'cond': 'US_FORM_T', 'time': 1656405616573,
'server_timestamp': 1656405573461,
'type': 'TradeTick', 'quote_level': 'usStockQuote', 'sn': 343, 'timestamp': 1656405617385}]
Get List of Subscribed Assets
PushClient.query_subscribed_quote()
Description
Get a list of all subscribed assets
Implement PushClient.query_subscribed_callback
to process the returned data
Argument
None
Callback Date
Implement PushClient.query_subscribed_callback
to process the returned data
callback data is a dict, meanings of keys as follows:
Key | Type | Description |
---|---|---|
subscribed_symbols | list | Subscribed contracts. (Correspond to PushClient.subscribe_quote) |
limit | int | The maximum number of contracts that can subscribe to quote for the current tiger id |
used | int | Number of contracts to which the current tiger id has subscribed |
symbol_focus_keys | dict | Subscribed quote field |
subscribed_quote_depth_symbols | list | List of contracts that have subscribed to the depth quote.(Correspond to PushClient.subscribe_depth_quote) |
quote_depth_limit | int | The maximum number of contracts that can subscribe to depth quote for the current tiger id |
quote_depth_used | int | Number of contracts to which the current tiger id has subscribed depth quote |
subscribed_trade_tick_symbols | list | List of contracts that have subscribed to the tick.(Correspond to PushClient.subscribe_tick) |
trade_tick_limit | int | The maximum number of contracts that can subscribe to tick data for the current tiger id |
trade_tick_used | int | Number of contracts to which the current tiger id has subscribed tick |
Example
from tigeropen.push.push_client import PushClient
from tigeropen.tiger_open_config import get_client_config
client_config = get_client_config(private_key_path='private key path', tiger_id='your tiger id', account='your account')
# Initialize PushClient
protocol, host, port = client_config.socket_host_port
push_client = PushClient(host, port, use_ssl=(protocol == 'ssl'))
# define callback method
def query_subscribed_callback(data):
"""
data example:
{'subscribed_symbols': ['QQQ'], 'limit': 1200, 'used': 1, 'symbol_focus_keys': {'qqq': ['open', 'prev_close', 'low', 'volume', 'latest_price', 'close', 'high']},
'subscribed_quote_depth_symbols': ['NVDA'], 'quote_depth_limit': 20, 'quote_depth_used': 1,
'subscribed_trade_tick_symbols': ['QQQ', 'AMD', '00700'], 'trade_tick_limit': 1200, 'trade_tick_used': 3}
"""
print(f'subscribed quote:{data}')
print(f'subscribed symbols:{data["subscribed_symbols"]}')
# bind callback method
push_client.query_subscribed_callback = query_subscribed_callback
# connect
push_client.connect(client_config.tiger_id, client_config.private_key)
# subscribe quote
push_client.subscribe_quote(['QQQ'])
# subscribe depth quote
push_client.subscribe_depth_quote(['NVDA'])
# subscribe tick
push_client.subscribe_tick(['QQQ'])
# query what I have subscribed
push_client.query_subscribed_quote()
time.sleep(10)
Callback data example
{'subscribed_symbols': ['QQQ'], 'limit': 1200, 'used': 1, 'symbol_focus_keys': {'qqq': ['open', 'prev_close', 'low', 'volume', 'latest_price', 'close', 'high']},
'subscribed_quote_depth_symbols': ['NVDA'], 'quote_depth_limit': 20, 'quote_depth_used': 1,
'subscribed_trade_tick_symbols': ['QQQ', 'AMD', '00700'], 'trade_tick_limit': 1200, 'trade_tick_used': 3
}
Subscribe to Option Quote
Description
Subscribe to market quote data for options
Argument
Argument | Type | Description |
---|---|---|
symbols | list[str] | The symbols of an option contract is made up with: ticker symbol of the underlying asset,expiration data(YYYYMMDD), strike price, PUT/CALL, example: AAPL 20230120 150.0 CALL |
Examplepush_client.subscribe_option(['AAPL 20230120 150.0 CALL', 'SPY 20220930 470.0 PUT'])
OR
push_client.subscribe_quote(['AAPL 20230120 150.0 CALL', 'SPY 20220930 470.0 PUT'])
Callback Data
You need to implement push_client.quote_changed
to process the data pushed by the server. Please refer to the examples for stocks above.
Subscribe to Future Quote
Argument
Argument | Type | Description |
---|---|---|
symbols | list[str] | The symbols of Futures, like 'CLmain', 'ES2209' |
Callback Data
You need to implement push_client.quote_changed
to process the data pushed by the server. Please refer to the examples for stocks above.
example
push_client.subscribe_future(['CLmain', 'CN2209'])
# OR
push_client.subscribe_quote(['VIXmain', 'ES2209'])