Files
PythagorasGoal/tests/test_trades_report.py
T
Adriano Dal Pastro de83909db9 un flag sconosciuto non e' l'azione di default: guardia su 18 script, indice USDE orario, pulizia
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
2026-09-02 15:49:40 +00:00

94 lines
4.0 KiB
Python

"""`trades_db.py --report` non stampa piu' un bonifico come rendimento (debito #14, 2026-09-02).
Il numero che stampava era `e1/e0-1` sulla serie grezza: «+243%» per il 96,3% un versamento.
Il report ora CHIAMA `journal.rendimento_twr` (P1: non rifa' il conto). `T.connect()` nudo
finisce in tmp grazie alla fixture autouse di conftest: qui non si tocca il libro vivo.
"""
from __future__ import annotations
import sys
from pathlib import Path
import pandas as pd
ROOT = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(ROOT))
from helpers import carica_script # noqa: E402
from src.live import journal as J # noqa: E402
from src.live import tradesdb as T # noqa: E402
def _carica_script():
return carica_script("scripts/live/trades_db.py", "trades_db_script")
def _px_piatto(livello=100.0):
ix = pd.date_range("2026-08-20", "2026-08-27", freq="1h", tz="UTC")
return pd.Series(livello, index=ix)
def _prepara(con, equity):
# il fill si scrive con `upsert_fills`, non con un INSERT a mano: una riga scritta a mano
# aveva `verified` NULL, una forma che la produzione non produce mai
T.upsert_fills(con, [T.Fill(ts_utc="2026-08-24T10:47:15+00:00", ts_source="test",
asset="BTC", side="buy", qty=0.001, price=60000.0, fee=0.01)])
T.upsert_equity(con, [(ts, eq, "test") for ts, eq in equity])
def test_il_report_stampa_il_TWR_e_non_il_grezzo(monkeypatch, capsys):
monkeypatch.setattr(J, "_px_1h", lambda a: _px_piatto())
con = T.connect() # -> tmp (conftest), NON data/live/trades.db
assert "data/live" not in str(con.execute("PRAGMA database_list").fetchone()[2])
_prepara(con, [("2026-08-24T10:47:01+00:00", 600.0),
("2026-08-25T10:47:01+00:00", 630.0), # +5%: sotto soglia rilevatore
("2026-08-25T11:47:01+00:00", 2030.0), # +1400: versamento
("2026-08-26T10:47:01+00:00", 2009.7)]) # -1%
con.close()
_carica_script().report()
out = capsys.readouterr().out
assert "TWR" in out and "+3.95%" in out
assert "+234.95%" not in out # il grezzo non compare piu'
assert "+1,400.00 certi" in out
assert "+9.70" in out
assert "movimenti di capitale INCLUSI" in out # il delta $ resta, etichettato
def test_il_report_senza_movimenti_dice_lo_stesso_numero_di_prima(monkeypatch, capsys):
monkeypatch.setattr(J, "_px_1h", lambda a: _px_piatto())
con = T.connect()
_prepara(con, [("2026-08-24T10:47:01+00:00", 600.0), ("2026-08-25T10:47:01+00:00", 630.0)])
con.close()
_carica_script().report()
out = capsys.readouterr().out
assert "+5.00%" in out and "movimenti capitale" not in out
def test_il_report_a_base_zero_dice_n_d_e_non_l_intero_conto(monkeypatch, capsys):
monkeypatch.setattr(J, "_px_1h", lambda a: _px_piatto())
con = T.connect()
_prepara(con, [("2026-08-24T09:47:01+00:00", 0.0),
("2026-08-24T10:47:01+00:00", 598.06),
("2026-08-25T10:47:01+00:00", 610.0)])
con.close()
_carica_script().report()
out = capsys.readouterr().out
assert out.count("n/d") >= 2 and "TWR" in out
assert "+610.00 di equity" in out and "arming : +610.00" not in out
def test_il_report_con_il_feed_assente_non_stampa_il_grezzo_come_TWR(monkeypatch, capsys):
# revisione 02/09: con data/raw assente (host ripristinato prima di rebuild_history) ogni
# salto era "ambiguo", certi=0, e il report stampava +243% sotto l'etichetta TWR
monkeypatch.setattr(J, "_px_1h", lambda a: None)
con = T.connect()
_prepara(con, [("2026-08-24T10:47:01+00:00", 600.0),
("2026-08-25T11:47:01+00:00", 2000.0),
("2026-08-26T10:47:01+00:00", 2020.0)])
con.close()
_carica_script().report()
out = capsys.readouterr().out
assert out.count("n/d") >= 2 and "TWR" in out
assert "% =" not in out and "+236" not in out
assert "[ambiguo: mercato non misurabile" in out