def __init__(self, **kwargs):
        """
        Create the subscription client to subscribe the update from server.

        :param kwargs: The option of subscription connection.
            api_key: The public key applied from Binance.
            secret_key: The private key applied from Binance.
            uri: Set the URI for subscription.
            is_auto_connect: When the connection lost is happening on the subscription line, specify whether the client
                            reconnect to server automatically. The connection lost means:
                                Caused by network problem
                                The connection close triggered by server (happened every 24 hours)
                            No any message can be received from server within a specified time, see receive_limit_ms
            receive_limit_ms: Set the receive limit in millisecond. If no message is received within this limit time,
                            the connection will be disconnected.
            connection_delay_failure: If auto reconnect is enabled, specify the delay time before reconnect.
        """
        api_key = None
        secret_key = None
        if "api_key" in kwargs:
            api_key = kwargs["api_key"]
        if "secret_key" in kwargs:
            secret_key = kwargs["secret_key"]
        self.__api_key = api_key
        self.__secret_key = secret_key
        self.websocket_request_impl = WebsocketRequestImpl(self.__api_key)
        self.connections = list()
        self.uri = WebSocketDefine.Uri
        is_auto_connect = True
        receive_limit_ms = 60000
        connection_delay_failure = 1
        if "uri" in kwargs:
            self.uri = kwargs["uri"]
        if "is_auto_connect" in kwargs:
            is_auto_connect = kwargs["is_auto_connect"]
        if "receive_limit_ms" in kwargs:
            receive_limit_ms = kwargs["receive_limit_ms"]
        if "connection_delay_failure" in kwargs:
            connection_delay_failure = kwargs["connection_delay_failure"]
        self.__watch_dog = WebSocketWatchDog(is_auto_connect, receive_limit_ms,
                                             connection_delay_failure)

        self.logger = logging.getLogger("binance-futures")
class SubscriptionClient(object):
    def __init__(self, **kwargs):
        """
        Create the subscription client to subscribe the update from server.

        :param kwargs: The option of subscription connection.
            api_key: The public key applied from Binance.
            secret_key: The private key applied from Binance.
            uri: Set the URI for subscription.
            is_auto_connect: When the connection lost is happening on the subscription line, specify whether the client
                            reconnect to server automatically. The connection lost means:
                                Caused by network problem
                                The connection close triggered by server (happened every 24 hours)
                            No any message can be received from server within a specified time, see receive_limit_ms
            receive_limit_ms: Set the receive limit in millisecond. If no message is received within this limit time,
                            the connection will be disconnected.
            connection_delay_failure: If auto reconnect is enabled, specify the delay time before reconnect.
        """
        api_key = None
        secret_key = None
        if "api_key" in kwargs:
            api_key = kwargs["api_key"]
        if "secret_key" in kwargs:
            secret_key = kwargs["secret_key"]
        self.__api_key = api_key
        self.__secret_key = secret_key
        self.websocket_request_impl = WebsocketRequestImpl(self.__api_key)
        self.connections = list()
        self.uri = WebSocketDefine.Uri
        is_auto_connect = True
        receive_limit_ms = 60000
        connection_delay_failure = 1
        if "uri" in kwargs:
            self.uri = kwargs["uri"]
        if "is_auto_connect" in kwargs:
            is_auto_connect = kwargs["is_auto_connect"]
        if "receive_limit_ms" in kwargs:
            receive_limit_ms = kwargs["receive_limit_ms"]
        if "connection_delay_failure" in kwargs:
            connection_delay_failure = kwargs["connection_delay_failure"]
        self.__watch_dog = WebSocketWatchDog(is_auto_connect, receive_limit_ms,
                                             connection_delay_failure)

        self.logger = logging.getLogger("binance-futures")

    def __create_connection(self, request):
        connection = WebsocketConnection(self.__api_key, self.__secret_key,
                                         self.uri, self.__watch_dog, request)
        self.connections.append(connection)
        connection.connect()

    def unsubscribe_all(self):
        for conn in self.connections:
            conn.close()
        self.connections.clear()

    def subscribe_aggregate_trade_event(self,
                                        symbol: 'str',
                                        callback,
                                        error_handler=None):
        """
        Aggregate Trade Streams

        The Aggregate Trade Streams push trade information that is aggregated for a single taker order every 100 milliseconds.

        Stream Name: <symbol>@aggTrade
        """
        request = self.websocket_request_impl.subscribe_aggregate_trade_event(
            symbol, callback, error_handler)
        self.__create_connection(request)

    def subscribe_index_price_event(self,
                                    pair: 'str',
                                    callback,
                                    error_handler=None):
        """
        Index Price Stream

        Index price for a single symbol pushed every 3 secends.

        Stream Name: <pair>@indexPrice
        """
        request = self.websocket_request_impl.subscribe_index_price_event(
            pair, callback, error_handler)
        self.__create_connection(request)

    def subscribe_mark_price_event(self,
                                   symbol: 'str',
                                   callback,
                                   error_handler=None):
        """
        Mark Price Stream

        Mark price for a single symbol pushed every 3 secends.

        Stream Name: <symbol>@markPrice
        """
        request = self.websocket_request_impl.subscribe_mark_price_event(
            symbol, callback, error_handler)
        self.__create_connection(request)

    def subscribe_continuous_candlestick_event(self,
                                               pair: 'str',
                                               contract_type: 'str',
                                               interval: 'CandlestickInterval',
                                               callback,
                                               error_handler=None):
        """
        Continuous Kline/Candlestick Streams

        The continuous Kline/Candlestick Stream push updates to the current klines/candlestick every 250 milliseconds (if existing).

        Stream Name: <pair><contractType>@continuousKline_<interval>
        """
        request = self.websocket_request_impl.subscribe_continuous_candlestick_event(
            pair, contract_type, interval, callback, error_handler)
        self.__create_connection(request)

    def subscribe_candlestick_event(self,
                                    symbol: 'str',
                                    interval: 'CandlestickInterval',
                                    callback,
                                    error_handler=None):
        """
        Kline/Candlestick Streams

        The Kline/Candlestick Stream push updates to the current klines/candlestick every 250 milliseconds (if existing).

        Stream Name: <symbol>@kline_<interval>
        """
        request = self.websocket_request_impl.subscribe_candlestick_event(
            symbol, interval, callback, error_handler)
        self.__create_connection(request)

    def subscribe_mark_price_candlestick_event(self,
                                               symbol: 'str',
                                               interval: 'CandlestickInterval',
                                               callback,
                                               error_handler=None):
        """
        Mark price Kline/Candlestick Streams

        The mark price Kline/Candlestick Stream push updates to the current mark price klines/candlestick every 250 milliseconds (if existing).

        Stream Name: <symbol>@markPriceKline_<interval>
        """
        request = self.websocket_request_impl.subscribe_mark_price_candlestick_event(
            symbol, interval, callback, error_handler)
        self.__create_connection(request)

    def subscribe_index_candlestick_event(self,
                                          pair: 'str',
                                          interval: 'CandlestickInterval',
                                          callback,
                                          error_handler=None):
        """
        Index Kline/Candlestick Streams

        The index Kline/Candlestick Stream push updates to the current index klines/candlestick every 250 milliseconds (if existing).

        Stream Name: <pair>@indexPriceKline_<interval>
        """
        request = self.websocket_request_impl.subscribe_index_candlestick_event(
            pair, interval, callback, error_handler)
        self.__create_connection(request)

    def subscribe_symbol_miniticker_event(self,
                                          symbol: 'str',
                                          callback,
                                          error_handler=None):
        """
        Individual Symbol Mini Ticker Stream

        24hr rolling window mini-ticker statistics for a single symbol pushed every 3 seconds. These are NOT the statistics of the UTC day, 
        but a 24hr rolling window from requestTime to 24hrs before.

        Stream Name: <symbol>@miniTicker
        """
        request = self.websocket_request_impl.subscribe_symbol_miniticker_event(
            symbol, callback, error_handler)
        self.__create_connection(request)

    def subscribe_all_miniticker_event(self, callback, error_handler=None):
        """
        All Market Mini Tickers Stream

        24hr rolling window mini-ticker statistics for all symbols pushed every 3 seconds. 
        These are NOT the statistics of the UTC day, but a 24hr rolling window from requestTime to 24hrs before. 
        Note that only tickers that have changed will be present in the array.

        Stream Name: !miniTicker@arr
        """
        request = self.websocket_request_impl.subscribe_all_miniticker_event(
            callback, error_handler)
        self.__create_connection(request)

    def subscribe_symbol_ticker_event(self,
                                      symbol: 'str',
                                      callback,
                                      error_handler=None):
        """
        Individual Symbol Ticker Streams

        24hr rollwing window ticker statistics for a single symbol pushed every 3 seconds. These are NOT the statistics of the UTC day, 
        but a 24hr rolling window from requestTime to 24hrs before.

        Stream Name: <symbol>@ticker
        """
        request = self.websocket_request_impl.subscribe_symbol_ticker_event(
            symbol, callback, error_handler)
        self.__create_connection(request)

    def subscribe_all_ticker_event(self, callback, error_handler=None):
        """
        All Market Tickers Stream

        24hr rollwing window ticker statistics for all symbols pushed every 3 seconds. These are NOT the statistics of the UTC day, but a 24hr rolling window from requestTime to 24hrs before. 
        Note that only tickers that have changed will be present in the array.

        Stream Name: !ticker@arr
        """
        request = self.websocket_request_impl.subscribe_all_ticker_event(
            callback, error_handler)
        self.__create_connection(request)

    def subscribe_symbol_bookticker_event(self,
                                          symbol: 'str',
                                          callback,
                                          error_handler=None):
        """
        Individual Symbol Book Ticker Streams

        Pushes any update to the best bid or ask's price or quantity in real-time for a specified symbol.

        Stream Name: <symbol>@bookTicker
        """
        request = self.websocket_request_impl.subscribe_symbol_bookticker_event(
            symbol, callback, error_handler)
        self.__create_connection(request)

    def subscribe_all_bookticker_event(self, callback, error_handler=None):
        """
        All Book Tickers Stream

        Pushes any update to the best bid or ask's price or quantity in real-time for all symbols.

        Stream Name: !bookTicker
        """
        request = self.websocket_request_impl.subscribe_all_bookticker_event(
            callback, error_handler)
        self.__create_connection(request)

    def subscribe_symbol_liquidation_event(self,
                                           symbol: 'str',
                                           callback,
                                           error_handler=None):
        """
        Liquidation Order Streams

        The Liquidation Order Streams push force liquidation order information for specific symbol

        Stream Name:  <symbol>@forceOrder
        """
        request = self.websocket_request_impl.subscribe_symbol_liquidation_event(
            symbol, callback, error_handler)
        self.__create_connection(request)

    def subscribe_all_liquidation_event(self, callback, error_handler=None):
        """
        All Market Liquidation Order Streams

        The All Liquidation Order Streams push force liquidation order information for all symbols in the market.

        Stream Name: !forceOrder@arr
        """
        request = self.websocket_request_impl.subscribe_all_liquidation_event(
            callback, error_handler)
        self.__create_connection(request)

    def subscribe_book_depth_event(
            self,
            symbol: 'str',
            limit: 'int',
            callback,
            error_handler=None,
            update_time: 'UpdateTime' = UpdateTime.INVALID):
        """
        Partial Book Depth Streams

        Top bids and asks, Valid are 5, 10, or 20.

        Stream Names: <symbol>@depth<levels> OR <symbol>@depth<levels>@100ms.
        """
        request = self.websocket_request_impl.subscribe_book_depth_event(
            symbol, limit, update_time, callback, error_handler)
        self.__create_connection(request)

    def subscribe_diff_depth_event(
            self,
            symbol: 'str',
            callback,
            error_handler=None,
            update_time: 'UpdateTime' = UpdateTime.INVALID):
        """
        Diff. Depth Stream

        Bids and asks, pushed every 250 milliseconds or 100 milliseconds(if existing)

        Stream Name: <symbol>@depth OR <symbol>@depth@100ms
        """
        request = self.websocket_request_impl.subscribe_diff_depth_event(
            symbol, update_time, callback, error_handler)
        self.__create_connection(request)

    def subscribe_user_data_event(self,
                                  listenKey: 'str',
                                  callback,
                                  error_handler=None):
        """
        User Data Streams
        """
        request = self.websocket_request_impl.subscribe_user_data_event(
            listenKey, callback, error_handler)
        self.__create_connection(request)

    def subscribe_pair_mark_price_event(self,
                                        pair: 'str',
                                        callback,
                                        error_handler=None):
        """
        Mark Price of All Symbols of a Pair

        Stream Name: <pair>@markPrice OR <pair>@markPrice@1s

        Update Speed: 3000ms or 1000ms
        """
        request = self.websocket_request_impl.subscribe_pair_mark_price_event(
            pair, callback, error_handler)
        self.__create_connection(request)