Quant Infrastructure #4 - Keeping Track of Inventory
How to stay in sync with an asynchronous exchange.
Trading on an exchange requires us to keep track of the state of our account and markets in close to real-time. Our trading infrastructure and the exchange run asynchronously with each other and communicate over the network, which is at times unreliable and always carries some latency.
Today we write a robust Inventory component for our Quant Infrastructure to correctly and reliably track the traded inventory on the exchange. We will maintain a local copy of all wallet assets and open positions and make it available to other components. Our Inventory will be exchange-agnostic and suitable for trading live as well as backtesting without any code changes and within the same infrastructure.
We will also address reliability problems encountered in the course of trading live on Crypto exchanges, which, to my knowledge, has not been done anywhere previously.
This is the first article out of three that cover the three core components of the trading part of the infrastructure: InstrumentStore, Inventory and OrderExecutor. We will cover these in the next few articles and make an interlude for fixed-point numbers. The next article will introduce the idea of orders-in-flight and show how to neatly handle limit orders in our Quant Infrastructure.
A typical trading loop on a Crypto CEX will see us passively ingest events from the exchange — usually through a WebSocket connection— which will carry updates about the state of our account, orders, traded instruments, prices, the order book, etc., whilst we occasionally make requests to the exchange via an HTTP API.
Robust tracking of state on the exchange carries some nuance:
The data feed itself can malfunction. Events can be skipped, delayed, or arrive out of order.
When related entities are updated separately — as is typically the case with inventory and orders — the tracked local state can become inconsistent and cause erroneous behaviour by our infrastructure.
An example of erroneus trading caused by orders-inventory inconsistency:
Suppose we want to buy 1 BTC. We post an order and obtain a fill. The event with the filled order arrives so naively we think we no longer have an order posted; but the event about the new inventory hasn’t arrived yet. Between those two events, we may mistakenly think we don’t have the desired amount of BTC and don’t have an order posted and may mistakenly post another order and so on.
We will address these issues in the article.
We will begin by defining the exchange events which we will ingest, followed by the implementation of a simple inventory component as a base case. Then, we will make our inventory component robust to errors. Last, we will show how we can handle the orders-inventory inconsistency.
Today’s article is free to read. The complete source code is available for paying subscribers in the Subscriber Materials section at the end of the article as per usual.
Keep reading with a 7-day free trial
Subscribe to TaiwanQuant's Newsletter to keep reading this post and get 7 days of free access to the full post archives.