ee5c6ed53945b5ce4fa1d0f96c65c956ec3ddd17
7 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
2751a7efd0 |
journal: la voce del giorno IN CORSO non si presenta piu' come una giornata
cron_daily (00:30 UTC) faceva DUE chiamate al giornale: chiudeva IERI (giusto)
e apriva OGGI. La pagina di oggi nasceva con ~30 minuti dentro e nessuno la
aggiornava fino alla notte dopo.
Il difetto non era il dato mancante: era che la pagina non lo diceva dove si
legge. Aveva TUTTE le sezioni di una chiusa -> passava ogni controllo di
completezza e freschezza, e la parzialita' stava solo in §Salute, quinta
sezione su otto. Stessa famiglia di "una barra presente non e' una giornata
presente", in veste nuova: la pagina e' presente, il giorno no.
Taglia misurata sul caso reale di oggi: la pagina congelata alle 00:37 diceva
"giorno: $+0.54 (1 letture)" e la regola [pnl] chiosava "senza operare". Alle
08:54 il libro aveva fatto 3 fill, 2 round-trip e +$25.86 ($642.56 -> $667.88).
Avrebbe raccontato una giornata ferma per tutta una giornata operativa.
Riparato in due pezzi indipendenti:
1. la pagina dichiara la parzialita' nel TITOLO e nella prima riga —
"PARZIALE (giorno in corso)", copertura esplicita (N giri su 24), il fatto
che non si aggiorna da sola, e quali numeri sono di quella frazione;
2. tolta la seconda chiamata dal cron. In docs/journal/ restano solo giorni
chiusi; lo stato corrente si prende da journal.py a mano (pagina marcata)
o da trades.db, che cron_book sincronizza ogni ora.
Scelta dichiarata: NON si rigenera ogni ora. Costerebbe una riga in cron_book
ma riscriverebbe un file tracciato da git 24 volte al giorno per un consumatore
che non esiste (l'analista legge il giorno chiuso). Se un domani servisse, la
strada e' RIGENERARLA, non congelarla: e' scritto nel commento del cron.
Prove (test_journal 28 -> 31): una accende la marcatura, una la tiene spenta su
un giorno chiuso (una marcatura sempre accesa non si legge), una e' guardia sul
SORGENTE di cron_daily.sh — ogni chiamata a journal.py deve avere --giorno
esplicito, perche' senza argomenti scrive OGGI.
Regolare docs/journal/2026-08-25.md rigenerato: ora si dichiara PARZIALE (9/24).
NON riparato, e registrato come debito aperto in CLAUDE.md §5:
test_wave_0726::test_t1_canonical_riproduce_il_backtest_ufficiale fallisce, e
falliva gia' prima di questa modifica (verificato con git stash sull'albero
pulito). Sharpe hold-out SKH01 canonical 1,9223 contro la banda cablata
1.3 < h < 1.9: il codice non e' cambiato, sono cambiati i dati (data/raw e'
gitignored, il cron lo ricostruisce ogni notte). La banda NON e' stata
allargata — lezione 07/08. Suite: 710 passati, 1 fallito.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
||
|
|
11a2370027 |
journal: voci automatiche del 23-25/08
Giri notturni del cron. Il 23/08 e' stato rigenerato alle 00:36 del 24 col giorno COMPLETO (24 giri invece di 20, equity $637.58, cumulato $+39.52): la voce precedente era stata scritta alle 19:44 a giornata in corso. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
12dc04c969 |
analista: modello di default a opus-5
Sonnet-5 ha prodotto due errori di ragionamento in due giri: una frase su un merge di cui nessuno gli aveva parlato, e un round-trip corretto sulla pagina dichiarato inesistente, con una spiegazione inventata per il proprio dubbio. Nessuno dei due contiene una cifra nuova, quindi numeri_non_supportati() non li vede: e' il buco dichiarato quando la guardia e' stata scritta. Primo giro con opus-5 sulla stessa giornata: nessuna affermazione inventata, e le affermazioni numeriche verificate a mano contro il DB tornano tutte (fill 1 contro 2/5/4/3 dei giorni precedenti, equity ferma a $597.12 dal 13 al 18/08, target BTC 189 -> 115). Resta un'imprecisione di nome: chiama "target" un valore che nella fonte era la POSIZIONE. Il numero e' della fonte, la classe di errore e' cambiata. E ha prodotto una riformulazione che le regole non possono dare: la concentrazione del P&L in 7 giorni ha una lettura alternativa altrettanto compatibile — quei sette giorni sono anche gli UNICI in cui il libro e' stato a mercato, quindi la finestra non separa l'edge dal beta a un rialzo del 22-29%. ⚠️ Il campione e' di due osservazioni contro una: e' un tentativo di abbassare un tasso, non una garanzia, ed e' scritto cosi' nel sorgente. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
782c0ce4bc |
analista: manda l'analisi giornaliera su Telegram, con l'esito registrato
La notifica porta una testata coi numeri che si leggono senza aprire nulla
(equity, delta del giorno, cumulato, posizioni, leva, fill e round-trip) e
sotto l'analisi del modello.
Il trasporto Telegram e' pero' il punto singolo di guasto gia' misurato in
questo progetto: un tentativo, nessun retry, esito mai registrato, 6,9% di
invii persi (2/29). Su un messaggio al giorno sono ~25 messaggi persi
all'anno, quindi qui sono state fatte due delle tre riparazioni dichiarate
il 2026-08-23 e mai eseguite:
(a) `send(text, tentativi=1)` — retry OPZIONALE con backoff. Il default resta
1, cosi' il comportamento e' invariato per tutti i chiamanti esistenti:
alzarlo per tutti cambierebbe la latenza degli allarmi di venue_watch e
book_execute su un percorso con soldi veri, e non e' una modifica da fare
di straforo dentro un'altra funzionalita'. L'analista chiede 3.
(b) `ultimo_errore()` — il motivo si registra nel punto in cui l'eccezione
veniva ingoiata, e NON sopravvive a un invio riuscito. Regola gia'
codificata il 29/07 su un altro percorso e mai applicata al notifier.
La terza (marcare `alerted=True` solo a invio riuscito in venue_watch) cambia
il comportamento degli allarmi e resta una decisione dell'operatore.
L'esito finisce nel DB in tre stati: inviata / non configurato / FALLITA col
motivo. Un invio perso che non lascia traccia, il giorno dopo, non si
distingue da "non e' successo niente".
E se l'analisi manca, il messaggio parte lo stesso dicendo PERCHE': senza
quel ramo un guasto del modello si leggerebbe come una giornata senza nulla
da dire. Taglio a 4096 caratteri dichiarato, mai silenzioso; HTML del modello
neutralizzato.
708 test passano. Strategia, pesi, config INVARIATI.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
||
|
|
f5d9409213 |
analista di bordo: un modello scrive la prosa del giorno, in un campo suo
Aggiunto il quarto livello della pagina, tenuto separato dagli altri tre: numeri -> misurati dal feed e dal DB Lettura -> regole deterministiche, ognuna col suo id Analisi -> questo: prosa di un modello, che puo' sbagliare Nota -> l'operatore NON scrive dentro `nota`, che era la richiesta letterale: quel campo e' dell'operatore, ed e' cio' che a rileggere il giornale fra sei mesi permette di sapere chi ha scritto cosa. L'agente ha `analisi`, marcato col modello, con l'ora e con l'esito del controllo sui numeri. Gira via `claude -p` (verificato con env -i che risponda nell'ambiente nudo di cron), una chiamata al giorno sul giorno CHIUSO, tolte le tool. Tre guardie, una per ogni modo in cui una prosa generata rovina un registro: - NUMERO INVENTATO: numeri_non_supportati() estrae ogni cifra dall'analisi e verifica che compaia in cio' che il modello ha ricevuto. Oltre tre numeri liberi l'analisi e' RIFIUTATA e la pagina resta senza. E' un controllo debole per costruzione, e lo dichiara: prende l'invenzione, non il ragionamento sbagliato. - COMMENTO DI SE': senza_analisi() toglie dalla pagina la sezione dell'agente prima di dargliela. Al primo giro reale il modello aveva letto la propria uscita precedente e prodotto un paragrafo sull'avviso che si era preso il giorno prima — un ciclo di retroazione che in poche settimane avrebbe riempito il giornale di meta-commento, e che nessun controllo automatico puo' distinguere da prosa valida. - ANALISI DI IERI SPACCIATA PER OGGI: se il modello non risponde, la pagina resta VUOTA e il perche' viene registrato (stato + motivo). Il silenzio non diventa continuita'. Corretto anche un falso positivo mio: il tripwire validava sulla sola pagina mentre il prompt include anche il blocco storico, quindi bocciava un'equity vera. Una guardia piu' stretta del contratto produce allarmi che si impara a ignorare. Ogni guardia ha un test in entrambe le direzioni. 695 test passano. Strategia, pesi, config INVARIATI. Nessun ordine. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
1803e0ac9f |
giornale: lettura ragionata a regole dichiarate e tracciabili
Non prosa libera: dodici regole, ognuna con un id stampato accanto alla riga che ha prodotto. Combinano solo numeri gia' presenti nella pagina, tacciono sul non misurato e non prevedono niente. Il campo `nota` resta l'unico posto dove puo' finire un giudizio umano. Le regole: stato del libro e PERCHE' e' flat (componente per componente), disaccordo fra orizzonti del trend contro esposizione TP01, incoerenza (trend su ma libro fuori), leva contro il tetto, P&L del giorno, costo che supera il movimento, concentrazione del cumulato, drawdown dal picco, implicita contro realizzata col gate IV-rank di VRP01, giornata oltre 2 deviazioni, giri mancanti e feed vecchio, e la taglia del campione. Ogni regola ha DUE test: uno che la accende e uno che la tiene spenta. Una regola che si accende sempre non sta leggendo niente, una che non si accende mai e' indistinguibile da una rotta. Tre difetti corretti prima di pubblicare, tutti trovati scrivendo i test: - il tetto di leva era RIDICHIARATO (0.5 cablato) invece che letto da config/live.json — quinta occorrenza dello schema che il progetto paga da luglio: un sorvegliante che ridichiara il proprio bersaglio continua a passare il giorno che il bersaglio cambia. Ora deriva, e se il config non si legge lo dice invece di inventare un tetto. - l'IV-rank era il percentile a UN ANNO etichettato col nome del gate di VRP01, che usa un percentile ESPANDENTE. Due statistiche diverse, e oggi danno il verdetto OPPOSTO: 0.52 (sopra la soglia, "il sleeve venderebbe") contro 0.18 (sotto, sleeve fermo). Il valore giusto combacia con quanto gia' misurato il 30/07: 0/8 settimane passano il gate. - la concentrazione si accendeva su $2,08 di cumulato: vera e inutile. Ora ha una soglia di rilevanza, o e' una riga che insegna a saltare la sezione. 62 voci rigenerate. Strategia, pesi, config INVARIATI. 675 test passano. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
10c373075c |
libro di bordo: DB dei trade allineato col tempo + giornale giornaliero
I trade erano salvati, ma non allineati col tempo: book_execute.py scriveva ts_utc = pd.Timestamp(r['last_data']), cioe' la data della BARRA DI SEGNALE. 19 righe su 19 a 00:00:00, e un trade (ETH 0.04 @ 1869.74) registrato SEI GIORNI prima di essere eseguito — fill vero 2026-07-14T14:00, scritto 08/07. L'ora vera esisteva solo in logs/cron_book.log, che e' gitignored, fuori dal backup e ruotabile: la cronologia reale del libro live viveva in un file che una rotazione avrebbe cancellato senza che nessuno se ne accorgesse. - src/live/tradesdb.py: parser del cron log (ora vera + contesto del segnale), FIFO con fee pro-quota, riconciliazione a tre fonti, sqlite in data/live/ (dentro il perimetro del backup). Le tre fonti si INCROCIANO e non si sovrascrivono: reconcile() riporta le divergenze e non ripara niente da solo. Il venue e' autorevole ma TRONCA (1 trade su BTC, 0 su ETH): dichiarato. - scripts/live/trades_db.py: --sync (idempotente, in cron_book ogni ora), --report, --reconcile. - src/live/journal.py + scripts/live/journal.py: una voce al giorno in docs/journal/YYYY-MM-DD.md — mercato (ritorni, RV30, TSMOM sugli orizzonti di produzione, DVOL con eta'), libro (TP01/SKH01, target, posizione, leva), P&L (equity del venue come autorita', scomposizione locale), salute. NIENTE narrativa automatica: il campo `nota` e' l'unico posto per il testo libero ed e' dell'operatore, mai riscritto da un ricalcolo. - book_execute.py: ts_utc = ora vera del fill, bar_ts = barra. Test di regressione sulla sorgente: se qualcuno rimette last_data, il test lo dice. - 62 voci di giornale ricostruite dall'arming a oggi. Tre difetti trovati dai test mentre scrivevo, non a occhio: il renderer cadeva in KeyError se mancava il blocco mercato (un giornale che non si scrive non e' un giornale); "24 giri attesi" su un giorno IN CORSO produceva un allarme a ogni esecuzione; e libro e P&L leggevano due istanti diversi, quindi la stessa pagina mostrava due equity. Strategia, pesi, config INVARIATI. Nessun ordine. 659 test passano. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |