from __future__ import annotations from mcp_common.microstructure import orderbook_imbalance def test_orderbook_imbalance_balanced(): bids = [[100.0, 1.0], [99.5, 1.0], [99.0, 1.0]] asks = [[100.5, 1.0], [101.0, 1.0], [101.5, 1.0]] out = orderbook_imbalance(bids, asks, depth=3) assert abs(out["imbalance_ratio"]) < 0.01 # bilanciato assert out["bid_volume"] == 3.0 assert out["ask_volume"] == 3.0 assert out["microprice"] is not None def test_orderbook_imbalance_bid_heavy(): bids = [[100.0, 5.0], [99.5, 5.0]] asks = [[100.5, 1.0], [101.0, 1.0]] out = orderbook_imbalance(bids, asks, depth=2) assert out["imbalance_ratio"] > 0.5 # forte bid pressure assert out["bid_volume"] == 10.0 assert out["ask_volume"] == 2.0 def test_orderbook_imbalance_ask_heavy(): bids = [[100.0, 1.0], [99.5, 1.0]] asks = [[100.5, 5.0], [101.0, 5.0]] out = orderbook_imbalance(bids, asks, depth=2) assert out["imbalance_ratio"] < -0.5 def test_orderbook_imbalance_microprice_skew(): """Microprice è weighted mid: pesato bid/ask depth opposto.""" bids = [[100.0, 9.0]] asks = [[101.0, 1.0]] out = orderbook_imbalance(bids, asks, depth=1) # large bid → microprice closer to ask (paradox: weighted by *opposite* size) assert out["microprice"] > 100.5 def test_orderbook_imbalance_empty(): out = orderbook_imbalance([], [], depth=5) assert out["imbalance_ratio"] is None assert out["microprice"] is None def test_orderbook_imbalance_one_sided(): out = orderbook_imbalance([[100.0, 1.0]], [], depth=1) assert out["imbalance_ratio"] == 1.0 # all bid def test_orderbook_imbalance_slope(): """Slope = velocity of liquidity dropoff: ripido = poca liquidità in profondità.""" bids_steep = [[100.0, 10.0], [99.0, 1.0]] # depth crolla → slope alto asks_steep = [[101.0, 10.0], [102.0, 1.0]] out = orderbook_imbalance(bids_steep, asks_steep, depth=2) assert out["bid_slope"] is not None # bid liquidity drops by 9 per 1 price unit → slope ~9 assert out["bid_slope"] > 5.0