Skip to content
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

Market and Limit Oder Filling Logic #40

Merged
merged 14 commits into from
Feb 24, 2024
Merged

Conversation

crnbarr93
Copy link
Collaborator

Closes: #12 #13

What is the purpose of the change

This pull request is to add the logic for filling market orders and, by extension, specially placed limit orders. Orders are filled by crossing ticks in ascending/descending order bounded by the orderbook's next tick data (and placed tick id for limit orders) and filling from currently placed orders.

Due to mutability issues with storage all orders that are being fulfilled are assigned as a Fulfilment, noting the order and how much is to be filled. Once all ticks have been crossed or the placed order is filled all of the Fulfilment structs are resolved. Resolving a Fulfilment involves generating a BankMsg::Send for the order, updating TICK_LIQUIDITY and updating or removing the order as necessary.

The resolved Fulfilment structs are returned as a vector of bank messages in order to transfer funds to the order maker. The placed order's appropriate transfer message is then appended before returning.

Testing and Verifying

This change added tests and can be verified as follows:

cargo run unit-test test_resolve_fulfilments
cargo run unit-test test_run_market_order
cargo run unit-test test_run_limit_order
  • A large amount of test cases were added for each method and can be found in /contracts/orderbook/src/tests/test_order.sh

@crnbarr93 crnbarr93 linked an issue Feb 21, 2024 that may be closed by this pull request
Copy link
Collaborator

@AlpinYukseloglu AlpinYukseloglu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice job! Left a few comments on a first pass. Happy to discuss offline on best way to address

price: Decimal,
) -> Result<BankMsg, ContractError> {
ensure!(
self.quantity >= quantity,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this be the other way around? With this check, partial fills fail with the error "Order does not have enough funds" which doesn't seem right

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe fulfil is a misleading name, if it was the other way around the quantity in the order struct could potentially go negative? We could pass in the total amount and take the min inside this function if that makes more sense?

@@ -36,6 +38,69 @@ impl LimitOrder {
quantity,
}
}

// Transfers the specified quantity of the order's asset to the owner
pub fn fulfill(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thoughts on simplifying the naming here to fill/fills (as opposed to fulfillment/fulfillments) to better align with standard orderbook terminology?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

) -> Result<Vec<BankMsg>, ContractError> {
let mut market_order: MarketOrder = order.clone().into();
let (fulfillments, order_fulfillment_msg) =
run_market_order(storage, &mut market_order, Some(order.tick_id))?;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm run_limit_order feels a bit confusing as an abstraction. Might be worth considering renaming to something like fill_limit_to_tick. But also, this is pretty much just doing a market order with a bound, so it might be cleaner to do the following:

  1. Move the resolve_fulfillments logic into run_market_order, as technically the market order should not be "complete" until the collected fills are actually resolved and written to state
  2. Remove this abstraction and just call run_market_order with the correct tick bound in place_limit logic when appropriate (i.e. when bid limit tick > next ask or ask limit tick < next bid)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Can't be done due to the mutability concerns, we could rename this method and abstract the run_market_order name/logic similar to the current run_limit_order?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Yea that makes sense, I'll comment the tests and we can replicate the cases for place_limit.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For 2: ebfe61a

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Created an issue tracking this at #42. Moving the logic into place_limit can be done in a separate PR

Copy link
Collaborator

@AlpinYukseloglu AlpinYukseloglu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM on another skim. #42 and tying in price conversion from #41 can be in a separate PR to not block this one further

@AlpinYukseloglu AlpinYukseloglu merged commit c6b008e into main Feb 24, 2024
2 checks passed
@AlpinYukseloglu AlpinYukseloglu deleted the connor/fill-limit branch February 24, 2024 00:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Orderbook]: Tick crossing logic [Orderbook]: Limit order filling logic
2 participants