10101
10101 copied to clipboard
feat: Rewrite order matching strategy
I opted to finish this PR up to a point where it can be merged and left a couple of todos that need to get addressed when we start implementing limit orders.
Refactors the current trading component into a clearly separated orderbook component and a trade execution component. The linking part is the ExecutableMatch
which can be derived from the matches stored into the database.
At the moment we assume optimistically that the trade execution will succeed. However, we should consider that a pending match may never get filled or it fails at execution in such a scenario we would need to rollback the matched orders.
An overview of the changes:
- Adds the order id to the trade entry so we can link which order created the trade.
- Allows for orders to get partially matched and update the
matches
table accordingly - Matched limit orders are created as
Filled
from the get go since we do not execute them with our own maker. - (Partially) Matched limit orders are not deleted anymore, but the quantity is updated to how much has already been mapped. (e.g. if an open limit order of $1000 gets deleted with $300 matched it will be updated to
Taken
with a quantity of $300)
Example of a matches table after opening and closing a position of $3576. Note the maker generates $1000 orders.
orderbook=# select execution_price, quantity, order_id, match_order_id from matches where trader_id='032752136072951607b66dd85f236363efab91b315b1c4fc8d9530ee873875108a' and match_state='Filled' order by created_at;
execution_price | quantity | order_id | match_order_id
-----------------+----------+--------------------------------------+--------------------------------------
60001 | 1000 | 42dd8a30-a20d-4640-bddd-f5467a638d28 | 9acc7260-0f24-405e-ad84-550a797b4464
60001 | 1000 | 42dd8a30-a20d-4640-bddd-f5467a638d28 | c486a21c-312e-4ae0-ab35-38a8e93d07d5
60001 | 1000 | 42dd8a30-a20d-4640-bddd-f5467a638d28 | e30ff0dc-4f8a-4888-a3ea-cddf63c94179
60001 | 576 | 42dd8a30-a20d-4640-bddd-f5467a638d28 | adae6065-d78a-4ed6-bab3-9852f395ef67
59999 | 1000 | a6be5b42-8817-40f7-8f86-0615df33c57a | 19811f8f-7fe7-4dd1-9b3a-72f24a0fcee5
59999 | 1000 | a6be5b42-8817-40f7-8f86-0615df33c57a | 6cf3b7bd-2652-4590-afed-f15ece0a1ded
59999 | 1000 | a6be5b42-8817-40f7-8f86-0615df33c57a | 0c8b6575-2ba2-4e37-8aa2-9c0e8beb055d
59999 | 576 | a6be5b42-8817-40f7-8f86-0615df33c57a | 17fcb395-4434-4ca8-9cb2-4ca75ec73063
(8 rows)
Example of updated limit orders when deleted.
orderbook=# select order_id, price, direction, quantity, order_type from orders where order_id in ('19811f8f-7fe7-4dd1-9b3a-72f24a0fcee5', '6cf3b7bd-2652-4590-afed-f15ece0a1ded', '0c8b6575-2ba2-4e37-8aa2
order_id | price | direction | quantity | order_type
--------------------------------------+-------+-----------+----------+------------
19811f8f-7fe7-4dd1-9b3a-72f24a0fcee5 | 59999 | long | 1000 | limit
6cf3b7bd-2652-4590-afed-f15ece0a1ded | 59999 | long | 1000 | limit
0c8b6575-2ba2-4e37-8aa2-9c0e8beb055d | 59999 | long | 1000 | limit
17fcb395-4434-4ca8-9cb2-4ca75ec73063 | 59999 | long | 576 | limit
(4 rows)