On Oct 31st, we saw a flash crash on Deribit which triggered undue liquidations for many traders. This happened because Deribit’s algorithms calculated an index-price which did not reflect true BTC-USD price, at the time of the crash. Their risk systems further used incorrect mark-price and started liquidating positions which caused the traded price to crash.
In this post I look to explore what happened with Deribit index and where did the index methodology or algorithm go wrong.
How does Deribit index work? (skip)
Deribit BTC Index calculation has 3 key steps:
1) Poll spot price data from multiple spot exchanges
2) Remove outliers from those prices, i.e. remove the max and min value of the spot price
3) Average the remaining prices to determine the index price
The methodology is good in the sense that it triangulates prices from various exchanges and does not rely on any single source. However, it doesn’t seem to take into account cases when one or more of the sources becomes unhealthy, unavailable or reports stale data. Something, which happened on the evening of Oct 31st.
What happened at Coinbase
Coinbase Pro, which is part of Deribit BTC index, experienced an outage on Oct 31. If you look at Coinbase’s status-page on Oct 31, you’d find that around 13:00 PDT Coinbase decided to implement a small bug-fix on their BTC-USD product. Their BTC-USD market went into an auction at roughly 13:20 PDT and only resumed at 14:27 PDT or 9:30 pm London time (30mins after the crash).
During this time Coinbase API was not throwing any price. See screenshot below.
1572551700000000000 is October 31, 2019 7:55:00 PM
1572556500000000000 is October 31, 2019 9:15:00 PM
It’s noteworthy that Coinbase BTC-USD price was unavailable and unreliable for almost an hour before the crash happened on Deribit (9:00 pm UTC). During this time everything seemed to work fine. The outlier removal algorithm handled this perfectly by removing Coinbase price and hence nothing was impacted. The problem was not with the data-feed!
What happened at LMAX
At 9:00 pm UTC LMAX, another constituent of Deribit index, halted trading. This trading break is a daily affair on LMAX and lasts for 5 minutes. Thus we had 2 exchanges which were affected at the same time. It seems that Deribit’s outlier removal algorithm removed prices from one exchange but the other faulty price was used for calculations and that’s what caused the Deribit’s BTC index price to crash.
Let’s see the calculations
Number of exchanges in consideration set before crash: 7
Coinbase price = 0 or NA
Prices from other 6 exchanges ~ 9150
Exchanges used for averaging: Middle 5
Average of prices from 5 exchanges in the middle ~ 9150
At 9:00 pm UTC, when LMAX went offline
No. of exchanges in consideration set: 7
Price from Coinbase = 0 or NA
Price from LMAX = 0 or NA
Price from other 5 exchanges ~ 9150
Exchanges used for averaging: Middle 5
Average of prices from 5 exchanges in middle: (9150+9150+9150+9150+0)/5 = $7320.
The price to which Deribit BTC index slipped on Halloween night was as low as $7300. See chart below.
Deribit’s algo did not remove exchanges which were offline or under auction (post-only / cancel-only) mode from the consideration set. Since both LMAX and Coinbase were non-operational at the time of the crash, prices from both should have been ignored before checking for outliers and finding average price.
Following the event, in order to give stability to their index, Deribit removed Coinbase from its index calculations. About 48 hours later Coinbase Pro was already included but LMAX price was removed from index calculations. Ideally speaking, none of these exchanges had an issue and should not have been removed from the index.
It’s common for exchanges (crypto & otherwise) to go offline, experience inconstant connectivity, go for maintenance etc. The index price calculation algorithm should have accounted for such cases. Anytime an exchange is not supplying data or is reporting data which is stale (infrequent trading) it’s prices should not be used for index calculations and this should happen in real-time.
At Delta Exchange we have built for these situations. Any exchange that is under maintenance or is not sending latest data is dynamically removed from our index composition.
Coinbase Pro is also a part of BTC Index at Delta Exchange (.DEXBTUSD). Since we remove exchanges that are offline or are giving stale data, the BTC-USD index price on Delta Exchange did not crash.
Furthermore, if all the spot exchanges are down then we disrupt the market to avoid any unnecessary liquidations. Trading resumes via open auction when a healthy spot is available.
Index design is a complex topic and getting it wrong has huge repercussions. It remains an under-appreciated problem in our industry and deserves more thought than it currently garners. All said, it’s difficult to account for all possible scenarios with any index design and there will always be cases that one has never anticipated. Though Deribit’s design was good and covered most cases it left some loopholes which caused the crash.
On Delta Exchange we have given lot of thought to index design. Since we list Altcoins such as XTZ, ATOM, BAT, RVN etc., which are a lot more volatile than BTC, ETH and are not as widely traded on spot exchanges this problem becomes extra important for us.
In the next few posts I will cover more nuances that go into index design. These range from selecting the right base and quoting currencies, right venues to take prices from, accounting for order book depth, accounting for dispersion amongst sources etc. Do comment and share your ideas on how to make a robust index for cryptos.
Lastly, there are lot of learnings from this event at Deribit but there is one question which is still unanswered:
1) Deribit’s index price went down and liquidations were triggered by the liquidation engine. Hence the bid side of the order book on BTC contracts collapsed – that’s understandable. Why did the offer side collapse?
Who was willing to sell BTC contracts sub 9000 on Deribit? Ideally the spread should have widened and the top of the order-book should have looked like 7200-9000, which did not happen. Why?
Let us know your thoughts on this.