The Cancel-Order Failure: A Bad Headache for Market Makers
In one of our previous articles entitled “The Private Information Edge: An Interesting Tale in High Frequency Trading”, we presented an in-depth discussion about how market makers might gain some information edge over other people by making use of the time difference between the private data feed and the public data feed from an exchange. However, market making isn’t risk free and market makers quite often resume substantial risks of adverse selection. On the trading battle fields, market makers face very great challenges. More than once, we noticed that there were discussions on our Discord channel like this: I was performing cross exchange market making between Binance and a small exchange S, all of a sudden, Binance’s best bid price drops dramatically, I immediately sent a request to exchange S to cancel my maker order but only to find out that it has just been filled! Apart from increasing the safety margin of my quotes, what else can be done to prevent it? The goal of this article is to provide partial answers to such questions. Hopefully after going through this article our readers will become better market makers who suffer less on adverse selections.
Let us start the quest for a remedy by recalling our discussions in the previous article about the asynchronous nature of information flow in high frequency trading (HFT) and our observations and experiments on the time difference between the private and public data feed from Kucoin. We know that the private information edge is our friend when we possess it. But because any traders can use the same technique to obtain their information edge over us, we are also vulnerable to this weapon. There are two possible mitigations: one is associated with the private-public information duality and the other is associated with another kind of private information edge (which strictly speaking isn’t an edge over the general public but an edge over the previous version of ourselves). Let us dive straight into the details.
First, we can use public trade information as a mitigation. If you recall our example about Kucoin in the previous article:
https://docs.kucoin.com/#match-execution-data is the public channel for Kucoin’s websocket feed which provides public trades information in realtime.
https://docs.kucoin.com/#private-order-change is the private channel for Kucoin’s websocket feed which provides private trades information in realtime.
By the private-public information duality, we mean that for the same underlying event happening on the exchange server, private and public information arrive at our trading server at slightly different times. If the private information arrives before the public one, we possess private information edge. Otherwise, we don’t. And when we don’t, we’d use the public information (which comes before the private information) as a mitigation method. For example, on UTC time 2023–05–02, we had a buy order resting on the order book of Kucoin’s BTC/USDC with client order id 1683032436483. At 13:29:03.098640, our trading server received a public data feed from Binance that the best bid price of it’s usdt margined perpetual future BTCUSDT instantly dropped quite a lot. Our fair pricing model performed a swift calculation and concluded that Kucoin’s BTC/USDC’s fair bid price should be now below 28042.3. Since our maker buy order was at 28046.5 (with size 0.0005081), the trading server decided to cancel this order so as to avoid adverse selection. Therefore at 13:29:03.099125 (i.e. 0.139 milliseconds later) we sent out a request to cancel this order.
13:29:03.099 Request cancel order 1683032436483
13:29:03.105 Public - lastPrice: 28046.5, lastSize: 0.0005081
13:29:03.105 Use public trade exact match to close private order 1683032436483
13:29:03.117 Private trade for 1683032436483, price: 28046.5, quantity: 0.0005081
Then instead of receiving any acknowledgement or confirmation for cancellation, 6 milliseconds passed, at 13:29:03.105 we received a message from the public trade data feed which told us that there was a public trade happening at price 28046.5 and size 0.0005081. These happen to exactly match the price and size of our own order 1683032436483, the one that we just sent out a cancellation request a moment ago! Could we make a wild guess that this public information was pointing at our private order? Probably yes. Indeed, some 12 milliseconds later at 13:29:03.117 we received a solid confirmation from the exchange about the fill through the private data feed. If any arbitrage action was planned, then probably the action should have been taken at the time of 13:29:03.105 rather than 12 milliseconds later. From repetitive experiments, it turned out that such “guesses” were very accurate if our order sizes were unique enough on the order book. We leave a few questions here for the curious readers to think about: [1] Under what circumstances might our order sizes not be unique enough for us to make such guesses? [2] Under what circumstances might (or not!) we use the public order book data feed (as opposed to public trade data feed) to “guess close” our private orders? This concludes our discussion on the first mitigation.
Second, we can use order cancellation error response as a mitigation. By the order cancellation error response, we mean that if we try to cancel an order that has already been closed on the exchange, we might receive an error response. For example, on Kucoin, find out any of your orders that has already been filled, try to cancel it via the REST API endpoint https://docs.kucoin.com/#cancel-an-order, what response do you receive? It is an error response with error code 400100
. If we are sure that our maker order is resting on the order book, we try to cancel such an order and receive this error response, we’d know that our order has just been filled. Sometimes this error response comes back extremely fast, faster than any other information. So let’s make good use of it without waiting for another several hundred milliseconds. However, be careful that we have to be very sure that the exchange’s behaviors on such error responses are very consistent.
To sum up, in this article we introduced two possible ways for a market maker to mitigate adverse selection in high frequency trading: one through public data feed and the other from API error responses. If you are interested in our work or collaborating with us, join us on Discord: https://discord.gg/b5EKcp9s8T and find us on Github: https://github.com/crypto-chassis/ccapi 🎉. We specialize in market data collection, high speed trading system, infrastructure optimization, and proprietary market making.
Disclaimer: This is an educational article rather than investment/financial advice.