Important changes by release
This page lists all relevant updates to Hummingbot codebase aimed to help connector developers in making the requisite changes to their connectors.
Each exchange connector is comprised of the following components:
|(1) Trade execution||Sending buy/sell/cancel instructions to the exchange.|
|(2) Conforming order book data||Formatting an exchange's order book data into the standard format used by Hummingbot.|
|(3) Order book tracking||State management: tracking exchange's real-time order book data.|
|(4) Active order tracking||State management: tracking orders placed by the bot on the exchange.|
|(5) User stream tracker||Tracking data specific to the user of the bot.|
This guide is intended to get you familiarized with basic structure of a connector in Hummingbot. It will guide you through the scope of creating/modifying the necessary components to implement a connector.
By the end of this guide, you should:
- Have a general understanding of the base classes that serve as building blocks of a connector
- Be able to integrate new connectors from scratch
Implementing a new connector can generally be split into 3 major tasks:
Tasks and UML Diagram¶
The following diagram displays the tasks and their relevant classes(required and optional) as checklist to get started.
Order Lifecycle and Market Events¶
Exchange connectors track status updates of all orders created in Hummingbot, and emit events on status updates of its orders for strategy objects. When implementing a new exchange connector, care must be taken to ensure all the status updates and emitted events adhere to the same semantics as other market connectors.
Order tracking starts when
c_sell() is called. It happens for both market order and limit orders. A market connector should keep tracking the status of the order and emit events for any change of states, until the order is completed, cancelled, expired or failed.
Order Lifecycle Flowchart¶
Creating an Order¶
An order is created by invoking
c_sell() in a market connector - usually from a strategy object.
c_sell() would return immediately with a client-side order ID that Hummingbot uses to track the order's status. They would schedule the order to be submitted to the exchange as soon as possible, but would not wait for the reply from the exchange before returning.
Submitting an Order¶
In most of our built-in market connectors, order submission happens in the functions
execute_sell() - although it may be different for some decentralized exchange connectors.
execute_sell() are different from
c_sell() because they are asynchronous functions - they can make network calls without blocking other code in Hummingbot.
execute_sell() successfully submits an order to the exchange, and gets back a successful reply - then a
SellOrderCreatedEvent would be emitted. If the order submission fails, then a
MarketOrderFailureEvent would be emitted. Note that despite the naming,
MarketOrderFailureEvent is emitted even for limit orders.
Order Being Filled¶
An order would be filled by other market participants over time, once it's live on an exchange. If the order is a limit order, then usually it has to wait for market orders from other market participants to hit it. If the order is a market order, then usually it is filled as soon as possible by getting matched to limit orders on the exchange.
For every order fill related to orders it made before, a market connector must emit a
OrderFilledEvent, to notify strategy objects about the progress of the order.
Once an order has been completely filled, the market connector would emit a
SellOrderCompleted event. The market connector would stop tracking the order afterwards.
SellOrderCompleted events should always come after the
OrderFilledEvent that finished filling the order.d
Order Cancellation or Expiry¶
If an order is cancelled, or expired before it has been completely filled - then an
OrderCancelledEvent or an
OrderExpiredEvent would be emitted.
For centralized exchanges, order tracking should end after emitting an
OrderExpiredEvent. On decentralized exchanges - since it's possible for orders to be filled after cancellation or even expiry, due to block delays - the market connector may keep tracking the order for a certain amount of time afterwards.
On some exchanges, it is possible for an order to fail or rejected without having completed, having been cancelled or expired. For example, on decentralized exchanges, an live order could be rejected by the exchange after initial submission if there is not enough balance on the wallet to fill the order. If an order has failed or has been rejected for any reason other than cancellation or expiry, then a
MarketOrderFailureEvent would be emitted.
In Flight Order Helper¶
Hummingbot comes with a built-in helper class for market connectors to track their order states, the
While market connector authors are free to extend or modify from
InFlightOrderBase to suit their own logic. There are a few conventions within Hummingbot's built-in market connectors for extending
InFlightOrderBase, and it is recommended that new market connectors should stick with the same conventions.
This property indicates whether the order is done or not, whether it has been completely filled or failed, cancelled or expired.
This property indicates whether the order has been cancelled or not.
This property indicates whether the order has been terminated before completion or not. This includes all cases like order cancellation, expiry or rejection.
The base asset symbol.
The quote asset symbol.
This is called when the market connector has successfully submitted the order to the exchange, and has got back an exchange-native order ID. This notifies any coroutines waiting on the
get_exchange_order_id()function (detailed below).
async get_exchange_order_id(): str
This is an asynchronous function and can only be called from
async deffunctions in Hummingbot. It returns the exchange-native order ID for the order, if the order has been submitted and the exchange-native order ID is known. Otherwise, it would wait until
update_exchange_order_id(str)is called by the market connector.
Converts the in-flight order data structure to a
LimitOrderdata object. This should only be used on limit orders.
to_json(): Dict[str, any]
Convert the in-flight order data structure to a dictionary that can be serialized into JSON format.