CTrader: Mid-Point Match Execution Algorithm


Our latest progress on the CSuite library offering provides excellent insight into the obscure world of execution algorithms for efficient order crossing. These types of algorithms serve to manage the acquisition price of the basic lot (i.e. one block of an iceberg/complex order) in reference to the live Limit Order Book (LOB) and are highly time-sensitive.

The Rationale

The move towards computerisation of execution underlines the need for granular control of orders in an extremely fast LOB environment, like in contemporary crypto markets. For example, a human interfaced order via Binance UI might go “stale” (i.e. be placed too far from the current top-of-book) between being entered by the user and seen by the exchange. Through the introduction of algorithmic execution, we can ensure that order parameters, such as price are as accurate as possible. In such a way we can submit precise orders seeking to execute on instant prices at e.g. the bid or mid-point. Creating capabilities like these has practical benefits in providing the tools to precisely execute complex order algorithms like a VWAP.

Mid-Point Match belongs to a (sub)class of execution algorithms which lack temporal sensitivity and act to ensure correct execution of minimum lots. Construction of higher-level order (pricing) algorithms requires calls of these execution level algorithms which fulfil micro-horizon goals. For example, a certain systematic strategy might need to utilise VWAP when buying/selling, each time it may call Mid-Point Match multiple times to fulfil the execution of each block.

The Objective

Mid-Point Match is an execution algorithm considered neutral, it seeks to fill as much of the order as possible at the unweighted Mid-Point or better, using IOC limit orders. This algorithm is orientated toward use cases which while necessitating immediacy a high level of immediacy, do not allow crossing the spread. Such a function makes it especially useful for Mean-Reversion strategies where it is implied that the move will be directed towards the passive side of the spread. Its design caters to high-frequency execution with fast cycles. There is no guarantee that the submitted limit order will act as a maker as it can cross against market orders.

Traditional Mid-Point Match (ECNs)

The idea to share the spread through neutral Mid-Point execution has been a practice in established markets like equities and options for some time. However, the fundamental lack of consistent spreads wider than 1 tick, in the most liquid cryptocurrencies makes normative Mid-Point execution unfeasible. Traditionally, this pricing is achieved through Crossing Networks which are proprietary Electronic Communication Networks (ECNs) which cross orders at the BBO mid, through ‘dark’ liquidity but necessitate both parties to consent to match at the mid-point. This offers the benefit of guaranteeing the mid if crossed which remains true even for sub-penny increments when crossing a 1-tick spread which cannot be achieved otherwise.
Thus, developing a Mid-Point Match for crypto requires facing the issues of crossing against ‘lit’ priced orders and thus, the lack of a capturable spread because the spread tends to be 1 tick. Since the algorithm needs to cross against the market flow it cannot split that tick and therefore, will only capture the mid-point if the spread is wider than 1 tick.

Our Design

Capturing the Mid-Point begins by retrieving the BBO through the Binance API [6], which gives us the reference price in the Mid-Point calculation which is utilised as the Limit Order strike [9]. As we mentioned above it is often unlikely that a spread of >1 tick exists and in such cases, we know that the round() method would result in rounding up to the opposite side of the spread. Thus, we must add/subtract one tick from the strike to match the best quote on either side [10–14].

To better illustrate let’s consider the following example:
B. Bid: 0.5000 — B.Ask: 0.5001 — Calc. Mid-Point: 0.50005 ~= Best Ask.

To finish off the process we then submit the order using the CSuite LimitOrder object [17], print a report to the terminal [19], and check for it being filled [21]. Since the algorithm seeks to realize a price which exists for a fraction of a second, we employ continuous submission of Immediate-or-Cancel (IOC) orders which will respond as either ‘FILLED’ or ‘CANCELED’ upon submission confirmation thus, we can easily monitor the status and stop submitting new orders if the trade is complete.
Since we’ve minimised the processing time between getting the BBO and submitting the order, and are also using Limit Orders, we can be sure that we will execute at Mid-Point or better on the received book. There are cases where the quote might get stale but the use of IOC orders ensures that there are only 200ms for other participants to capitalise on the order resting on the exchange (also don’t forget that Binance does not allow crossing the spread so submitting a Bid above the Best Ask is impossible). Below, you can find a sniped of the Python production code for the Mid-Point Match.