Making Amends (Happen)
Hi my name is Pete and I am part of the core engineering team. Recently I took on the ticket to implement amends functionality into the core of the Vega system.
I thought, “how hard can it be to alter an existing order? The hard part of getting the order into the system has been performed already”. Well here is a quick review of some of the things I learnt while making this ‘quick’ change.
How does an amend affect the order book?
If a client needs to reduce the size of an order the matching engine can keep the order in the same place in the order book and just reduce its size. Nothing else needs to be done to keep the order book correct and fair. If a client wants to increase the size of the order, the matching engine cannot just increase it in place as that has an unfair effect on the people behind that order in the price level. This means the matching engine has to remove the order and reinsert it into the back of the price level. The same thing happens if a client tries to amend the price of an order. This produces a very different computation time depending on what is being amended.
Does the client really know the current state of the order?
The first attempt of handling a size change was done using absolute values. This means a client tells the order book to change the order size from A to B. This makes sense if the order has not been filled but if the order has been partially filled the client might end up with a total order size more than they wanted.
Here is an example:
The order book has a client buy order for 100 items at price 500. The client decides they only need 60 items so they send off an amend with a new size of 60. While that order is being sent, the original order is partially filled with 50 items, leaving 50 remaining. When the amend gets to the order book, the size of the remaining order will be increased from 50 to 60. After this is fully filled, the total amount filled for this order will be 110.
To get around this, we have a size delta, which is used to adjust the original size. In the case above, the client would send an amend with a sizeDelta of -40. When the amend reaches the order book, the remaining size of the order would be reduced by 40 down to 10 remaining. Then after being fully filled the total size would be 60, as expected.
When is an amend not an amend?
When clients use the Vega Console to amend orders, basic validation can be performed to make sure the amend makes sense. Sending a price amend for an order where the new price is the same as the current price is such an example. However API users have to validate the values themselves and it is possible for them to send such an amend. How should we handle that amend? Plenty of options exist, we could reject the amend as soon as we realise the price is the same. We could accept the amend but not touch the existing order. How would we let the user know what had happened? After collecting some great feedback from the traders and other coders in the team, we decided to not reject those trades and to update the ModifiedAt field in the order before sending out a fresh OrderResponse message. This way the user can see that the amend was processed but no changes are made to the position of the order in the orderbook.
How do we keep track of all the versions?
Amends take an existing order and change something about it. An order can be amended many times before it is finally filled or cancelled. For reconciliation systems, knowing the history of how the order changed is a requirement and something that the Vega core needs to support. The way we handle this internally is with a version number. Whenever something is changed due to an amend, we update the order and then increment the version number. The order response we give back to the user contains the version number for the live order. If the user wants to get the order information for a previous order, they can query using the orderID and version number to retrieve it. Unlike normal financial exchanges, crypto exchanges run 24/7/365. Orders can stay in the book for the lifetime of the exchange, so to make sure we do not overflow the version storage we are using an unsigned 64 bit value to represent the version number. If the user amends the same order 1,000,000 times a second, the version number will not overflow for around half a million years!