An in-memory limit order book with a single entry point: place_order. The function attempts to match the incoming order against the opposite side and then adds any remaining quantity to the book.
An incoming sell order should be attempted to match/trade with the best existing buy orders on the book, a best buy order would be the one with the highest price (willing to pay the most ), a best selling order on the sell side is the one that is willing to sell for the least price:
- Price–time priority. Fill the oldest orders at the best price level first.
- Trade price = resting (book) order’s price.
- Partial fills allowed. Remove fully filled resting orders; decrease quantity otherwise.
- Remainder: if the incoming order still has quantity, add it to the book at its limit price with newest time priority.
- No cancels, no expiries, no self-match prevention (keep it simple).
Implement in Rust or Go:
place_order(side, price, quantity) -> trades- side:
BuyorSell - price: integer
- quantity: integer
- returns: list of trades
(buy_order_id, sell_order_id, price, quantity)in match order
- side:
best_bid() -> Option<(price, tatal_quantity)>total_quantity being the sum of all orders quantities at that price .best_ask() -> Option<(price, tatal_quantity)>
OrderBook trait has two implementations (as attempt to experiment with performance):
- module
hp_ob-- withVecDequeto store resting orders (Optimal for the most part and doesn't limit how many resting orders) - module
fcb_ob-- with customFastCircularBufferto store resting orders
cargo build
cargo test
cargo bench
Usage:
// Create in-memory limit order book
let mut book = LimitOrderBook::new();
// Add sell order
// Results in empty trades as there is currently nothing in the book
let _trades = book.place_order(Side::Sell, 105, 100);
// Add buy order
// Results in one trade and sell trade still in the book,
// but now with quantity 93
let trades = book.place_order(Side::Buy, 250, 7);
assert_eq!(None, book.best_bid()); // Above order fullfilled and never made it into book
assert_eq!(Some((105, 93)), book.best_ask());