-
Notifications
You must be signed in to change notification settings - Fork 23
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: Rewrite order matching strategy #2539
Conversation
d9a8203
to
77d9bcc
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like the idea of defining an orderbook component which keeps the orders in memory, can be optimised for speed (eventually) and has exclusive access to certain DB tables. I think this is the vision suggested by this PR.
Also, I think the last patch is a continuation of an earlier patch. By default I assume that a PR should be reviewed patch by patch, but in this case I think I wasted some time reviewing an earlier version of the same thing. In the future, if you know this is the case, I would appreciate it if you let me know in the PR description or just squashed some patches.
coordinator/src/orderbook/mod.rs
Outdated
let order = if !matches.is_empty() { | ||
// order has been at least partially matched. | ||
let matched_quantity = matches.iter().map(|m| m.quantity).sum(); | ||
|
||
orders::set_order_state_partially_taken(&mut conn, order_id, matched_quantity) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
❓I don't understand what's going on here. Why do we need to do this when a limit order is being removed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because it might have been partially matched already.
Today we are setting an order to deleted regardless if it has been matched or not. IMHO we should only set open orders to deleted, but not taken ones.
However how to deal with orders that have been partially matched? I opted to set the state to taken and reduce the quantity to the amount that has already been matched.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't we do that earlier and not on deletion though. Also, why do we go directly against the database instead of updating the state in the ordebook cache? It seems like the state is only in the DB? Why is that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, why do we go directly against the database instead of updating the state in the ordebook cache? It seems like the state is only in the DB? Why is that?
Both states are updated, first the database and then the orderbook.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't we do that earlier and not on deletion though.
Can you elaborate on that, when do you think this should happen?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the status of this PR? Do we want to continue with it?
I will continue to work on this after the lightning onboarding flow. |
167979c
to
2143ffd
Compare
602eca1
to
f8e9991
Compare
This will allow us to implement partial order matching, by summing the quantity of trades related to an order.
This is already done by the maker, also expired orders are not considered for matching.
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.
The order and the matches are persisted by async actors. It can happen that the market order has not yet been persisted when the match is processed. Thus it could happen that the matches table is persisted before the order has been persisted, which resulted in a foreign key violation. By dropping the foreign key we don't care if the order is already persisted and can continue with eventual consistency. I think this is the better option than to synchronize the two inserts as we are anyways aiming for decoupling the orderbook from the coordinator.
f8e9991
to
51e49ec
Compare
@luckysori @bonomat this PR turned into more refactoring than originally anticipated, although not all issues are addressed yet I think its in a good spot to get into main, before tackling limit orders. Below shows the new design of the orderbook.
There are certainly still some minor things that I'd like to clean up, but its in a good state for your review. |
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:
matches
table accordinglyFilled
from the get go since we do not execute them with our own maker.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.
Example of updated limit orders when deleted.
TODO: