Skip to content

Task 2 — UserStreamTracker & Authentication

UserStreamTrackerUMLDiagram

The UML Diagram, given above, illustrates the relations between UserStreamTracker and its subsidiary classes.

The UserStreamTracker responsibility is to fetch user account data and queues it accordingly.

UserStreamTracker contains subsidiary classes that help maintain the real-time wallet/holdings balance and open orders of a user. Namely, the classes required are:

  • UserStreamTrackerDataSource
  • UserStreamTracker
  • Auth(if applicable).

Note

Auth is generally only required in Centralized Exchanges

UserStreamTrackerDataSource

UserStreamTrackerDataSourceClassDiagram

The UserStreamTrackerDataSource class is responsible for initializing a WebSocket connection to obtain user order, trade, and balances updates. Implementing an exchange connector would require you to create its own data source that extends from the UserStreamTrackerDataSource base class here.

Below are some variable(s) and its respective description that you might find useful when creating a connector:

Variable(s) Type Description
_domain Optional[str] Denotes the base domain for all REST API requests and WS connections.
_last_recv_time float The timestamp(in ms) of the last user data message received by the websocket client.
_auth Auth The Auth class used by the UserStreamTrackerDataSource.

Tip

For an example on _domain you can refer to Binance or ProBit.

The following details the required functions in UserStreamTrackerDataSource:

last_recv_time

A property function that retrieves the timestamp(in ms) of the last user data message received by the WebSocket client. Should be updated(using python's time.time() or using the message timestamp) everytime message is received from the WebSocket.

Input Parameter: None
Expected Output(s): float

listen_for_user_stream

An abstract function from the UserTrackerDataSource base class that must be implemented. Subscribes to all relevant user channels via web socket, and keeps the connection open for incoming messages.

Input Parameter: ev_loop: asyncio.BaseEventLoop, output: asyncio.Queue
Expected Output(s): None

UserStreamTracker

UserStreamTrackerClassDiagram

The UserStreamTracker class is responsible for capturing the user's account balances and orders. It simply parses and queues the messages to be processed by the Exchange class.

This can be achieved in 2 ways(depending on the available API on the exchange):

  1. REST API

In this scenario, we would have to periodically make API requests to the exchange to retrieve information on the user's account balances and order statuses. An example of this can be seen in Huobi's connector exchange file connector.

As seen in the Exchange class, Huobi uses REST API alone by periodically calling the market's _update_balances() and _update_order_status() through the _status_polling_loop(). Also, it can be seen that no user stream files exist in Huobi's connector directory.

Warning

Maintaining user data using just the REST API is not ideal and would generally lead to degraded performance of the bot.

  1. WebSocket API

When an exchange does have WebSocket API support to retrieve user account details and order statuses, it would be ideal to incorporate it into the Hummingbot client when managing account balances and to update order statuses. This is especially important since Hummingbot needs to know the available account balances and order statuses at all times.

Tip

In most scenarios, as seen in most other Centralized Exchanges(i.e. Binance, Crypto.com, ProBit), a simple WebSocket integration is used to listen on selected topics and retrieving messages to be processed in Exchange class.

The following details the required functions to be implemented in UserStreamTracker:

data_source

Initializes a user stream data source.

Input Parameter: None
Expected Output(s): UserStreamTrackerDataSource

start

Starts all listeners and tasks.

Input Parameter: None
Expected Output(s): None

Authentication

AuthClassDiagram

Tracking a user's orders, trades and balance generally require authentication tied to each request or a WebSocket connection. Hence it would only make sense to have a dedicated module to handle the generation of request signatures(REST API) or authentication payloads(WebSocket API).

The Auth class is responsible for creating the necessary request headers and/or data bodies necessary to authenticate said request/WebSocket connection.

Note

Although mainly used in the Exchange class, it is generally required here in the UserStreamTrackerDataSource.

Below are some variable(s) and its respective description that you might find useful when creating a connector:

Variable(s) Type Description
api_key str The user's API Key for the exchange.
secret_key str The user's API Secret for the exchange.
passphrase Optional[str] The passphrase associated to said API key. An optional variable depending on the exchange specifications.
domain Optional[str] Denotes the base domain for all REST API requests and WS connections.
auth_token Optional[str] The OAuth token associated to a user. An optional variable depending on the exchange specifications.

The following details the required functions to be implemented in Auth:

generate_auth_dict

Generates the necessary auth headers and its corresponding values for an API request.

Input Parameter: Any
Expected Output(s): Dict[str, Any]

get_ws_auth_payload

Generates the authentication payload required to established a authenticated websocket connection.

Input Parameter: Any
Expected Output(s): Dict[str, Any]

Warning

The details on how to correctly generate the request signature and websocket auth payload is determined by the exchange.

Debugging & Testing

As part of the Code Review and QA process, for each task (Task 1 through 3), you are required to include the unit test cases for the code review process to begin. Refer to Option 1: Unit Test Cases to build your unit tests.


Last update: 2021-09-27
Back to top