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
73 lines
3.0 KiB
Python
73 lines
3.0 KiB
Python
#!/usr/bin/env python3
|
|
"""Sorveglianza giornaliera della CHIAVE DI SCALA del libro (SPEC-scale-key §6.4).
|
|
|
|
uv run python scripts/live/scale_watch.py # osserva e stampa, invia se ALLARME
|
|
uv run python scripts/live/scale_watch.py --secco # osserva e stampa, NON invia nulla
|
|
uv run python scripts/live/scale_watch.py --quiet # una riga sola (per il cron)
|
|
|
|
Tre domande, tre azioni diverse, tre stati (OK / ALLARME / NON MISURABILE).
|
|
Non impedisce la modifica: la rende visibile entro 24 ore e attribuibile.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
sys.path.insert(0, str(Path(__file__).resolve().parents[2]))
|
|
|
|
from src.live.notifier import notify # noqa: E402
|
|
from src.live.scale_watch import ALLARME, OK, run_once # noqa: E402
|
|
|
|
|
|
def _sender(testo: str):
|
|
try:
|
|
notify(testo)
|
|
return True, "telegram"
|
|
except Exception as e: # P3: si registra dove lo si ingoia
|
|
return False, f"{type(e).__name__}: {e}"
|
|
|
|
|
|
def main() -> None:
|
|
secco = "--secco" in sys.argv
|
|
quiet = "--quiet" in sys.argv
|
|
rep = run_once(sender=None if secco else _sender)
|
|
icona = {OK: "✅", ALLARME: "🚨"}.get(rep["stato"], "⚠️")
|
|
if quiet:
|
|
fb = rep["fallback"]
|
|
q = f"{100*fb['quota']:.2f}%" if "quota" in fb else "n/d"
|
|
print(f" scale_watch: {icona} {rep['stato']} · scala {rep['scala_dichiarata']:.2f}x · "
|
|
f"fallback {q} · {rep['invio']}")
|
|
return
|
|
print("=" * 88)
|
|
print(f" SCALE WATCH — la chiave di scala del libro {icona} {rep['stato']}")
|
|
print("=" * 88)
|
|
print(f" scala dichiarata : {rep['scala_dichiarata']:.2f}x "
|
|
f"(scaletta {rep['ladder']}, tetto {rep['tetto']:.2f}x — costanti di CODICE)")
|
|
for nome, d in rep["domande"].items():
|
|
print(f"\n {nome} [{d['stato']}] {d['motivo']}")
|
|
if d.get("azione") and d["azione"] != "nessuna":
|
|
print(f" → azione: {d['azione']}")
|
|
fb = rep["fallback"]
|
|
if fb.get("stato") == "NON MISURABILE":
|
|
print(f"\n fallback [{fb['stato']}] {fb.get('motivo')}")
|
|
else:
|
|
print(f"\n fallback [{fb['stato']}] equity illeggibile in {fb['fallback_veri']}/{fb['giri']} "
|
|
f"giri ({100*fb['quota']:.2f}%, soglia {100*fb['soglia']:.0f}%) — "
|
|
f"{fb['paper']} giri pre-finanziamento esclusi, li' il libro non invia affatto")
|
|
print(f"\n lettore di produzione [{rep['lettore']['stato']}] {rep['lettore']['motivo'][:150]}")
|
|
print(f"\n invio: {rep['invio']}")
|
|
|
|
|
|
USO = """uso: scale_watch.py [--quiet] [--secco]
|
|
|
|
uv run python scripts/live/scale_watch.py # osserva e stampa, invia se ALLARME
|
|
uv run python scripts/live/scale_watch.py --secco # osserva e stampa, NON invia nulla
|
|
uv run python scripts/live/scale_watch.py --quiet # una riga sola (per il cron)
|
|
|
|
Dettaglio nel docstring in testa al file."""
|
|
|
|
if __name__ == "__main__":
|
|
from src.live.cli import valida
|
|
valida("scale_watch.py", USO, flag=("--quiet", "--secco"), con_valore=())
|
|
main()
|