#29 B2: lo stato si salvava PRIMA dell'invio e il ritorno di notify() non si leggeva — un invio fallito restava "gia' detto" per l'episodio intero. Schema di cuscino_watch.py: nuove_condizioni()/rec["allertati"] contano una condizione come "gia' detta" solo se l'invio precedente e' RIUSCITO; un record vecchio senza `allertati` vale come "tutto allertato" (nessun rispam retroattivo). Lo stato si scrive una volta sola, a fine giro. #35 B3/B4: la quota non e' piu' una decisione dell'operatore rinviata a lunedi' — dal 10/09 (issue #7) e' DERIVATA dal cuscino USDC (usde._nota_cuscino) — quindi tolti DECISIONE_QUOTA_DAL, quota_da_decidere() e la notify "la decisione di QUOTA e' dovuta". Il tetto di allerta IDONEO legge c["quota_max_frac"] invece del 50% cablato. La riga "margine" non dice piu' "conto SEGREGATO" (il modello e' Cross X:SM dal 31/08): stampa il totale USDC + USDE scontato del cross, coi numeri che la funzione ha gia'. Le due modifiche toccano lo stesso blocco (allarmi + STATE write + stampa) e non si possono separare per hunk senza rischio: un solo commit per il file. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
+44
-12
@@ -193,18 +193,12 @@ def test_nessuna_finestra_misurabile_non_e_zero():
|
||||
assert r["apr"] is None and r["finestre"] == 0
|
||||
|
||||
|
||||
def test_la_quota_si_decide_da_lunedi_e_solo_se_IDONEO():
|
||||
from datetime import datetime, timezone
|
||||
|
||||
def q(giorno, v):
|
||||
return W.quota_da_decidere(datetime.fromisoformat(giorno + "T12:35:00+00:00"), v)
|
||||
|
||||
assert W.DECISIONE_QUOTA_DAL == "2026-08-31"
|
||||
assert q("2026-08-30", "IDONEO") is False, "il rinvio dell'operatore non e' rispettato"
|
||||
assert q("2026-08-31", "IDONEO") is True, "lunedi' la domanda non viene posta"
|
||||
assert q("2026-09-30", "IDONEO") is True, "smette di chiedere: la decisione si dimentica"
|
||||
assert q("2026-08-31", "IN_ATTESA") is False, "chiede la quota su un conto non idoneo"
|
||||
assert q("2026-08-31", "NON_IDONEO") is False
|
||||
def test_quota_da_decidere_e_stata_rimossa():
|
||||
"""#35 (B3/B4): dal 10/09 (issue #7) la quota e' DERIVATA dal cuscino USDC
|
||||
(usde._nota_cuscino), non e' piu' una decisione dell'operatore rinviata da ricordare ogni
|
||||
giorno finche' non la si toglie a mano."""
|
||||
assert not hasattr(W, "quota_da_decidere")
|
||||
assert not hasattr(W, "DECISIONE_QUOTA_DAL")
|
||||
|
||||
|
||||
# ------------------------------ lettura dei trade: i due limiti del canale (issue #2) ------------------------------
|
||||
@@ -266,3 +260,41 @@ def test_i_trade_prima_della_lettura_precedente_non_contano():
|
||||
rows = _ordini(2, prev - 60_000) + [{"timestamp": prev + 1, "direction": "sell", "amount": 40.0}]
|
||||
tot, n, motivo = W._trades_spot_da(_ClientFinto(rows), prev, now)
|
||||
assert motivo is None and n == 1 and abs(tot + 40.0) < 1e-9
|
||||
|
||||
|
||||
# =============================================================================================
|
||||
# issue #29 (B2) — un invio fallito non deve consumare la transizione (schema di cuscino_watch)
|
||||
# =============================================================================================
|
||||
|
||||
def test_notify_fallito_la_condizione_si_ripresenta_come_nuova():
|
||||
"""Il difetto: lo stato si salvava PRIMA dell'invio e il False di notify() non si leggeva ->
|
||||
un invio fallito restava 'gia' detto' per l'episodio intero. Qui: la condizione era attiva
|
||||
l'ultima volta ma NON e' fra le confermate (`allertati`) -> deve tornare 'nuova'."""
|
||||
att = {"QUOTA_OVER"}
|
||||
prev = dict(allertati=[]) # QUOTA_OVER era attivo, l'invio era FALLITO
|
||||
assert W.nuove_condizioni(att, att, prev) == {"QUOTA_OVER"}
|
||||
|
||||
|
||||
def test_notify_riuscito_non_si_ripete():
|
||||
att = {"QUOTA_OVER"}
|
||||
prev = dict(allertati=["QUOTA_OVER"]) # invio RIUSCITO l'ultima volta
|
||||
assert W.nuove_condizioni(att, att, prev) == set()
|
||||
|
||||
|
||||
def test_record_vecchio_senza_allertati_vale_come_tutto_allertato():
|
||||
"""Compatibilita': un record scritto prima di questo fix non ha il campo `allertati`. Non
|
||||
deve produrre un rispam retroattivo delle condizioni gia' viste."""
|
||||
att = {"QUOTA_OVER", "BLIND"}
|
||||
prev = dict(stato="OK") # nessun campo `allertati`
|
||||
assert W.nuove_condizioni(att, att, prev) == set()
|
||||
|
||||
|
||||
def test_senza_record_precedente_tutto_e_nuovo():
|
||||
att = {"QUOTA_OVER", "DEPEG_WARN"}
|
||||
assert W.nuove_condizioni(att, set(), None) == att
|
||||
|
||||
|
||||
def test_una_condizione_appena_comparsa_e_sempre_nuova():
|
||||
"""Anche con `allertati` presente, una condizione che non era in att_prev e' nuova per
|
||||
definizione — l'insieme confermato non la riguarda."""
|
||||
assert W.nuove_condizioni({"BLIND"}, set(), dict(allertati=["QUOTA_OVER"])) == {"BLIND"}
|
||||
|
||||
Reference in New Issue
Block a user