1from market_agents.exchange.book import LimitOrderBook2from market_agents.exchange.orders import Order, OrderType, Side345def mk(oid, side, qty, price, t=0.0, otype=OrderType.LIMIT):6 return Order(order_id=oid, agent_id=oid, asset=0, side=side, order_type=otype, qty=qty, price=price,7 submit_time=t, arrival_time=t)8910def test_price_time_priority():11 b = LimitOrderBook(0)12 b.rest(mk(1, Side.SELL, 5, 101))13 b.rest(mk(2, Side.SELL, 5, 100))14 b.rest(mk(3, Side.SELL, 5, 100))15 inc = mk(9, Side.BUY, 7, 101)16 fills = b.match(inc)17 assert [(f.resting.order_id, f.qty, f.price) for f in fills] == [(2, 5, 100), (3, 2, 100)]18 assert inc.remaining == 019 assert b.best_ask() == 100 and b.get(3).remaining == 320 b.check_invariants()212223def test_limit_does_not_cross_beyond_price():24 b = LimitOrderBook(0)25 b.rest(mk(1, Side.SELL, 5, 105))26 inc = mk(2, Side.BUY, 5, 104)27 assert b.match(inc) == [] and inc.remaining == 528 b.rest(inc)29 assert b.best_bid() == 104 and b.best_ask() == 10530 b.check_invariants()313233def test_market_order_walks_book_and_stops_when_empty():34 b = LimitOrderBook(0)35 b.rest(mk(1, Side.BUY, 3, 99))36 b.rest(mk(2, Side.BUY, 3, 98))37 inc = mk(3, Side.SELL, 10, None, otype=OrderType.MARKET)38 fills = b.match(inc)39 assert sum(f.qty for f in fills) == 6 and inc.remaining == 440 assert b.best_bid() is None41 b.check_invariants()424344def test_cancel_and_depth():45 b = LimitOrderBook(0)46 for i in range(1, 6):47 b.rest(mk(i, Side.BUY, i, 100 - i))48 bids, asks = b.depth(3)49 assert bids == [(99, 1), (98, 2), (97, 3)] and asks == []50 assert b.cancel(2).remaining == 2 and 2 not in b51 assert b.cancel(2) is None52 assert b.depth_within(Side.BUY, 2) == 1 + 353 b.check_invariants()54