""" Tests for sim/queue.py — queue position model. """ from sim.queue import QueueModel, QueuePosition, fill_probability class TestQueueModel: def test_place_bid(self): qm = QueueModel() oid = qm.place_order("bid", 50000.0, 0.01, sim_time=100.0) tob = qm.top_of_book() assert tob["best_bid"] == 50000.0 assert tob["best_ask"] == 0 # no asks placed def test_queue_position_is_front(self): qm = QueueModel() oid = qm.place_order("ask", 50002.0, 0.01, sim_time=100.0) qp = qm.queue_position("ask", 50002.0, oid) assert qp is not None assert qp.position == 0 assert qp.is_front def test_queue_position_behind_others(self): qm = QueueModel() qm.place_order("bid", 50000.0, 0.01, sim_time=99.0) oid2 = qm.place_order("bid", 50000.0, 0.01, sim_time=100.0) qp = qm.queue_position("bid", 50000.0, oid2) assert qp is not None assert qp.position == 1 # behind first order def test_cancel_order(self): qm = QueueModel() oid = qm.place_order("bid", 50000.0, 0.01, sim_time=100.0) filled = qm.cancel_order(oid, sim_time=105.0) assert filled == 0.0 assert qm.order_status(oid)["status"] == "cancelled" assert len(qm.active_orders()) == 0 def test_trade_eats_ask(self): qm = QueueModel() oid = qm.place_order("ask", 50002.0, 0.01, sim_time=100.0) fills = qm.process_trade("buy", 50002.0, 0.01, sim_time=101.0) assert len(fills) == 1 assert fills[0]["size"] == 0.01 def test_trade_eats_bid(self): qm = QueueModel() oid = qm.place_order("bid", 50000.0, 0.02, sim_time=100.0) fills = qm.process_trade("sell", 50000.0, 0.01, sim_time=101.0) assert fills[0]["size"] == 0.01 assert qm.order_status(oid)["filled"] == 0.01 def test_partial_fill_remaining(self): qm = QueueModel() oid = qm.place_order("bid", 50000.0, 0.03, sim_time=100.0) qm.process_trade("sell", 50000.0, 0.01, sim_time=101.0) status = qm.order_status(oid) assert status["filled"] == 0.01 assert status["status"] == "active" def test_fully_filled_status(self): qm = QueueModel() oid = qm.place_order("bid", 50000.0, 0.01, sim_time=100.0) qm.process_trade("sell", 50000.0, 0.01, sim_time=101.0) assert qm.order_status(oid)["status"] == "filled" def test_trade_crosses_spread(self): qm = QueueModel() qm.place_order("ask", 50002.0, 0.01, sim_time=100.0) qm.place_order("ask", 50003.0, 0.01, sim_time=100.0) fills = qm.process_trade("buy", 50003.0, 0.02, sim_time=101.0) assert len(fills) == 2 def test_top_of_book(self): qm = QueueModel() qm.place_order("bid", 50000.0, 0.01, sim_time=100.0) qm.place_order("ask", 50002.0, 0.02, sim_time=100.0) tob = qm.top_of_book() assert tob["best_bid"] == 50000.0 assert tob["best_ask"] == 50002.0 assert tob["spread"] == 2.0 class TestFillProbability: def test_front_of_queue(self): result = fill_probability(queue_pos=0, total_queue_depth=1.0, order_size=0.01, arrival_rate=1.0, time_horizon=1.0) assert result["fill_probability"] > 0.5 def test_deep_in_queue(self): result = fill_probability(queue_pos=5, total_queue_depth=10.0, order_size=0.01, arrival_rate=1.0, time_horizon=1.0) assert result["fill_probability"] < 0.5 def test_no_arrivals_zero_prob(self): result = fill_probability(queue_pos=0, total_queue_depth=1.0, order_size=0.01, arrival_rate=0.0, time_horizon=1.0) assert result["fill_probability"] == 0.0