# Subscribe and Unsubscribe

# Subscribe to Real-Time Market Data

subscribe(code_list, subtype_list, is_first_push=True, subscribe_push=True, is_detailed_orderbook=False, extended_time=False)

  • Description

    To subscribe to the real-time information required for registration, specify the stock and subscription data types. HK market (including underlying stocks, warrants, CBBCs, options, futures) subscriptions require LV1 and above permissions. Subscriptions are not supported under BMP permissions.

  • Parameters

    Parameter Type Description
    code_list list A list of stock codes that need to be subscribed.
    subtype_list list List of data types that need to be subscribed.
    is_first_push bool Whether to push the cached data immediately after a successful subscription.
    subscribe_push bool Whether to push data after subscription.
    is_detailed_orderbook bool Whether to subscribe to the detailed order book.
    extended_time bool Whether to allow pre-market and after-hours data of US stocks.
  • Return

    Field Type Description
    ret RET_CODE Interface result.
    err_message NoneType If ret == RET_OK, None is returned.
    str If ret != RET_OK, error description is returned.
  • Example

import time
from futu import *
class OrderBookTest(OrderBookHandlerBase):
    def on_recv_rsp(self, rsp_pb):
        ret_code, data = super(OrderBookTest,self).on_recv_rsp(rsp_pb)
        if ret_code != RET_OK:
            print("OrderBookTest: error, msg: %s"% data)
            return RET_ERROR, data
        print("OrderBookTest ", data) # OrderBookTest's own processing logic
        return RET_OK, data
quote_ctx = OpenQuoteContext(host='127.0.0.1', port=11111)
handler = OrderBookTest()
quote_ctx.set_handler(handler) # Set real-time swing callback
quote_ctx.subscribe(['HK.00700'], [SubType.ORDER_BOOK]) # Subscribe to the order type, OpenD starts to receive continuous push from the server
time.sleep(15) # Set the script to receive OpenD push duration to 15 seconds
quote_ctx.close() # Close the current link, OpenD will automatically cancel the corresponding type of subscription for the corresponding stock after 1 minute
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
  • Output
OrderBookTest  {'code': 'HK.00700', 'svr_recv_time_bid': '2020-04-29 10:40:03.147', 'svr_recv_time_ask': '2020-04-29 10:40:03.147', 'Bid': [(416.8, 2600, 11, {}), (416.6, 13100, 17, {}), (416.4, 24600, 17, {}), (416.2, 28000, 13, {}), (416.0, 46900, 30, {}), (415.8, 10900, 7, {}), (415.6, 7100, 9, {}), (415.4, 13300, 3, {}), (415.2, 300, 3, {}), (415.0, 11200, 36, {})], 'Ask': [(417.0, 17600, 31, {}), (417.2, 17800, 24, {}), (417.4, 15300, 10, {}), (417.6, 28800, 17, {}), (417.8, 20700, 11, {}), (418.0, 114200, 155, {}), (418.2, 20600, 19, {}), (418.4, 24100, 28, {}), (418.6, 42700, 45, {}), (418.8, 181900, 76, {})]}
1

# Cancel Market Data Subscription

unsubscribe(code_list, subtype_list, unsubscribe_all=False)

  • Description

    unsubscribe

  • Parameters

    Parameter Type Description
    code_list list A list of stock codes to unsubscribe.
    subtype_list list List of data types that need to be subscribed.
    unsubscribe_all bool Cancel all subscriptions.
  • Return

    Field Type Description
    ret RET_CODE Interface result.
    err_message NoneType If ret == RET_OK, None is returned.
    str If ret != RET_OK, error description is returned.
  • Example

from futu import *
import time
quote_ctx = OpenQuoteContext(host='127.0.0.1', port=11111)

print('current subscription status :', quote_ctx.query_subscription()) # Query the initial subscription status
ret_sub, err_message = quote_ctx.subscribe(['HK.00700'], [SubType.QUOTE, SubType.TICKER], subscribe_push=False)
# First subscribed to the two types of QUOTE and TICKER. After the subscription is successful, OpenD will continue to receive pushes from the server, False means that there is no need to push to the script temporarily
if ret_sub == RET_OK: # Subscription successful
    print('subscribe successfully! current subscription status :', quote_ctx.query_subscription()) # Query subscription status after successful subscription
    time.sleep(60) # You can unsubscribe at least 1 minute after subscribing
    ret_unsub, err_message_unsub = quote_ctx.unsubscribe(['HK.00700'], [SubType.QUOTE])
    if ret_unsub == RET_OK:
        print('unsubscribe successfully! current subscription status:', quote_ctx.query_subscription()) # Query the subscription status after canceling the subscription
    else:
        print('unsubscription failed!', err_message_unsub)
else:
    print('subscription failed', err_message)
quote_ctx.close() # After using the connection, remember to close it to prevent the number of connections from running out
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
  • Output
current subscription status : (0, {'total_used': 0, 'remain': 1000, 'own_used': 0, 'sub_list': {}})
subscribe successfully!current subscription status : (0, {'total_used': 2, 'remain': 998, 'own_used': 2, 'sub_list': {'QUOTE': ['HK.00700'], 'TICKER': ['HK.00700']}})
unsubscribe successfully!current subscription status: (0, {'total_used': 1, 'remain': 999, 'own_used': 1, 'sub_list': {'TICKER': ['HK.00700']}})
1
2
3

# Cancel All Market Data Subscriptions

unsubscribe_all()

  • Description

    Unsubscribe all subscriptions

  • Return

    Field Type Description
    ret RET_CODE Interface result.
    err_message NoneType If ret == RET_OK, None is returned.
    str If ret != RET_OK, error description is returned.
  • Example

from futu import *
import time
quote_ctx = OpenQuoteContext(host='127.0.0.1', port=11111)

print('current subscription status :', quote_ctx.query_subscription()) # Query the initial subscription status
ret_sub, err_message = quote_ctx.subscribe(['HK.00700'], [SubType.QUOTE, SubType.TICKER], subscribe_push=False)
# First subscribed to the two types of QUOTE and TICKER. After the subscription is successful, OpenD will continue to receive pushes from the server, False means that there is no need to push to the script temporarily
if ret_sub == RET_OK: # Subscription successful
    print('subscribe successfully! current subscription status :', quote_ctx.query_subscription()) # Query subscription status after successful subscription
    time.sleep(60) # You can unsubscribe at least 1 minute after subscribing
    ret_unsub, err_message_unsub = quote_ctx.unsubscribe_all() # Cancel all subscriptions
    if ret_unsub == RET_OK:
        print('unsubscribe all successfully! current subscription status:', quote_ctx.query_subscription()) # Query the subscription status after canceling the subscription
    else:
        print('Failed to cancel all subscriptions!', err_message_unsub)
else:
    print('subscription failed', err_message)
quote_ctx.close() # After using the connection, remember to close it to prevent the number of connections from running out
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
  • Output
current subscription status : (0, {'total_used': 0, 'remain': 1000, 'own_used': 0, 'sub_list': {}})
subscribe successfully!current subscription status : (0, {'total_used': 2, 'remain': 998, 'own_used': 2, 'sub_list': {'QUOTE': ['HK.00700'], 'TICKER': ['HK.00700']}})
unsubscribe all successfully!current subscription status: (0, {'total_used': 0, 'remain': 1000, 'own_used': 0, 'sub_list': {}})
1
2
3

Interface Limitations

  • Supports subscriptions of multiple real-time data types, refer to SubType, each stock subscription for one one quota.
  • Please refer to Subscription Quota & Historical Candlestick Quota for Subscription Quota rules.
  • You can unsubscribe after subscribing after at least one minute.
  • Due to the large amount of SF market data in Hong Kong stocks, in order to ensure the speed of the SF market and the processing performance of OpenD, currently SF authorized users are limited to subscribing to 50 security products (including hkex stocks, warrants, bulls and bears) at the same time, the remaining subscription quota can still be used to subscribe to other types, such as: tickers and brokerage etc.
  • HK options and futures do not support subscription to TICKER type under LV1 authority.