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:
AdrianoDev
2026-04-27 23:58:07 +02:00
parent 867180f4bf
commit a13e3fe045
21 changed files with 1922 additions and 1 deletions
+77
View File
@@ -6,9 +6,11 @@ import httpx
import pytest
import pytest_httpx
from mcp_macro.fetchers import (
fetch_breakeven_inflation,
fetch_economic_indicators,
fetch_macro_calendar,
fetch_market_overview,
yield_curve_metrics,
)
# --- fetch_economic_indicators ---
@@ -183,3 +185,78 @@ async def test_market_overview_happy(httpx_mock: pytest_httpx.HTTPXMock):
assert result["gold"] == 2412.5
assert result["vix"] == 18.3
assert "data_timestamp" in result
# --- yield_curve_metrics ---
def test_yield_curve_metrics_normal_curve():
out = yield_curve_metrics({"us2y": 4.0, "us5y": 4.2, "us10y": 4.5, "us30y": 4.8})
assert out["slope_2y10y"] == 0.5
assert out["slope_5y30y"] == 0.6
assert out["regime"] == "steep"
# butterfly: 2*4.5 - 4.0 - 4.8 = 0.2
assert out["butterfly_2_10_30"] == 0.2
def test_yield_curve_metrics_inverted():
out = yield_curve_metrics({"us2y": 5.5, "us5y": 5.0, "us10y": 4.5, "us30y": 4.3})
assert out["slope_2y10y"] == -1.0
assert out["regime"] == "inverted"
def test_yield_curve_metrics_partial_data():
out = yield_curve_metrics({"us10y": 4.5})
assert out["slope_2y10y"] is None
assert out["regime"] == "unknown"
# --- fetch_breakeven_inflation ---
@pytest.mark.asyncio
async def test_breakeven_no_key():
out = await fetch_breakeven_inflation(fred_api_key="")
assert "error" in out
@pytest.mark.asyncio
async def test_breakeven_happy_path(httpx_mock: pytest_httpx.HTTPXMock):
for series_id, val in [("T5YIE", "2.3"), ("T10YIE", "2.5"), ("T5YIFR", "2.7")]:
httpx_mock.add_response(
url=httpx.URL(
"https://api.stlouisfed.org/fred/series/observations",
params={
"series_id": series_id,
"api_key": "k",
"file_type": "json",
"sort_order": "desc",
"limit": "1",
},
),
json={"observations": [{"value": val}]},
)
out = await fetch_breakeven_inflation(fred_api_key="k")
assert out["breakevens"]["be_5y"] == 2.3
assert out["breakevens"]["be_10y"] == 2.5
assert out["breakevens"]["be_5y5y_forward"] == 2.7
assert out["interpretation"] == "anchored"
@pytest.mark.asyncio
async def test_breakeven_high_inflation(httpx_mock: pytest_httpx.HTTPXMock):
for series_id in ("T5YIE", "T10YIE", "T5YIFR"):
httpx_mock.add_response(
url=httpx.URL(
"https://api.stlouisfed.org/fred/series/observations",
params={
"series_id": series_id,
"api_key": "k",
"file_type": "json",
"sort_order": "desc",
"limit": "1",
},
),
json={"observations": [{"value": "3.5"}]},
)
out = await fetch_breakeven_inflation(fred_api_key="k")
assert out["interpretation"] == "high_inflation_expected"