feat: 15 nuovi indicatori quant (common + deribit + bybit + macro + sentiment)
Common (mcp_common): - indicators.py: vol_cone, hurst_exponent, half_life_mean_reversion, garch11_forecast, autocorrelation, rolling_sharpe, var_cvar - options.py (nuovo): oi_weighted_skew, smile_asymmetry, atm_vs_wings_vol, dealer_gamma_profile, vanna_charm_aggregate - microstructure.py (nuovo): orderbook_imbalance (ratio + microprice + slope) - stats.py (nuovo): cointegration_test Engle-Granger + ADF helper Deribit (+6 tool MCP): - get_dealer_gamma_profile (net dealer gamma + flip level) - get_vanna_charm (vanna/charm aggregati pesati OI) - get_oi_weighted_skew, get_smile_asymmetry, get_atm_vs_wings_vol - get_orderbook_imbalance Bybit (+2 tool MCP): - get_orderbook_imbalance, get_basis_term_structure (futures dated curve) Macro (+2 tool MCP): - get_yield_curve_slope (2y10y/5y30y + butterfly + regime) - get_breakeven_inflation (FRED T5YIE/T10YIE/T5YIFR) Sentiment (+3 tool MCP): - get_funding_arb_spread (opportunità arb compatte annualizzate) - get_liquidation_heatmap (heuristic da OI delta + funding extreme, no feed paid Coinglass) - get_cointegration_pairs (Engle-Granger su coppie crypto Binance hourly) Tutto in TDD pure-Python (no numpy/scipy in mcp_common). README aggiornato con elenco completo. 442 test totali verdi. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
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
|
||||
Reference in New Issue
Block a user