fee_watch: realized_fee_bps sempre calcolata, divergenza da tier notificata una volta per episodio (#37 B9)

This commit is contained in:
2026-09-27 15:06:40 +00:00
parent 841d4c78cd
commit 95cfb396e7
2 changed files with 143 additions and 7 deletions
+97 -1
View File
@@ -204,7 +204,10 @@ def test_invio_riuscito_salva_lo_stato(monkeypatch):
salvato, inviato = _prepara(monkeypatch, _RIS_AZIONE, esito_invio=True)
FW.main()
assert len(inviato) == 1
assert len(salvato) == 1 and salvato[0] == _RIS_AZIONE["current"]
# (#37 B9) lo stato salvato porta anche il marcatore "divergenza_detta" (qui False: la
# fixture non ha divergenze), sibling delle fee per-strumento, non piu' solo `current`.
assert len(salvato) == 1
assert salvato[0] == {**_RIS_AZIONE["current"], "divergenza_detta": False}
def test_nessun_invio_dovuto_salva_comunque(monkeypatch):
@@ -213,3 +216,96 @@ def test_nessun_invio_dovuto_salva_comunque(monkeypatch):
FW.main()
assert inviato == [], "senza changes e livello OK non deve tentare l'invio"
assert len(salvato) == 1
# ===========================================================================
# issue #37 (B9) — realized_fee_bps() SEMPRE calcolato (non solo nel blocco di stampa) e
# divergenza dal tier pubblico notificata UNA volta per episodio.
# ===========================================================================
def test_run_calcola_sempre_la_fee_realizzata(monkeypatch):
"""Prima del #37 la fee realizzata girava solo dentro `if not quiet or interessante`: in
cron (--quiet) non girava mai. Ora e' `run()` a calcolarla, sempre."""
monkeypatch.setattr(FW, "fetch_fees",
lambda ins: dict(instrument=ins, taker_bps=5.0, maker_bps=0.0, liq_bps=75.0))
monkeypatch.setattr(FW, "load_state", lambda: {})
ins = FW.INSTRUMENTS[0]
monkeypatch.setattr(FW, "realized_fee_bps", lambda limit=20: {ins: 7.5})
r = FW.run()
assert r["realized"] == {ins: 7.5}
assert len(r["divergenze"]) == 1 and ins in r["divergenze"][0]
assert r["divergenza_gia_detta"] is False
def test_run_nessun_trade_e_None_non_zero(monkeypatch):
monkeypatch.setattr(FW, "fetch_fees",
lambda ins: dict(instrument=ins, taker_bps=5.0, maker_bps=0.0, liq_bps=75.0))
monkeypatch.setattr(FW, "load_state", lambda: {})
monkeypatch.setattr(FW, "realized_fee_bps", lambda limit=20: {})
r = FW.run()
assert r["realized"] is None
assert r["divergenze"] == []
def test_run_sotto_soglia_non_e_divergenza(monkeypatch):
monkeypatch.setattr(FW, "fetch_fees",
lambda ins: dict(instrument=ins, taker_bps=5.0, maker_bps=0.0, liq_bps=75.0))
monkeypatch.setattr(FW, "load_state", lambda: {})
ins = FW.INSTRUMENTS[0]
monkeypatch.setattr(FW, "realized_fee_bps", lambda limit=20: {ins: 5.3}) # +0.3 < 1.0
r = FW.run()
assert r["divergenze"] == []
_RIS_DIVERGE = dict(
current={"BTC_USDC-PERPETUAL": dict(taker_bps=5.0, maker_bps=0.0, liq_bps=75.0)},
changes=[], worst_taker_bps=5.0, level="OK", reason="ok", first_read=False,
realized={"BTC_USDC-PERPETUAL": 7.5},
divergenze=["BTC_USDC-PERPETUAL: realizzata 7.50 bps vs tier pubblico 5.00 (+2.50)"],
divergenza_gia_detta=False,
)
_RIS_DIVERGE_RIPETUTA = dict(_RIS_DIVERGE, divergenza_gia_detta=True)
_RIS_DIVERGE_RIENTRATA = dict(
current={"BTC_USDC-PERPETUAL": dict(taker_bps=5.0, maker_bps=0.0, liq_bps=75.0)},
changes=[], worst_taker_bps=5.0, level="OK", reason="ok", first_read=False,
realized={"BTC_USDC-PERPETUAL": 5.3}, divergenze=[], divergenza_gia_detta=True,
)
def _prepara_b9(monkeypatch, risultato, esito_invio):
"""Come `_prepara`, ma senza `changes`/livello AZIONE: isola il notify di B9 da quello di
B8 (qui non richiesto, dato che tutte le fixture hanno level='OK' e changes=[])."""
salvato, inviato = [], []
monkeypatch.setattr(FW, "run", lambda: risultato)
monkeypatch.setattr(FW, "save_state", lambda cur: salvato.append(cur))
monkeypatch.setattr(FW, "notify", lambda *a, **k: inviato.append((a, k)) or esito_invio)
monkeypatch.setattr(FW, "registra_giro", lambda *a, **k: None)
return salvato, inviato
def test_divergenza_prima_volta_notifica_e_marca(monkeypatch):
salvato, inviato = _prepara_b9(monkeypatch, _RIS_DIVERGE, esito_invio=True)
FW.main()
assert len(inviato) == 1
assert salvato[-1]["divergenza_detta"] is True
def test_divergenza_stesso_episodio_non_ripete(monkeypatch):
salvato, inviato = _prepara_b9(monkeypatch, _RIS_DIVERGE_RIPETUTA, esito_invio=True)
FW.main()
assert inviato == [], "gia' detta in questo episodio: nessun secondo invio"
assert salvato[-1]["divergenza_detta"] is True
def test_divergenza_notify_fallita_non_marca(monkeypatch):
salvato, inviato = _prepara_b9(monkeypatch, _RIS_DIVERGE, esito_invio=False)
FW.main()
assert len(inviato) == 1
assert salvato[-1]["divergenza_detta"] is False, \
"invio fallito -> marcatore non scritto, il giro dopo ritenta"
def test_divergenza_rientrata_azzera_il_marcatore(monkeypatch):
salvato, inviato = _prepara_b9(monkeypatch, _RIS_DIVERGE_RIENTRATA, esito_invio=False)
FW.main()
assert inviato == [], "sotto soglia: nessun invio da tentare"
assert salvato[-1]["divergenza_detta"] is False