Asked at IMC Trading, Hudson River Trading
Theory: Order Books and MatchingRead the problem, hints and solution here. The editor needs a bigger screen: open this page on a laptop to write and run your code.
Available in Python and C++. You are solving it in Python. Switch to C++
You are building the ticker component of a market data feed: after every order book event, it must publish the current top of book (best bid and best ask).
You receive a sequence of events. Each event is one of:
order_id, a side, a price and a qty: a new
limit order enters the book. side is B for a bid (buy) or S for an ask
(sell). Prices are integer ticks. order_id values of add events are
unique.order_id: the order leaves the book. A cancel
may reference an id that was never added or was already cancelled; treat
that as a no-op.Implement top_of_book(events) returning one entry per event: the pair
(best_bid, best_ask) immediately after applying that event. The best bid is
the highest live bid price, the best ask is the lowest live ask price. A side
with no live orders has no price. Order quantity never changes and does not
affect the top of book in this problem.
def top_of_book(
events: list[tuple[str, int, str, int, int] | tuple[str, int]],
) -> list[tuple[int | None, int | None]]: ...
An add is ("add", order_id, side, price, qty) with side as "B" or
"S", and a cancel is ("cancel", order_id). Use None for a side with no
live orders.
Orders are never matched against each other. A bid at or above the best ask does not trade: both orders stay live until they are cancelled, so the book can be crossed (best bid greater than or equal to best ask).
events = [
("add", 1, "B", 100, 5),
("add", 2, "S", 102, 3),
("add", 3, "B", 101, 2),
("cancel", 3),
]
top_of_book(events)
# [(100, None), (100, 102), (101, 102), (100, 102)]