feat(mcp-macro): fetch_cot_extreme_positioning scanner

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
AdrianoDev
2026-04-29 00:06:52 +02:00
parent 2474445b4c
commit dc285daac8
2 changed files with 103 additions and 1 deletions
+65 -1
View File
@@ -5,7 +5,7 @@ from typing import Any
import httpx
from mcp_common.http import async_client
from mcp_macro.cot import parse_disagg_row, parse_tff_row
from mcp_macro.cot import classify_extreme, compute_percentile, parse_disagg_row, parse_tff_row
from mcp_macro.cot_contracts import (
ALL_DISAGG_SYMBOLS,
ALL_TFF_SYMBOLS,
@@ -704,3 +704,67 @@ async def fetch_cot_disaggregated(symbol: str, lookback_weeks: int = 52) -> dict
_COT_CACHE[key] = out
_COT_CACHE_TS[key] = now
return out
async def fetch_cot_extreme_positioning(lookback_weeks: int = 156) -> dict[str, Any]:
"""Scanner posizionamento estremo (percentile <=5 o >=95) sui simboli watchlist.
TFF -> key_role = lev_funds (lev_funds_net).
Disaggregated -> key_role = managed_money (managed_money_net).
"""
import asyncio
tff_tasks = [fetch_cot_tff(s, lookback_weeks) for s in ALL_TFF_SYMBOLS]
disagg_tasks = [fetch_cot_disaggregated(s, lookback_weeks) for s in ALL_DISAGG_SYMBOLS]
tff_results, disagg_results = await asyncio.gather(
asyncio.gather(*tff_tasks, return_exceptions=True),
asyncio.gather(*disagg_tasks, return_exceptions=True),
)
extremes: list[dict[str, Any]] = []
for res in tff_results:
if isinstance(res, BaseException) or not isinstance(res, dict):
continue
rows = res.get("rows") or []
if len(rows) < 4:
continue
series = [r["lev_funds_net"] for r in rows]
current = series[-1]
history = series[:-1]
pct = compute_percentile(current, history)
extremes.append({
"symbol": res["symbol"],
"report_type": "tff",
"key_role": "lev_funds",
"current_net": current,
"percentile": pct,
"signal": classify_extreme(pct),
"report_date": rows[-1]["report_date"],
})
for res in disagg_results:
if isinstance(res, BaseException) or not isinstance(res, dict):
continue
rows = res.get("rows") or []
if len(rows) < 4:
continue
series = [r["managed_money_net"] for r in rows]
current = series[-1]
history = series[:-1]
pct = compute_percentile(current, history)
extremes.append({
"symbol": res["symbol"],
"report_type": "disaggregated",
"key_role": "managed_money",
"current_net": current,
"percentile": pct,
"signal": classify_extreme(pct),
"report_date": rows[-1]["report_date"],
})
return {
"lookback_weeks": lookback_weeks,
"extremes": extremes,
"data_timestamp": datetime.now(UTC).isoformat(),
}