cinque punti della revisione 09/09: usde_watch a 1000 trade + finestra 24h, cuscino_watch (equity USDC, riconverte da solo), PREVDAY-01 kill/veto cablati, SCALA-01 al 2027-02-28, versamento 04/09 dichiarato
Decisi dall'operatore il 2026-09-10, verificati da revisione fable (15 segnalazioni, 12 applicate). - usde_watch: TRADE_LIMIT 1000 (count max Deribit) e trade_copertura(): lista troncata o ultima lettura oltre la finestra di 24h del gateway => somma NON leggibile, reward non attribuito (P12). Riga del 07/09 corretta nel log con campo `correzione` (400 USDE erano acquisti, non reward). - cuscino_watch.py (cron :53, monitor_health): equity USDC contro cuscino derivato da usde.cuscino_richiesto_usd (formula spostata in src/live/usde.py, usde_convert la importa); OK/PREAVVISO/SCOPERTO/BLIND; sotto zero lancia usde_convert --quota quota_ripristino(0.20)=0.64 --esegui con guardie (execution_enabled, depeg_warn, 1 tentativo/6h). Primo giro: PREAVVISO, +$26. - usde_convert: il tetto del venue vale solo in ACQUISTO (bloccava la vendita). - paper_prevday: GATE PREVDAY-01 cablato (2027-06-21, kill Sharpe giornaliero < -0,50 su >=180 g attivi, veto >=80% barre ricostruibili + divergenze non crescenti con soglia materiale). Oggi: +0,95 su 81 g, 1942/1943 ricostruibili, kill NON MATURO. - CLAUDE.md: arming 20/06 (TP01) / 23/06 (BOOK); piano EUR 5.000 chiuso col versamento 04/09 ($2.414,68 dal balance, dichiarato); SCALA-01 non prima del 2027-02-28 (A2 dal 01/09); PREVDAY-01 con data, kill, veto; §5.17 riparato con i limiti dichiarati (ratchet, slack zero a 0,70). - test: 1062 (+31): test_cuscino_watch (16), test_paper_prevday_gate (8), test_usde_watch (+5). Fixes #2 Fixes #3 Fixes #4 Fixes #5 Fixes #6 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016kqvff47UBGeYfj1QeN4zE
This commit is contained in:
@@ -205,3 +205,64 @@ def test_la_quota_si_decide_da_lunedi_e_solo_se_IDONEO():
|
||||
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
|
||||
|
||||
|
||||
# ------------------------------ lettura dei trade: i due limiti del canale (issue #2) ------------------------------
|
||||
# Il 07/09 il lettore chiedeva limit=50, la sonda del 06/09 aveva fatto 54 ordini: 400 USDE di
|
||||
# acquisti sono finiti nel «reward». Il lettore ora chiede il massimo del venue (1000) e, se la
|
||||
# lista puo' essere incompleta — troncata al limite, o ultima lettura oltre la finestra di 24h
|
||||
# che il gateway espone — dichiara «non leggibile» invece di sommare (P12).
|
||||
|
||||
class _ClientFinto:
|
||||
def __init__(self, rows):
|
||||
self.rows, self.limit_chiesto = rows, None
|
||||
|
||||
def trade_history(self, instrument, limit=20):
|
||||
self.limit_chiesto = limit
|
||||
return self.rows[:limit]
|
||||
|
||||
|
||||
def _ordini(n, t0_ms, amt=100.0, passo_ms=15_000):
|
||||
return [{"timestamp": t0_ms + i * passo_ms, "direction": "buy", "amount": amt} for i in range(n)]
|
||||
|
||||
|
||||
def test_controllo_positivo_54_ordini_si_sommano_tutti():
|
||||
"""Il caso del 06-07/09: 54 ordini in 24h. Con il vecchio limit=50 ne mancavano 4."""
|
||||
prev, now = 1_788_698_101_000, 1_788_784_501_000 # 06/09 12:35Z -> 07/09 12:35Z
|
||||
c = _ClientFinto(_ordini(54, prev + 30_000_000))
|
||||
tot, n, motivo = W._trades_spot_da(c, prev, now)
|
||||
assert motivo is None and n == 54 and abs(tot - 5400.0) < 1e-9
|
||||
assert c.limit_chiesto == W.TRADE_LIMIT >= 54
|
||||
|
||||
|
||||
def test_lista_al_limite_del_venue_non_e_leggibile():
|
||||
prev, now = 1_788_698_101_000, 1_788_784_501_000
|
||||
c = _ClientFinto(_ordini(W.TRADE_LIMIT + 5, prev + 1000))
|
||||
tot, n, motivo = W._trades_spot_da(c, prev, now)
|
||||
assert tot is None and n is None and "troncata" in motivo
|
||||
# e il reward NON si attribuisce (P12)
|
||||
an = W.analizza({"eq_usde": 1000.0}, 1400.0, tot)
|
||||
assert an["reward_stimato"] is None and not an["reward_rilevato"]
|
||||
|
||||
|
||||
def test_lettura_oltre_la_finestra_del_gateway_non_e_leggibile():
|
||||
"""Giro saltato: 48h dall'ultima lettura. I trade fra 48h e 24h fa sono invisibili."""
|
||||
prev = 1_788_698_101_000
|
||||
now = prev + 48 * 3_600_000
|
||||
c = _ClientFinto(_ordini(3, now - 3_600_000))
|
||||
tot, n, motivo = W._trades_spot_da(c, prev, now)
|
||||
assert tot is None and "finestra" in motivo
|
||||
|
||||
|
||||
def test_la_cadenza_del_cron_sta_dentro_la_tolleranza():
|
||||
"""24h + qualche secondo (il cron delle 12:35 di due giorni consecutivi) e' coperta."""
|
||||
prev = 1_788_698_101_000
|
||||
assert W.trade_copertura(10, prev, prev + 24 * 3_600_000 + 2_000) is None
|
||||
assert W.trade_copertura(10, prev, prev + 24 * 3_600_000 + W.TOLL_FINESTRA_MS + 1) is not None
|
||||
|
||||
|
||||
def test_i_trade_prima_della_lettura_precedente_non_contano():
|
||||
prev, now = 1_788_698_101_000, 1_788_784_501_000
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user