| import pytest |
|
|
| from src.microstructure.orderbook import KalshiOrderBook |
| from src.microstructure.collector import TickCollector |
|
|
|
|
| |
|
|
| def test_snapshot_top_of_book(): |
| book = KalshiOrderBook("TEST") |
| book.apply_snapshot(yes=[[40, 100], [38, 50]], no=[[55, 80], [50, 20]]) |
| feats = book.features() |
| assert feats["best_bid"] == 0.40 |
| assert feats["best_ask"] == 0.45 |
| assert feats["bid_size"] == 100 |
| assert feats["ask_size"] == 80 |
| assert feats["spread"] == pytest.approx(0.05) |
| assert feats["mid"] == pytest.approx(0.425) |
|
|
|
|
| def test_delta_adds_and_removes_levels(): |
| book = KalshiOrderBook("TEST") |
| book.apply_snapshot(yes=[[40, 100]], no=[[55, 80]]) |
| book.apply_delta(40, -100, "yes") |
| assert book.features() is None |
| book.apply_delta(42, 30, "yes") |
| assert book.yes_bids == {42: 30} |
| assert book.features()["best_bid"] == 0.42 |
|
|
|
|
| def test_delta_partial_fill(): |
| book = KalshiOrderBook("TEST") |
| book.apply_snapshot(yes=[[40, 100]], no=[[55, 80]]) |
| book.apply_delta(40, -60, "yes") |
| assert book.yes_bids[40] == 40 |
|
|
|
|
| def test_crossed_book_returns_no_features(): |
| book = KalshiOrderBook("TEST") |
| |
| book.apply_snapshot(yes=[[60, 10]], no=[[65, 10]]) |
| assert book.features() is None |
|
|
|
|
| def test_imbalance_and_microprice(): |
| book = KalshiOrderBook("TEST") |
| |
| book.apply_snapshot(yes=[[40, 300]], no=[[55, 100]]) |
| feats = book.features() |
| assert feats["imbalance"] == 0.75 |
| |
| assert feats["microprice"] == pytest.approx(0.4375) |
|
|
|
|
| |
|
|
| def test_collector_applies_snapshot_then_delta(): |
| c = TickCollector(n_markets=1) |
| snap = {"type": "orderbook_snapshot", "seq": 1, |
| "msg": {"market_ticker": "T", "yes": [[40, 100]], "no": [[55, 80]]}} |
| assert c._apply_message(snap) is False |
| assert c.buffer[-1]["best_bid"] == 0.40 |
|
|
| delta = {"type": "orderbook_delta", "seq": 2, |
| "msg": {"market_ticker": "T", "price": 42, "delta": 30, "side": "yes"}} |
| assert c._apply_message(delta) is False |
| assert c.buffer[-1]["best_bid"] == 0.42 |
|
|
|
|
| def test_collector_detects_seq_gap(): |
| c = TickCollector(n_markets=1) |
| c._apply_message({"type": "orderbook_snapshot", "seq": 1, |
| "msg": {"market_ticker": "T", |
| "yes": [[40, 100]], "no": [[55, 80]]}}) |
| gap = {"type": "orderbook_delta", "seq": 5, |
| "msg": {"market_ticker": "T", "price": 42, "delta": 30, "side": "yes"}} |
| assert c._apply_message(gap) is True |
|
|
|
|
| def test_collector_ignores_control_frames(): |
| c = TickCollector(n_markets=1) |
| assert c._apply_message({"type": "subscribed", "msg": {"sid": 1}}) is False |
| assert c.buffer == [] |
|
|