a45794d2cba181f3fcd0efc6880d535a9615ef94
9 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
a45794d2cb |
usde: il venue mette un TETTO al 31,21% — e l'USDC paga gia' 3,40%
Richiesta dell'operatore: "porta in usde tutto il capitale che non viene usato". Il margine consuma $11 su $2.063 e l'USDE e' cross-collateral: preso alla lettera vale una quota ~99%, cioe' il 100% che il gate esclude. Portata all'operatore con le cifre, ha scelto 70%. Il 70% non e' un argmax (M8): e' il massimo compatibile col CUSCINO DI REGOLAMENTO, il vincolo che r0830_usde_quota non aveva guardato. P&L e funding dei perp USDC-lineari si regolano in USDC, non nel collaterale, quindi la quota non la limita l'haircut ma il saldo USDC che deve reggere il disaster-SL sulla massima esposizione: 2 x 0,5 x 0,30 = 30% dell'equity, che lascia il 70%. ESEGUITO +144 USDE (500,1757 -> 644,175691), quota 24,24% -> 31,21%, fee 0. Poi il muro. (a) TETTO DEL VENUE, misurato e non documentato da nessuna parte. Provato a saldo neutro: BUY 20 rifiutato, SELL 20 OK, BUY 20 OK, BUY 5 rifiutato, con $1.408 disponibili. E' un tetto sul LIVELLO. Il messaggio del venue (not_enough_funds_in_currency) e' fuorviante e ha fatto inseguire tre ipotesi sbagliate: taglia (falso, ma min_trade_amount=1 e' vero), rate-limit (falso), prezzo (vero in parte: il book REST pubblico e' in ritardo sul matching engine e prezzavo l'ordine sull'INDICE invece che sul BOOK — l'indice marca il collaterale, il book prezza lo scambio). La cronaca resta nel diario: chi rilegge non deve rifare il giro. (b) L'USDC PAGA 3,40%. public/get_currencies: USDE 4,1071%, USDC 3,4000%, e i nostri reward USDE misurati (~4,5%/anno) confermano che quelle APR sono reali. Il guadagno non e' il tasso, e' lo SPREAD: 0,71 punti, ~$4,6/anno sui $644 che teniamo, non i $21 che il gate implicava. Il gate ha misurato il reward dell'USDE e non ha mai chiesto cosa facesse l'USDC fermo: manca il controfattuale, M1 in un'altra veste. NON dimostrato che sia accreditato sul nostro conto — da verificare su un giorno senza trade. Nuovo attrezzo scripts/live/usde_convert.py: dry-run di default, banda prezzo, tetto hard di quota, cuscino di regolamento derivato da config. NON passa da execution.ALLOWED, che resta ai soli due perp. config: quota_target 0.70 registrato; quota_max_frac alzato a 0.85 e RIMESSO a 0.50 nella stessa sessione — la soglia larga presupponeva un 70% che non esiste, e lasciarla avrebbe disarmato la guardia per uno scenario che non si e' verificato. Suite: 795 passati, 0 falliti. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
e5052a690f |
usde: da patch d'emergenza a struttura — config, modulo unico, sorveglianza
- config/live.json sezione `usde` (unica autorita', P1): indice, haircut 10%, tetto allerta quota 50%, soglie depeg 0.99/0.95 coi criteri dichiarati (P6) - src/live/usde.py: config + catena di prezzo (indice pubblico -> ticker -> 1.0 dichiarato) + valutazione PURA; shadow._collaterale_usde ora deriva da qui - scripts/live/usde_watch.py + cron_usde.sh (12:35 UTC, dopo la finestra reward): reward per delta netto trade (P12: senza inventare attribuzioni), depeg (crit ripetuto, resto a transizione, P9), quota anche per deriva passiva (N4); applica il verdetto di eligibilita' pre-registrato (>=1 reward entro 29/08) - serie data/live/usde_watch.jsonl sotto monitor_health (max 30h, P5: un watch fermo non deve leggersi come "va tutto bene"); baseline 14:17Z registrata - GATE USDE-01 in CLAUDE.md §4; test 775 (+17 in tests/test_usde_watch.py) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01B9UyJLHzR7EJzxR3iQ3RN1 |
||
|
|
b023cc2bdf |
fix(live): cap di fallback legato all'ultima equity osservata + cap config 300 -> 3000
L'operatore ha autorizzato "si alza il cap a 3000". Verificato PRIMA di eseguire: il
deposito non era ancora arrivato (equity reale $596.92), e alzare il cap in quel momento
sarebbe stato pericoloso NEL VERSO OPPOSTO.
IL PROBLEMA. Quando l'equity reale non e' leggibile, shadow_report ripiega su paper_cap =
$2.000 NOMINALI, che non e' il conto vero: il sizing diventa 0.5 x 2000 x (...) = fino a
$1.000/asset, e il cap fisso e' l'unica cosa che impedisce a quel nominale di diventare
leva reale.
cap $300 -> fallback $600 lordi su $597 = 1.00x OK
cap $3000 -> fallback $2.000 lordi su $597 = 3.35x NO
Cioe' il cap sarebbe stato troppo alto proprio nel momento in cui non si sa quanto c'e'
sul conto, e con disaster_sl_pct -30% quella e' la configurazione peggiore possibile.
LA CORREZIONE. Invece di alzare un numero da ricordare, il cap di fallback e' legato al
conto: cap_fallback = min(cap_fisso_di_config, ultima_equity_reale_osservata * frac), con
watermark in data/live/equity_seen.json scritto da book_report ogni volta che l'equity
reale e' leggibile. Il cap di config torna a essere un TETTO DICHIARATO.
Senza watermark (primo avvio, file cancellato) -> CAP_UNKNOWN_USD = $300: non si sa niente
del conto, si usa la taglia storicamente sicura.
VERIFICATO SUL CONTO VERO, nei due regimi:
oggi, watermark $596.92 -> $298.46/asset = leva 1.00x
dopo il versamento, $6.047 -> $3,000.00/asset = leva 0.99x
Sicuro in entrambi gli ordini di eventi, senza dipendere da un'azione manuale al deposito.
Questo CHIUDE l'azione pre-registrata il 2026-07-02 ("al deposito alzare il cap a
equity/2"), rimasta ineseguita per 24 giorni — non eseguendola, ma rendendola non
necessaria.
REGOLA: un parametro di sicurezza che va aggiornato a mano a ogni cambio di scala e' un
difetto, non una configurazione. Lo stesso numero era sbagliato in un verso prima del
deposito e nell'altro dopo: la soluzione non era scegliere il valore giusto, era legarlo
alla grandezza che lo determina.
Guardie: tests/test_cap_watermark.py (11), A DUE LATI — il cap non puo' ne' superare il
conto reale (leva nascosta) ne' restare sotto dopo un deposito (strozzatura).
Dry-run sul conto reale: cap/asset $298, book flat, nessun ordine. 391 test verdi (+11).
Strategia, pesi, cron INVARIATI. Cambia solo config/live.json e il calcolo del cap di
fallback.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
||
|
|
031b71bf54 |
ops(live): sorveglianza freschezza feed SKH + correzione dei docstring sulla latenza d'uscita
T1 (TP di SKH01 come limit resting on-book) NON e' stato implementato, per misura.
Leggendo il codice di produzione: TP01 e SKH01 tradano lo stesso strumento con una
sola posizione netta Deribit, quindi un ordine on-book al livello di SKH chiuderebbe
anche quota TP01. Misurati i due ostacoli: (A) segno compatibile nel 97% dei trade
che escono in TP = risolvibile; (B) divergenza modello/live apparentemente bloccante.
Ma (B) non esiste: resample_5m NON scarta il bin 230m in corso (21 barre 5m su 46
nell'ultimo bin) e _skyhook_positions ci itera dentro -> il live rileva gia' SL/TP
intra-barra, entro ~1h dal tocco. I docstring che dicevano "usa solo barre chiuse" e
"latenza fino alla chiusura della barra 230m" erano FALSI e hanno guidato tre analisi
(02/07, 24/07, T1). Corretti sul posto.
Conseguenza: la lente `hourly` sottostima il path live di +0.081 Sharpe FULL di book
(23/23 offset, banda appaiata); il live vero sta sopra il canonical sul FULL, e il fix
richiesto sarebbe un declassamento (+0.054 vs +0.081) in cambio di ordini parziali sul
netto in un percorso con soldi veri.
Cablato invece il problema vero trovato per strada: fresh_5m fallisce in SILENZIO
(fallback al certificato, rigenerato 1x/giorno) -> la latenza d'uscita di SKH01 passa
da ~1h a ~1 giorno senza segnalazione, e nessun controllo esistente scatta (il gate di
staleness guarda il feed di TP01). Stesso schema del feed-freeze del 14/07.
* livefeed.feed_age_minutes: pura, eta' dalla CHIUSURA della barra, None = non
misurata, clamp sugli skew d'orologio
* book_report espone skh_feed_age_min (max fra gli asset)
* book_execute stampa lo stato e allerta su Telegram sopra skh_feed_max_age_min (30m)
Scelta dichiarata: ALLERTA, NON blocca. Bloccare fermerebbe anche TP01 (nettato sullo
stesso strumento) per un guasto di rete; forzare SKH flat chiuderebbe posizioni buone
su un glitch.
Follow-up dichiarato: la stessa barra parziale tocca gli INGRESSI (ent[n-1] da breakout
non confermato). Disaccordo in 1 bin su 112, ma con 3 entry nel campione la taglia non
e' stimabile. E' un cambio di strategia, non di strumentazione -> misura dedicata prima.
Strategia, pesi e cadenza del cron INVARIATI. Nessun ordine inviato. Suite 266 verdi.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
||
|
|
71b39c2c86 |
ops(live): staleness-gate bloccante + report Telegram giornaliero
Presa in carico operativa del conto Deribit (delega dell'utente). Nessun cambio a
strategie, pesi o sizing: il libro resta TP01 0.75 + SKH01 0.25.
1) STALENESS-GATE (protezione di capitale, era un follow-up mai cablato)
Il 2026-07-14 alle 14:00 UTC il book ha COMPRATO ETH $75 con l'ultima barra del
feed certificato ferma al 2026-07-08: feed congelato da 6 giorni (diario
2026-07-15-feed-freeze). I due gate esistenti non potevano vederlo — il conto ERA
online e la posizione ERA leggibile: proteggono dai problemi di CONTO, non da un
feed morto. Il diario raccomandava un alert; qui il gate e' BLOCCANTE, coerente
con gli altri due ("non opero a cieco"), col disaster-SL on-book come rete su
eventuali posizioni gia' aperte.
- config/live.json: max_data_age_days = 2;
- book_execute: _data_age_days() + blocco PRIMA di costruire DeribitTrader
(nessuna sessione autenticata aperta su dati morti) + alert Telegram con il
comando di sblocco; data illeggibile => trattata come stantia;
- letto con cfg.get(default): una config priva della chiave ricade sulla soglia
sicura invece di sollevare KeyError dentro il percorso con soldi veri;
- tests/test_book_staleness_gate.py: 8 casi, incluso il funzionale che riproduce
la situazione del 14/07 (online + posizione leggibile + ordine pronto) e
verifica che DeribitTrader NON venga costruito.
- tests/test_book_live.py: i 3 report finti avevano last_data="2026-07-01"
hardcoded -> ora data fresca calcolata. Quei test riguardano skh_error /
pos_error / eq_fallback, non la staleness: con la data fissa sarebbero marciti
al superamento della soglia.
2) REPORT TELEGRAM GIORNALIERO (scripts/live/telegram_daily.py, in cron_daily.sh)
Gli alert esistenti scattano solo su ordine o errore: con il libro flat — stato
normale e corretto col trend giu' — significava silenzio per settimane,
indistinguibile da un sistema morto. Il report dice ogni giorno dove sta il conto,
perche' non opera e quanto manca perche' operi (con la convenzione TP01 corretta:
media dei SEGNI, quindi servono 2 orizzonti su 3, non basta il piu' breve).
Sola lettura: un test verifica che il modulo non possa inviare ordini.
Stato al commit: equity $596.92, flat e a target, disaster-SL -30% verificato
(placed @ $1,308.7 sull'ultima posizione). TP01 0.00 su entrambi: accensione a
BTC $78.680 (+22,7%) / ETH $2.370 (+27,2%).
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
||
|
|
cf7de40dc0 |
feat(live): cap/asset dinamico = equity/2 — operazionalizza la decisione frontier (inerte a $600)
Il cap notional per-asset non e' piu' fisso a $300: con max_notional_per_asset_frac in config diventa equity/2, cosi' cresce col capitale e un deposito futuro non resta strozzato (frontiera 2026-07-03). Guardrail: dinamico SOLO con equity reale fidata; su fallback/offline si torna al cap fisso (protezione downside quando E e' ignota). Live dry-run: cap $299 a equity $598 -> inerte oggi. Suite 172 passed (+4 test). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
db738bce3b |
feat(live): arma il BOOK DERIBIT (TP01+SKH01 nettati in software)
Estende l'esecuzione live da TP01-only al book Deribit-only completo. TP01 e SKH01 tradano lo STESSO strumento (una sola posizione netta per conto su Deribit) -> netting in software: un solo ordine/asset verso il target netto. - src/live/book.py: target NETTO per asset = clamp(0.5*E*(0.75*tp_frac + 0.25*skh_sign), ±cap). Riusa current_target (TP01, causale) + _skyhook_positions (segno L/S, book 230m) + conto reale. - src/live/execution.py: rebalance_signed() — reconcile CON SEGNO (long/short, flip via close+open, reduce reduce_only). La close resta sempre permessa (si esce da qualunque posizione). - src/live/livefeed.py: fresh_5m() — feed 5m certificato + coda recente EFFIMERA da Deribit pubblico (stesso simbolo inverse, in-memory, NON scrive su disco -> dati certificati intatti; fallback al certificato su errore). Solo SKH01 ne ha bisogno (e' a 230m); TP01 e' giornaliero. - scripts/live/book_execute.py: executor doppio-gate (config + --execute), disaster-SL on-book sulla posizione netta, log in data/live/book_executions.jsonl. Feed SKH fresco (live_feed=True). - scripts/cron_book.sh + crontab ORARIO: book idempotente ogni ora (riconcilia al netto corrente); rimossa la riga live_execute.py (TP01-only) dal cron daily per non far collidere i due. - config/live.json: ARMATO (execution_enabled=true). cap/asset $300 split 75/25, disaster-SL -30%. Tutto flat all'arming -> nessun ordine finche' un segnale non arma. - tests/test_book_live.py: 20 test (sizing 75/25, cap, flip/close/reduce, parita' pesi backtest, gate-safety, reconcile con trader fittizio, merge/dedup feed + fallback, loader onorato). 76/76 pass. CAVEAT: exit SKH SOFTWARE (latenza fino a fine barra 230m; solo disaster-SL on-book); TP01 scende a peso 0.75 (max $225/asset); SKH01 resta research-grade (equity daily-step, margine DD ETH sottile). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
4650aa71a2 |
feat(live): ARMA l'esecuzione di TP01 (execution_enabled=true) + cabla al cron giornaliero
execution_enabled=true: con --execute il loop invia ordini REALI. Aggiunto al cron_daily.sh (00:30 UTC, dopo il refresh dati) lo step live_execute.py --execute. Validato armato: TP01 flat -> HOLD, zero ordini. Da qui TP01 opera da solo sul conto reale al prossimo ENTRY del segnale. NB: il loop NON piazza ancora il disaster-SL on-book (metodo presente, lifecycle bracket da cablare prima del primo ENTRY). Rischio posizione comunque limitato dal cap $300/asset (~1x, no leva). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
bc9e322d0d |
feat(live): loop di esecuzione GATED di TP01 (execution_enabled + --execute, default OFF)
scripts/live/live_execute.py porta il conto reale al target di TP01 (min(0.5*frazione*equity, cap/asset)): apre/riduce/chiude via DeribitTrader.rebalance_to(). DOPPIO GATE: config/live.json execution_enabled=true (master, default false) E flag --execute; senza entrambi e' dry-run. Reconciliation post-ordine + log in data/live/executions.jsonl. TP01 flat -> 0 azioni. - execution.py: rebalance_to() (open/reduce/close al target); MAX_AMOUNT alzato a tetto hard anti-fat-finger (~$630/$430 su conto ~$600), il sizing operativo lo decide config max_notional. - config/live.json: master switch + cap/asset $300 + min ordine $5 + disaster_sl_pct. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |