In the previous post I integrated a new order type – market – into the order book, implemented price and time priority rules for market orders, and started matching them. I tested and implemented the simplest case – matching incoming market order against outstanding limit order. In this post I am going to continue using Cucumber to test-drive the implementation of another use case: matching incoming limit order to outstanding market one. The complete source code for this and other posts in the series is available from my GitHub repo: https://github.com/prystupa/scala-cucumber-matching-engine
Crossing Limit Order with Outstanding Market Orders
What happens when an incoming limit order crosses with a market order in the opposite book? At what price should they cross? The actual rule is a bit involved:
- If the opposite book does not have outstanding limit orders, then the trade settles at the incoming order’s limit price
- “Best limit” price improvement rule: if the opposite book does have limit orders, the trade settles at the better of two prices – the incoming order’s limit or the best limit from the opposite book – the term “better of two prices” is from the point of view of the incoming limit order. In other words, if incoming limit order would have crossed with outstanding opposite “best limit” order in the absence of market order, then trade at that, potentially improved, “best limit” price.
To implement this logic it is useful to have OrderBook class maintain the notion of “best limit” price at any time. Lets capture the different possible scenarios in a Cucumber script:
Note that “best limit” is not always available. There is no best limit price when the book is empty or when it contains only market orders. We did capture all those scenarios. We now have to implement the supporting steps for new grammar:
As usual run the tests to see them fail first. Now the implementation is quite trivial thanks to the choice of data structures we made to maintain prices levels in the OrderBook:
Run the tests again and the all green! We are now ready to implement the matching itself. As usual, lets start with the tests:
Here we test different combinations of incoming limit orders crossing with market orders WITH and WITHOUT the “best limit” order in the opposite book. Run the test, see them red. The following code in the MatchingEngine class implements the requirement:
The most interesting code is at lines 25-28. When a limit order crosses with market we know the trade is going to happen, the only question is: at what price? We first consult the opposite order book for its best limit price. If it has it and it improves the incoming limit price, we trade at this price. Otherwise, we just trade at the incoming order’s limit price.
In the next post I’ll tackle the trickiest case in matching market orders – crossing market orders with market orders.
Previous posts in this series:
- Prototyping a Matching Engine with Scala and Cucumber
- Matching Engine – Crossing Limit Orders
- Matching Engine – Market Orders