de83909db9
MISURATO oggi durante la revisione: `trades_db.py --help` non stampava l'uso, cadeva in sync() e riscriveva meta.ultimo_sync. Nessuno dei 18 script di scripts/live/ usava argparse: un flag sbagliato era il ramo else. Su journal.py avrebbe scritto pagina e riga di DB, su analista.py avrebbe speso una chiamata al modello e mandato un Telegram. - src/live/cli.valida: prima istruzione di ogni __main__, prima di connect()/sync/rete. --help -> 0 con l'uso; flag ignoto, valore mancante o posizionale -> 2 con l'elenco dei previsti (P4). NIENTE argparse: cambierebbe messaggi, codici d'uscita e --help di script che il cron gia' chiama. - 18 script cablati (i 3 che scrivono + 14 + cc01), flag invariati. - tests/test_cli_flag.py (30): elenco DERIVATO dalla cartella (P1), valida come prima istruzione, uso che documenta i flag, e i flag che il CRON usa davvero restano accettati (P15/P16); end-to-end su --help e flag ignoto con trades.db non toccato (M15). Verificato a mano: monitor_health --quiet, trades_db --sync --quiet, book_execute dry-run. Debito §5.15, primo passo: balance_watch (orario) registra `usde_usdc` a ogni campione — None con la ragione se illeggibile, mai 1,0. Il cablaggio nel bound quando la serie ha storia. Pulizia dalla revisione: tests/helpers.carica_script al posto della 15a copia del loader importlib (5 file del libro live); il fill di prova via upsert_fills invece di un INSERT che lasciava verified NULL; asserzioni non ancorate al padding; movimenti_capitale accetta le righe gia' lette (una SELECT invece di due ai due lati di una scrittura del cron). Test 910 verdi (+52). Diario 2026-09-02c. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XDJsH3iDSaBns3ccpPBwiu
70 lines
2.9 KiB
Python
70 lines
2.9 KiB
Python
#!/usr/bin/env python
|
|
"""monitor_health.py — i forward-monitor stanno registrando? Riporta e allerta, non tocca nulla.
|
|
|
|
Tre gate pre-registrati (STATARB 27/09, XSR01 23/10, DVOLSPREAD 24/10) si decideranno leggendo
|
|
serie forward che, tranne una, **nessuno sorvegliava**. Un monitor fermo produce silenzio, e il
|
|
silenzio in una serie di ritorni si legge come "zero", cioe' come una misura. Non lo e'.
|
|
|
|
Vedi `src/live/monitor_health.py` per le due misure (coda + buchi interni), le cadenze per
|
|
monitor e la soglia di copertura 0.80 (la stessa del veto d'integrita' di DVOLSPREAD).
|
|
|
|
uv run python scripts/live/monitor_health.py # report
|
|
uv run python scripts/live/monitor_health.py --quiet # stampa/allerta solo se scatta
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
ROOT = Path(__file__).resolve().parents[2]
|
|
sys.path.insert(0, str(ROOT))
|
|
|
|
from src.live.monitor_health import MIN_COVERAGE, alerts_from, check_all # noqa: E402
|
|
from src.live.notifier import notify # noqa: E402
|
|
|
|
|
|
def main() -> int:
|
|
rows = check_all(ROOT)
|
|
alerts = alerts_from(rows)
|
|
|
|
if "--quiet" not in sys.argv or alerts:
|
|
print("=" * 92)
|
|
print(" MONITOR HEALTH — i forward-monitor stanno ancora registrando?")
|
|
print("=" * 92)
|
|
print(f"\n {'monitor':<20}{'stato':>10}{'barre':>8}{'attese':>8}"
|
|
f"{'copert.':>10}{'eta ultima':>13} gate che ne dipende")
|
|
for r in rows:
|
|
cov = f"{r['coverage']:.0%}" if r["coverage"] is not None else "-"
|
|
exp = f"{r['expected']}" if r["expected"] is not None else "-"
|
|
age = f"{r['age_h']:.0f}h" if r["age_h"] is not None else "-"
|
|
gate = (r["gate"] or "").split(" — ")[0]
|
|
print(f" {r['name']:<20}{r['status']:>10}{r['n_bars']:>8}{exp:>8}"
|
|
f"{cov:>10}{age:>13} {gate}")
|
|
print(f"\n soglia di copertura {MIN_COVERAGE:.0%} (= veto d'integrita' di DVOLSPREAD) · "
|
|
f"'NUOVO' = troppo giovane per un giudizio, non 'OK'")
|
|
for r in rows:
|
|
if r["why"] and r["status"] != "OK":
|
|
print(f" {r['name']}: {r['why']}")
|
|
|
|
if alerts:
|
|
notify("🩺 MONITOR HEALTH — un forward-monitor non sta registrando",
|
|
{f"alert {i+1}": a for i, a in enumerate(alerts)})
|
|
for a in alerts:
|
|
print(f" ALERT: {a}")
|
|
return 2
|
|
return 0
|
|
|
|
|
|
USO = """uso: monitor_health.py [--quiet]
|
|
|
|
monitor_health.py — i forward-monitor stanno registrando? Riporta e allerta, non tocca nulla.
|
|
uv run python scripts/live/monitor_health.py # report
|
|
uv run python scripts/live/monitor_health.py --quiet # stampa/allerta solo se scatta
|
|
|
|
Dettaglio nel docstring in testa al file."""
|
|
|
|
if __name__ == "__main__":
|
|
from src.live.cli import valida
|
|
valida("monitor_health.py", USO, flag=("--quiet",), con_valore=())
|
|
raise SystemExit(main())
|