test: isola il watermark nei test del book (leggevano lo stato di produzione)

Il commit precedente e' stato pushato con un test rosso: la catena `&&` leggeva l'exit
code di `tail`, non di pytest. Errore mio, riparato qui.

LA CAUSA E' PIU' SERIA DEL TEST. `test_cap_falls_back_to_fixed_on_eq_fallback` falliva
perche' `_write_cfg` isolava la CONFIG ma non il nuovo watermark: i test leggevano
`data/live/equity_seen.json` REALE, quindi il loro esito dipendeva da quanto c'e' sul
conto vero. Un test che non menziona il watermark cambiava risposta a ogni deposito.

`_write_cfg` ora monkeypatcha anche EQUITY_WATERMARK su tmp_path e accetta un parametro
`watermark` esplicito. Aggiunti due test sul comportamento nuovo:
  - fallback con watermark $596.92 e cap config $3.000 -> $298/asset, leva <= 1x;
  - fallback con watermark $6.047 -> $3.000/asset (il tetto di config).
Il test storico resta e ora documenta il caso "conto mai visto" -> taglia sicura.

393 test verdi (exit code verificato, non dedotto dal tail).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Adriano Dal Pastro
2026-07-26 20:56:03 +00:00
parent 8b21d29e69
commit 28b63cf3a3
+28 -2
View File
@@ -52,11 +52,19 @@ def test_net_target_clamps_negative():
import json as _json
def _write_cfg(monkeypatch, tmp_path, **keys):
def _write_cfg(monkeypatch, tmp_path, watermark: float | None = None, **keys):
"""⚠️ Isola SIA la config SIA il watermark dell'equity. Senza la seconda riga di
monkeypatch questi test leggono `data/live/equity_seen.json` REALE e il loro esito dipende
da quanto c'e' sul conto — difetto trovato il 2026-07-26, quando l'aggiunta del watermark
fece fallire un test che non lo menzionava nemmeno."""
import src.live.book as book
p = tmp_path / "live.json"
p.write_text(_json.dumps(keys))
monkeypatch.setattr(book, "CONFIG", p)
wm = tmp_path / "equity_seen.json"
monkeypatch.setattr(book, "EQUITY_WATERMARK", wm)
if watermark is not None:
wm.write_text(_json.dumps({"real_equity": float(watermark)}))
return book
@@ -68,13 +76,31 @@ def test_cap_dynamic_scales_with_trusted_equity(monkeypatch, tmp_path):
def test_cap_falls_back_to_fixed_on_eq_fallback(monkeypatch, tmp_path):
"""Senza watermark (conto mai visto) il fallback e' la taglia sicura, MAI equity/2 del paper
($1.000 su un conto ignoto = pericoloso). Comportamento storico, invariato."""
book = _write_cfg(monkeypatch, tmp_path, max_notional_per_asset_usd=300, max_notional_per_asset_frac=0.5)
# equity paper (real non leggibile) -> NON usare equity/2 ($1000 su conto ignoto = pericoloso)
assert book._cap(equity=2000.0, real_equity=None, eq_fallback="paper_cap") == 300.0
assert book._cap(equity=2000.0, real_equity=None, eq_fallback=None) == 300.0 # real None -> fisso
assert book._cap(equity=0.0, real_equity=0.0, eq_fallback=None) == 300.0 # equity 0 -> fisso
def test_cap_di_fallback_non_supera_il_conto_osservato(monkeypatch, tmp_path):
"""2026-07-26: col cap di config alzato a $3.000 in previsione di un deposito, il fallback
deve restare legato all'ULTIMA EQUITY VISTA, altrimenti su un conto da $597 permetterebbe
$2.000 di nozionale lordo = 3.35x di leva proprio quando l'equity non e' leggibile."""
book = _write_cfg(monkeypatch, tmp_path, watermark=596.92,
max_notional_per_asset_usd=3000, max_notional_per_asset_frac=0.5)
cap = book._cap(equity=2000.0, real_equity=None, eq_fallback="paper_cap")
assert cap == 596.92 * 0.5
assert 2 * cap <= 596.92, "leva > 1x in fallback"
def test_cap_di_fallback_cresce_col_conto_dopo_un_deposito(monkeypatch, tmp_path):
book = _write_cfg(monkeypatch, tmp_path, watermark=6047.0,
max_notional_per_asset_usd=3000, max_notional_per_asset_frac=0.5)
assert book._cap(equity=2000.0, real_equity=None, eq_fallback="paper_cap") == 3000.0
def test_cap_fixed_when_no_frac_in_config(monkeypatch, tmp_path):
book = _write_cfg(monkeypatch, tmp_path, max_notional_per_asset_usd=300) # niente frac
assert book._cap(equity=5000.0, real_equity=5000.0, eq_fallback=None) == 300.0