stampe, testi e piccoli calcoli che dicono il falso (14 rilievi minori) #35

Closed
opened 2026-09-27 13:12:15 +00:00 by Adriano · 7 comments
Owner

Revisione 2026-09-27 (goldrake): rilievo Opus 5.5, verifica avversariale fable. Sola lettura, nessun codice toccato.

Rilievo B3 [bug]

FILE: pg:scripts/live/usde_watch.py:66,165-169,327-334
COSA: "📌 USDE: la decisione di QUOTA e' dovuta" parte OGNI giorno da 28 giorni, anche se la decisione e' presa (quota derivata 0,64 dal 10/09, config _nota_cuscino).
SCENARIO: ogni 12:35Z Telegram riceve la stessa domanda gia' risolta -> l'operatore impara a ignorare i messaggi di usde_watch (P14), incluso il ⚠️ di depeg/quota che arriva dallo stesso mittente.
PROVA: VERIFICATO: grep -c QUOTA_DA_DECIDERE logs/cron_usde.log -> 28; ultimo 2026-09-27T12:35 "allarmi : QUOTA_DA_DECIDERE".
PROPOSTA: togliere DECISIONE_QUOTA_DAL / quota_da_decidere (il docstring stesso dice «si smette togliendo DECISIONE_QUOTA_DAL»); correggere anche il testo IDONEO «tetto allerta 50%» (riga 317; tetto 0,85).

Verifica fable B3 VERDETTO: CONFERMATO

GRAVITA': basso
PERCHE': usde_watch.py:66 DECISIONE_QUOTA_DAL="2026-08-31", quota_da_decidere (165-169) vera per sempre da quella data se IDONEO; grep -c QUOTA_DA_DECIDERE logs/cron_usde.log -> 28; l'ultimo giro 27/09 stampa allarmi : QUOTA_DA_DECIDERE. La ripetizione e' documentata come voluta (commento 322-325) ma la sua ragione e' caduta il 10/09 (quota DERIVATA, config/live.json usde._nota_cuscino). Testo IDONEO «tetto allerta 50%» (riga 317) cablato contro quota_max_frac 0.85 in config. Non e' una decisione vincolante nel CLAUDE.md: e' un promemoria che il codice stesso dice di togliere.
CORREZIONE: ok (togliere DECISIONE_QUOTA_DAL/quota_da_decidere; nel testo IDONEO usare c['quota_max_frac']).

Rilievo B4 [registro-falso]

FILE: pg:scripts/live/usde_watch.py:347-355
COSA: il report stampa ogni giorno «conto SEGREGATO: l'USDE non fa margine», ma il modello e' Cross X:SM dal 2026-08-31 (CLAUDE.md §1 riga 102).
SCENARIO: logs/cron_usde.log del 27/09: "margine : ~$1,726 — il solo USDC (conto SEGREGATO...). Con cross X:SM sarebbero ~$4,440" — il margine vero e' il secondo numero, il log dichiara il primo.
PROVA: VERIFICATO: tail logs/cron_usde.log; CLAUDE.md:102.
PROPOSTA: invertire la frase: margine cross ~$usdc+usd*(1-haircut), e rimuovere il commento 347-350.

Verifica fable B4 VERDETTO: CONFERMATO

GRAVITA': basso
PERCHE': usde_watch.py:347-353 stampa «il solo USDC (conto SEGREGATO...)»; logs/cron_usde.log 27/09: «margine : ~$1,726 — il solo USDC (conto SEGREGATO...). Con cross X:SM sarebbero ~$4,440»; CLAUDE.md:102 «Modello di margine: Cross: Standard Margin (X:SM) dal 2026-08-31». Registro falso di sola stampa (nessun calcolo a valle lo usa).
CORREZIONE: ok.

Rilievo B10 [registro-falso]

FILE: pg:scripts/live/cuscino_watch.py:161-171,83
COSA: riconverti registra ok=False/«FALLITA» per ogni rc!=0 di usde_convert, compresi timeout (kill a 900s dopo ordini gia' fillati) e "ordine accettato ma non fillato" (rc=1 con ordine rimasto aperto, B1): il registro e il Telegram dicono FALLITA quando USDE e' stato (o sara') scambiato.
SCENARIO: 30 ordini da 100 con qualche rifiuto (backoff 24/48/90s) superano i 900s -> subprocess ucciso a meta', nessuna riga finale in usde_convert.jsonl, cuscino_watch scrive tentata/ok=False e manda "vendita FALLITA".
PROVA: PRESUNTO: tempo per giro ~12s pausa + 3 GET (leggi_stato x2 valute + book_top) per 60 iterazioni ~ 15 min = TIMEOUT_CONVERT_S; nessuna conversione automatica mai tentata (cuscino_watch.jsonl: 408 righe, tentate 0), quindi percorso mai esercitato in produzione.
PROPOSTA: dopo il subprocess rileggere i saldi e registrare quota_prima/quota_dopo nel record; esito = "parziale" se la quota si e' mossa.

Verifica fable B10 VERDETTO: CONFERMATO-RIDIMENSIONATO

GRAVITA': basso
PERCHE': cuscino_watch.py:161-171 ok = rc==0; timeout/eccezione -> ok False anche con fill gia' avvenuti: confermato per il TIMEOUT. Ridimensionato: (1) il caso «rc=1 accettato ma non fillato» ha tot_filled==0 (usde_convert.py:296), quindi «FALLITA» e' esatto per cio' che e' successo (il residuo e' B1, non un registro falso); (2) fill parziale seguito da stop -> rc 0 -> ok True; (3) --chunk 100, --pausa 12 (usde_convert.py:194-195): 60 iterazioni = 6.000 USDE, irraggiungibile con equity ~$4.5k; un timeout richiede ~8 rifiuti con backoff (24+48+90x6 ≈ 600s) piu' fill. Mai esercitato: cuscino_watch.jsonl 408 righe, tentata 0.
CORREZIONE: ok (quota_prima/quota_dopo nel record, esito "parziale"); il commento TIMEOUT_CONVERT_S «60 ordini = 12 min» ignora le 3-4 GET per giro: ~14s/giro -> 840s, quindi il tetto e' stretto sul caso massimo, non largo.

Rilievo B11 [pulizia]

FILE: pg:src/live/venue_probe.py:75-77,106-116,172
COSA: in_release_window (martedi' 09:00-09:30) non puo' piu' essere vera per il chiamante unico, book_execute al minuto :47 (dal 25/08): atteso e' sempre False, codice morto che si legge come una declassazione attiva.
PROVA: VERIFICATO: grep -> unico chiamante scripts/live/book_execute.py:177; crontab 47 * * * *.
PROPOSTA: dichiararlo nel docstring o rimuovere il ramo atteso; se si vuole la declassazione, legarla alla durata dell'annuncio (venue_news) e non all'orologio.

Verifica fable B11 VERDETTO: CONFERMATO

GRAVITA': basso (pulizia)
PERCHE': src/live/venue_probe.py:75-77,106-116 finestra martedi' 09:00-09:30; chiamanti di diagnose: scripts/live/book_execute.py:51,177 (cron :47 -> minuto 587, fuori da [540,570)) e scripts/live/trades_db.py:66 (report manuale). atteso non puo' essere vero in cron.
CORREZIONE: ok.

Rilievo B12 [pulizia]

FILE: pg:src/portfolio/sleeves.py:405-406 (usato da scripts/live/edge_watch.py:59-61)
COSA: edge_watch giudica il book con pesi CABLATI 0.75/0.25 invece di importare book.W_TP01/W_SKH (P1), e misura il backtest dei sleeve sul feed certificato, non il P&L eseguito (trades.db): il titolo «criterio di kill scattato sul book LIVE» descrive una cosa che non legge.
PROVA: VERIFICATO: lettura sleeves.py:405-406, edge_watch.py:59-61,110.
PROPOSTA: importare i pesi da src.live.book; aggiungere (o dichiarare assente) un criterio sul realizzato (slippage/fee vs backtest) e correggere il titolo.

Verifica fable B12 VERDETTO: CONFERMATO

GRAVITA': basso (pulizia)
PERCHE': src/portfolio/sleeves.py:405-406 weight=0.75/0.25 cablati; src/live/book.py:56-57 W_TP01=0.75, W_SKH=0.25: oggi coincidono, ma sono due dichiarazioni (P1). scripts/live/edge_watch.py:59-61 misura book_daily() (backtest dei sleeve sul feed), :143 titolo «criterio di kill scattato sul book LIVE». Il docstring (righe 4-25) dichiara la regola sul backtest: il titolo e' l'unica cosa falsa.
CORREZIONE: ok (importare i pesi da book; titolo «sul book (serie backtest, non il P&L eseguito)»); aggiungere un criterio sul realizzato e' uno sviluppo, non una correzione.

Rilievo C3 [registro-falso]

FILE: PG:scripts/live/telegram_daily.py:62-65
COSA: "accensione a X" usa il riferimento negativo piu' basso; con TUTTI e tre gli orizzonti negativi girarne uno da' media −1/3 -> TP01 resta 0.
SCENARIO: segni −1/−1/−1 -> il messaggio dice "accensione a ", ma al superamento di quel prezzo TP01 resta 0; serve il SECONDO riferimento piu' basso.
PROVA: VERIFICATO (lettura + aritmetica): tgt=max(0, mean(sg)); con 2 negativi e 1 positivo la soglia e' il min, con 3 negativi e' il secondo in ordine crescente.
PROPOSTA: soglia = sorted(refs negativi)[len(neg) - 1] se servono k flip (k = numero minimo per mean>0: 1 con 2 negativi, 2 con 3), cioe' sorted(r for _,r in neg)[len(neg)-2].

Verifica fable C3 VERDETTO: CONFERMATO

GRAVITA': basso
PERCHE': scripts/live/telegram_daily.py:57-65: tgt = max(0, mean(sg)); con tre segni −1 serve che DUE riferimenti vengano superati (mean −1/3 -> ancora 0); il codice stampa min(neg) = il piu' basso, superato il quale TP01 resta 0. Aritmetica verificata.
CORREZIONE: ok: sorted(r for _, r in neg)[len(neg) - 2] (min per 2 negativi, secondo per 3).

Rilievo C7 [registro-falso]

FILE: PG:src/live/journal.py:606-610 (regola drawdown)
COSA: il picco e' sull'equity GREZZA, movimenti inclusi. Un prelievo certo (gia' classificato e scorporato altrove nella stessa pagina) diventa "Equity X% sotto il picco".
SCENARIO: prelievo di $1.000 su $4.570 -> la lettura stampa "Equity −21,9% sotto il picco" in un giorno a P&L nullo. (Oggi ci sono stati solo versamenti, che alzano il picco senza danno visibile.)
PROPOSTA: calcolare il DD sulla serie al netto dei movimenti certi (cumulata dei segmenti di rendimento_twr) o tacere la regola nei giorni successivi a un movimento negativo, dichiarandolo.

Verifica fable C7 VERDETTO: CONFERMATO

GRAVITA': basso (latente: finora solo versamenti)
PERCHE': journal.py:596 picco = max(r["equity"] for r in eq) sulla serie grezza; 613-615 dd = (e1-picco)/picco. Un prelievo certo (che la stessa pagina scorpora in mv_ev) diventa drawdown. Il versamento oggi alza il picco: un P&L negativo successivo sarebbe misurato dal picco gonfiato — quindi anche oggi il numero non e' quello che dice.
CORREZIONE: ok (DD sulla serie al netto dei movimenti certi, cumulando i segmenti TWR).

Rilievo C8 [registro-falso]

FILE: PG:src/live/analista.py:207-211 (testata Telegram)
COSA: la testata stampa delta_equity GREZZO come «(… oggi)»: in un giorno di versamento dice «+1.399 oggi». Il cumulato e' qualificato «di cui versati», il giornaliero no; e «oggi» e' IERI (il cron gira alle 00:30 sul giorno chiuso).
PROPOSTA: se mov_giorno != 0 mostrare trading_giorno con «(di cui X movimenti)»; etichetta «nel giorno» invece di «oggi».

Verifica fable C8 VERDETTO: CONFERMATO

GRAVITA': basso
PERCHE': src/live/analista.py:207-211 stampa p["delta_equity"] grezzo con etichetta «oggi»; journal.py:369-373 delta_equity e' il grezzo, trading_giorno = delta - mov_g esiste e non e' usato in testata; cron_daily.sh gira alle 00:30 su yesterday.
CORREZIONE: ok.

Rilievo C9 [bug] (basso)

FILE: PG:src/live/journal.py:376-377 (salute, giorno in corso)
COSA: attesi = ora+1, ma il giro gira al :47. Fra hh:00 e hh:47 la pagina di un giorno in corso segna sempre «1 mancante» con livello attenzione.
PROVA: VERIFICATO (lettura): alle 12:10 giri fatti 00:47..11:47 = 12, atteso 13. Il test test_journal.py:39 non copre la finestra.
PROPOSTA: atteso = adesso.hour + (1 if adesso.minute >= 48 else 0) (o derivare il minuto dal crontab/cron_book).

Verifica fable C9 VERDETTO: CONFERMATO

GRAVITA': basso
PERCHE': journal.py:388-389 atteso = adesso.hour + 1 per il giorno in corso; il giro cade al :47, quindi fra hh:00 e hh:47 il giro dell'ora corrente non e' ancora avvenuto -> «1 mancante» stabile per 47 minuti di ogni ora (il docstring 383-385 dice di voler evitare proprio l'allarme che scatta sempre).
CORREZIONE: ok (adesso.hour + (1 if adesso.minute >= 48 else 0); il minuto andrebbe letto da una costante condivisa con cron_book, non cablato una seconda volta).

Rilievo C13 [bug] (basso)

FILE: PG:src/live/revisione.py:261-264; src/live/analista.py:239-241
COSA: il taglio per Telegram avviene su testo gia' HTML (escape/tag): puo' spezzare un'entita' (&am) o lasciare un <b> aperto -> Telegram rifiuta con «can't parse entities» e il messaggio si perde (registrato come FALLITA/telegram False, quindi non silenzioso).
SCENARIO: Sintesi della revisione > 3.500 caratteri con un & o < vicino al taglio.
PROPOSTA: tagliare il testo PRIMA di html.escape (e prima della sostituzione **…**-><b>).

Verifica fable C13 VERDETTO: CONFERMATO

GRAVITA': basso
PERCHE': src/live/revisione.py:261-264 taglia corpo DOPO html.escape -> puo' spezzare &amp;; src/live/analista.py:239-241 taglia testo che gia' contiene <b>/<i> -> tag aperto. Telegram rifiuta «can't parse entities»; l'esito e' registrato (analista inviata_stato), quindi non silenzioso.
CORREZIONE: ok (tagliare prima dell'escape/markup; in analista tagliare la sola corpo prima di comporre).

Rilievo C14 [pulizia]

FILE: PG:scripts/live/telegram_daily.py:31-32, 94
COSA: date dei gate cablate (STATARB 2026-09-27 = oggi, XSR01 2026-10-23), duplicate di CLAUDE.md §4; da domani la riga stampa «(−-1g)». Header fisso «Perche' non opera» anche col libro a mercato.
PROPOSTA: leggere i gate da una fonte unica (monitor_health o config) e formattare «scaduto da N g».

Verifica fable C14 VERDETTO: CONFERMATO

GRAVITA': basso (pulizia)
PERCHE': scripts/live/telegram_daily.py:31-32 GATES con date cablate (STATARB 2026-09-27 = oggi); :91 giorni = (dec - date.today()).days, :93 formato (−{giorni}g) -> da domani «(−-1g)». Duplicato di CLAUDE.md §4.
CORREZIONE: ok.

Rilievo C15 [pulizia]

FILE: PG:src/live/journal.py:589-600 (regola concentrazione)
COSA: la finestra «ultimi 7 giorni» prende letture da giorno−7 incluso fino a giorno = 8 giorni di calendario.
PROPOSTA: g7s = giorno − 6 giorni (o baseline = ultima lettura PRIMA di g7s).

Verifica fable C15 VERDETTO: CONFERMATO

GRAVITA': basso (pulizia)
PERCHE': journal.py:594-597 g7s = giorno - 7 giorni, g7 = [r ... >= g7s], baseline g7[0] = prima lettura di giorno−7 -> la finestra copre 8 giorni di calendario mentre il testo dice «ultimi 7 giorni».
CORREZIONE: ok.

Rilievo A7 [pulizia]

FILE: PG:src/live/book.py:318
COSA: build_book_order(..., min_usd=5.0) cablato, mentre book_execute usa min_order_usd di config per rebalance_signed: se la config scende sotto 5 il report dice HOLD e nessun ordine parte; se sale, report e log dicono "BUY" per ordini che rebalance_signed poi scarta. Viola "config/live.json unica autorita'".
PROVA: VERIFICATO: book.py:318, book_execute.py:93,272.
PROPOSTA: leggere min_order_usd dalla config in book_report (o passarlo come parametro).

Verifica fable A7 VERDETTO: CONFERMATO

GRAVITA': basso
PERCHE': book.py:318 build_book_order(..., min_usd=5.0) cablato; book_execute.py:93,272 usa min_order_usd di config per rebalance_signed. Oggi coincidono (config 5).
CORREZIONE: ok.

Rilievo A9 [pulizia]

FILE: PG:src/live/execution.py:11-12,20-22; src/live/deribit.py:1-10; src/live/book.py:7,16,20; src/live/tradesdb.py:5-8
COSA: commenti che contraddicono il codice: execution.py "finestra d'uso attuale: micro-test ... deploy pieno gated" (armato dal 23/06) e "MAX_AMOUNT ~$630/$430 su conto ~$600"; deribit.py "SOLA LETTURA ... contratti ristretti a BTC/ETH-PERPETUAL inverse, amount in USD" (si usano i lineari USDC, amount in coin); book.py "budget di rischio $300/asset", "cap fisso $300" (config 3000, cap dinamico); tradesdb.py "ts_utc e' la data della barra" (corretto il 23/08 in book_execute).
PROVA: VERIFICATO: lettura dei file citati.
PROPOSTA: allineare i docstring (nessun cambio di codice).

Verifica fable A9 VERDETTO: CONFERMATO

GRAVITA': basso
PERCHE': letti: execution.py:11-12 ("micro-test", "deploy gated"; armato dal 23/06 per config) e :20-21 ("~$630/$430 su conto ~$600"); deribit.py:1-10 ("SOLA LETTURA", "inverse, amount in USD"); book.py:7,16 ("$300/asset", "($300)"; config 3000 + cap dinamico); tradesdb.py:5-8 ("ts_utc e' la data della barra", corretto il 23/08 in book_execute.py:276-279).
CORREZIONE: ok.

Revisione 2026-09-27 (goldrake): rilievo Opus 5.5, verifica avversariale fable. Sola lettura, nessun codice toccato. ### Rilievo B3 [bug] FILE: pg:scripts/live/usde_watch.py:66,165-169,327-334 COSA: "📌 USDE: la decisione di QUOTA e' dovuta" parte OGNI giorno da 28 giorni, anche se la decisione e' presa (quota derivata 0,64 dal 10/09, config `_nota_cuscino`). SCENARIO: ogni 12:35Z Telegram riceve la stessa domanda gia' risolta -> l'operatore impara a ignorare i messaggi di usde_watch (P14), incluso il ⚠️ di depeg/quota che arriva dallo stesso mittente. PROVA: VERIFICATO: `grep -c QUOTA_DA_DECIDERE logs/cron_usde.log` -> 28; ultimo 2026-09-27T12:35 "allarmi : QUOTA_DA_DECIDERE". PROPOSTA: togliere DECISIONE_QUOTA_DAL / quota_da_decidere (il docstring stesso dice «si smette togliendo DECISIONE_QUOTA_DAL»); correggere anche il testo IDONEO «tetto allerta 50%» (riga 317; tetto 0,85). ### Verifica fable B3 VERDETTO: CONFERMATO GRAVITA': basso PERCHE': `usde_watch.py:66` `DECISIONE_QUOTA_DAL="2026-08-31"`, `quota_da_decidere` (165-169) vera per sempre da quella data se IDONEO; `grep -c QUOTA_DA_DECIDERE logs/cron_usde.log` -> 28; l'ultimo giro 27/09 stampa `allarmi : QUOTA_DA_DECIDERE`. La ripetizione e' documentata come voluta (commento 322-325) ma la sua ragione e' caduta il 10/09 (quota DERIVATA, `config/live.json usde._nota_cuscino`). Testo IDONEO «tetto allerta 50%» (riga 317) cablato contro `quota_max_frac` 0.85 in config. Non e' una decisione vincolante nel CLAUDE.md: e' un promemoria che il codice stesso dice di togliere. CORREZIONE: ok (togliere `DECISIONE_QUOTA_DAL`/`quota_da_decidere`; nel testo IDONEO usare `c['quota_max_frac']`). ### Rilievo B4 [registro-falso] FILE: pg:scripts/live/usde_watch.py:347-355 COSA: il report stampa ogni giorno «conto SEGREGATO: l'USDE non fa margine», ma il modello e' Cross X:SM dal 2026-08-31 (CLAUDE.md §1 riga 102). SCENARIO: logs/cron_usde.log del 27/09: "margine : ~$1,726 — il solo USDC (conto SEGREGATO...). Con cross X:SM sarebbero ~$4,440" — il margine vero e' il secondo numero, il log dichiara il primo. PROVA: VERIFICATO: tail logs/cron_usde.log; CLAUDE.md:102. PROPOSTA: invertire la frase: margine cross ~$usdc+usd*(1-haircut), e rimuovere il commento 347-350. ### Verifica fable B4 VERDETTO: CONFERMATO GRAVITA': basso PERCHE': `usde_watch.py:347-353` stampa «il solo USDC (conto SEGREGATO...)»; `logs/cron_usde.log` 27/09: «margine : ~$1,726 — il solo USDC (conto SEGREGATO...). Con cross X:SM sarebbero ~$4,440»; `CLAUDE.md:102` «Modello di margine: Cross: Standard Margin (X:SM) dal 2026-08-31». Registro falso di sola stampa (nessun calcolo a valle lo usa). CORREZIONE: ok. ### Rilievo B10 [registro-falso] FILE: pg:scripts/live/cuscino_watch.py:161-171,83 COSA: `riconverti` registra ok=False/«FALLITA» per ogni rc!=0 di usde_convert, compresi timeout (kill a 900s dopo ordini gia' fillati) e "ordine accettato ma non fillato" (rc=1 con ordine rimasto aperto, B1): il registro e il Telegram dicono FALLITA quando USDE e' stato (o sara') scambiato. SCENARIO: 30 ordini da 100 con qualche rifiuto (backoff 24/48/90s) superano i 900s -> subprocess ucciso a meta', nessuna riga finale in usde_convert.jsonl, cuscino_watch scrive tentata/ok=False e manda "vendita FALLITA". PROVA: PRESUNTO: tempo per giro ~12s pausa + 3 GET (leggi_stato x2 valute + book_top) per 60 iterazioni ~ 15 min = TIMEOUT_CONVERT_S; nessuna conversione automatica mai tentata (`cuscino_watch.jsonl`: 408 righe, tentate 0), quindi percorso mai esercitato in produzione. PROPOSTA: dopo il subprocess rileggere i saldi e registrare quota_prima/quota_dopo nel record; esito = "parziale" se la quota si e' mossa. ### Verifica fable B10 VERDETTO: CONFERMATO-RIDIMENSIONATO GRAVITA': basso PERCHE': `cuscino_watch.py:161-171` `ok = rc==0`; timeout/eccezione -> ok False anche con fill gia' avvenuti: confermato per il TIMEOUT. Ridimensionato: (1) il caso «rc=1 accettato ma non fillato» ha `tot_filled==0` (`usde_convert.py:296`), quindi «FALLITA» e' esatto per cio' che e' successo (il residuo e' B1, non un registro falso); (2) fill parziale seguito da stop -> rc 0 -> ok True; (3) `--chunk` 100, `--pausa` 12 (`usde_convert.py:194-195`): 60 iterazioni = 6.000 USDE, irraggiungibile con equity ~$4.5k; un timeout richiede ~8 rifiuti con backoff (24+48+90x6 ≈ 600s) piu' fill. Mai esercitato: `cuscino_watch.jsonl` 408 righe, `tentata` 0. CORREZIONE: ok (quota_prima/quota_dopo nel record, esito "parziale"); il commento `TIMEOUT_CONVERT_S` «60 ordini = 12 min» ignora le 3-4 GET per giro: ~14s/giro -> 840s, quindi il tetto e' stretto sul caso massimo, non largo. ### Rilievo B11 [pulizia] FILE: pg:src/live/venue_probe.py:75-77,106-116,172 COSA: `in_release_window` (martedi' 09:00-09:30) non puo' piu' essere vera per il chiamante unico, book_execute al minuto :47 (dal 25/08): `atteso` e' sempre False, codice morto che si legge come una declassazione attiva. PROVA: VERIFICATO: grep -> unico chiamante scripts/live/book_execute.py:177; crontab `47 * * * *`. PROPOSTA: dichiararlo nel docstring o rimuovere il ramo `atteso`; se si vuole la declassazione, legarla alla durata dell'annuncio (venue_news) e non all'orologio. ### Verifica fable B11 VERDETTO: CONFERMATO GRAVITA': basso (pulizia) PERCHE': `src/live/venue_probe.py:75-77,106-116` finestra martedi' 09:00-09:30; chiamanti di `diagnose`: `scripts/live/book_execute.py:51,177` (cron :47 -> minuto 587, fuori da [540,570)) e `scripts/live/trades_db.py:66` (report manuale). `atteso` non puo' essere vero in cron. CORREZIONE: ok. ### Rilievo B12 [pulizia] FILE: pg:src/portfolio/sleeves.py:405-406 (usato da scripts/live/edge_watch.py:59-61) COSA: edge_watch giudica il book con pesi CABLATI 0.75/0.25 invece di importare book.W_TP01/W_SKH (P1), e misura il backtest dei sleeve sul feed certificato, non il P&L eseguito (trades.db): il titolo «criterio di kill scattato sul book LIVE» descrive una cosa che non legge. PROVA: VERIFICATO: lettura sleeves.py:405-406, edge_watch.py:59-61,110. PROPOSTA: importare i pesi da src.live.book; aggiungere (o dichiarare assente) un criterio sul realizzato (slippage/fee vs backtest) e correggere il titolo. ### Verifica fable B12 VERDETTO: CONFERMATO GRAVITA': basso (pulizia) PERCHE': `src/portfolio/sleeves.py:405-406` `weight=0.75/0.25` cablati; `src/live/book.py:56-57` `W_TP01=0.75, W_SKH=0.25`: oggi coincidono, ma sono due dichiarazioni (P1). `scripts/live/edge_watch.py:59-61` misura `book_daily()` (backtest dei sleeve sul feed), `:143` titolo «criterio di kill scattato sul book LIVE». Il docstring (righe 4-25) dichiara la regola sul backtest: il titolo e' l'unica cosa falsa. CORREZIONE: ok (importare i pesi da book; titolo «sul book (serie backtest, non il P&L eseguito)»); aggiungere un criterio sul realizzato e' uno sviluppo, non una correzione. ### Rilievo C3 [registro-falso] FILE: PG:scripts/live/telegram_daily.py:62-65 COSA: "accensione a X" usa il riferimento negativo piu' basso; con TUTTI e tre gli orizzonti negativi girarne uno da' media −1/3 -> TP01 resta 0. SCENARIO: segni −1/−1/−1 -> il messaggio dice "accensione a <ref minimo>", ma al superamento di quel prezzo TP01 resta 0; serve il SECONDO riferimento piu' basso. PROVA: VERIFICATO (lettura + aritmetica): tgt=max(0, mean(sg)); con 2 negativi e 1 positivo la soglia e' il min, con 3 negativi e' il secondo in ordine crescente. PROPOSTA: `soglia = sorted(refs negativi)[len(neg) - 1]` se servono k flip (k = numero minimo per mean>0: 1 con 2 negativi, 2 con 3), cioe' `sorted(r for _,r in neg)[len(neg)-2]`. ### Verifica fable C3 VERDETTO: CONFERMATO GRAVITA': basso PERCHE': `scripts/live/telegram_daily.py:57-65`: `tgt = max(0, mean(sg))`; con tre segni −1 serve che DUE riferimenti vengano superati (mean −1/3 -> ancora 0); il codice stampa `min(neg)` = il piu' basso, superato il quale TP01 resta 0. Aritmetica verificata. CORREZIONE: ok: `sorted(r for _, r in neg)[len(neg) - 2]` (min per 2 negativi, secondo per 3). ### Rilievo C7 [registro-falso] FILE: PG:src/live/journal.py:606-610 (regola `drawdown`) COSA: il picco e' sull'equity GREZZA, movimenti inclusi. Un prelievo certo (gia' classificato e scorporato altrove nella stessa pagina) diventa "Equity X% sotto il picco". SCENARIO: prelievo di $1.000 su $4.570 -> la lettura stampa "Equity −21,9% sotto il picco" in un giorno a P&L nullo. (Oggi ci sono stati solo versamenti, che alzano il picco senza danno visibile.) PROPOSTA: calcolare il DD sulla serie al netto dei movimenti certi (cumulata dei segmenti di `rendimento_twr`) o tacere la regola nei giorni successivi a un movimento negativo, dichiarandolo. ### Verifica fable C7 VERDETTO: CONFERMATO GRAVITA': basso (latente: finora solo versamenti) PERCHE': `journal.py:596` `picco = max(r["equity"] for r in eq)` sulla serie grezza; 613-615 `dd = (e1-picco)/picco`. Un prelievo certo (che la stessa pagina scorpora in `mv_ev`) diventa drawdown. Il versamento oggi alza il picco: un P&L negativo successivo sarebbe misurato dal picco gonfiato — quindi anche oggi il numero non e' quello che dice. CORREZIONE: ok (DD sulla serie al netto dei movimenti certi, cumulando i segmenti TWR). ### Rilievo C8 [registro-falso] FILE: PG:src/live/analista.py:207-211 (testata Telegram) COSA: la testata stampa `delta_equity` GREZZO come «(… oggi)»: in un giorno di versamento dice «+1.399 oggi». Il cumulato e' qualificato «di cui versati», il giornaliero no; e «oggi» e' IERI (il cron gira alle 00:30 sul giorno chiuso). PROPOSTA: se `mov_giorno` != 0 mostrare `trading_giorno` con «(di cui X movimenti)»; etichetta «nel giorno» invece di «oggi». ### Verifica fable C8 VERDETTO: CONFERMATO GRAVITA': basso PERCHE': `src/live/analista.py:207-211` stampa `p["delta_equity"]` grezzo con etichetta «oggi»; `journal.py:369-373` `delta_equity` e' il grezzo, `trading_giorno = delta - mov_g` esiste e non e' usato in testata; `cron_daily.sh` gira alle 00:30 su `yesterday`. CORREZIONE: ok. ### Rilievo C9 [bug] (basso) FILE: PG:src/live/journal.py:376-377 (salute, giorno in corso) COSA: attesi = ora+1, ma il giro gira al :47. Fra hh:00 e hh:47 la pagina di un giorno in corso segna sempre «1 mancante» con livello attenzione. PROVA: VERIFICATO (lettura): alle 12:10 giri fatti 00:47..11:47 = 12, atteso 13. Il test test_journal.py:39 non copre la finestra. PROPOSTA: `atteso = adesso.hour + (1 if adesso.minute >= 48 else 0)` (o derivare il minuto dal crontab/cron_book). ### Verifica fable C9 VERDETTO: CONFERMATO GRAVITA': basso PERCHE': `journal.py:388-389` `atteso = adesso.hour + 1` per il giorno in corso; il giro cade al :47, quindi fra hh:00 e hh:47 il giro dell'ora corrente non e' ancora avvenuto -> «1 mancante» stabile per 47 minuti di ogni ora (il docstring 383-385 dice di voler evitare proprio l'allarme che scatta sempre). CORREZIONE: ok (`adesso.hour + (1 if adesso.minute >= 48 else 0)`; il minuto andrebbe letto da una costante condivisa con cron_book, non cablato una seconda volta). ### Rilievo C13 [bug] (basso) FILE: PG:src/live/revisione.py:261-264; src/live/analista.py:239-241 COSA: il taglio per Telegram avviene su testo gia' HTML (escape/tag): puo' spezzare un'entita' (`&am`) o lasciare un `<b>` aperto -> Telegram rifiuta con «can't parse entities» e il messaggio si perde (registrato come FALLITA/telegram False, quindi non silenzioso). SCENARIO: Sintesi della revisione > 3.500 caratteri con un `&` o `<` vicino al taglio. PROPOSTA: tagliare il testo PRIMA di `html.escape` (e prima della sostituzione `**…**`->`<b>`). ### Verifica fable C13 VERDETTO: CONFERMATO GRAVITA': basso PERCHE': `src/live/revisione.py:261-264` taglia `corpo` DOPO `html.escape` -> puo' spezzare `&amp;`; `src/live/analista.py:239-241` taglia `testo` che gia' contiene `<b>`/`<i>` -> tag aperto. Telegram rifiuta «can't parse entities»; l'esito e' registrato (analista `inviata_stato`), quindi non silenzioso. CORREZIONE: ok (tagliare prima dell'escape/markup; in analista tagliare la sola `corpo` prima di comporre). ### Rilievo C14 [pulizia] FILE: PG:scripts/live/telegram_daily.py:31-32, 94 COSA: date dei gate cablate (STATARB 2026-09-27 = oggi, XSR01 2026-10-23), duplicate di CLAUDE.md §4; da domani la riga stampa «(−-1g)». Header fisso «Perche' non opera» anche col libro a mercato. PROPOSTA: leggere i gate da una fonte unica (monitor_health o config) e formattare «scaduto da N g». ### Verifica fable C14 VERDETTO: CONFERMATO GRAVITA': basso (pulizia) PERCHE': `scripts/live/telegram_daily.py:31-32` `GATES` con date cablate (STATARB 2026-09-27 = oggi); `:91` `giorni = (dec - date.today()).days`, `:93` formato `(−{giorni}g)` -> da domani «(−-1g)». Duplicato di CLAUDE.md §4. CORREZIONE: ok. ### Rilievo C15 [pulizia] FILE: PG:src/live/journal.py:589-600 (regola `concentrazione`) COSA: la finestra «ultimi 7 giorni» prende letture da `giorno−7` incluso fino a `giorno` = 8 giorni di calendario. PROPOSTA: `g7s = giorno − 6 giorni` (o baseline = ultima lettura PRIMA di g7s). ### Verifica fable C15 VERDETTO: CONFERMATO GRAVITA': basso (pulizia) PERCHE': `journal.py:594-597` `g7s = giorno - 7 giorni`, `g7 = [r ... >= g7s]`, baseline `g7[0]` = prima lettura di giorno−7 -> la finestra copre 8 giorni di calendario mentre il testo dice «ultimi 7 giorni». CORREZIONE: ok. ### Rilievo A7 [pulizia] FILE: PG:src/live/book.py:318 COSA: `build_book_order(..., min_usd=5.0)` cablato, mentre book_execute usa `min_order_usd` di config per rebalance_signed: se la config scende sotto 5 il report dice HOLD e nessun ordine parte; se sale, report e log dicono "BUY" per ordini che rebalance_signed poi scarta. Viola "config/live.json unica autorita'". PROVA: VERIFICATO: book.py:318, book_execute.py:93,272. PROPOSTA: leggere min_order_usd dalla config in book_report (o passarlo come parametro). ### Verifica fable A7 VERDETTO: CONFERMATO GRAVITA': basso PERCHE': book.py:318 `build_book_order(..., min_usd=5.0)` cablato; book_execute.py:93,272 usa `min_order_usd` di config per rebalance_signed. Oggi coincidono (config 5). CORREZIONE: ok. ### Rilievo A9 [pulizia] FILE: PG:src/live/execution.py:11-12,20-22; src/live/deribit.py:1-10; src/live/book.py:7,16,20; src/live/tradesdb.py:5-8 COSA: commenti che contraddicono il codice: execution.py "finestra d'uso attuale: micro-test ... deploy pieno gated" (armato dal 23/06) e "MAX_AMOUNT ~$630/$430 su conto ~$600"; deribit.py "SOLA LETTURA ... contratti ristretti a BTC/ETH-PERPETUAL inverse, amount in USD" (si usano i lineari USDC, amount in coin); book.py "budget di rischio $300/asset", "cap fisso $300" (config 3000, cap dinamico); tradesdb.py "ts_utc e' la data della barra" (corretto il 23/08 in book_execute). PROVA: VERIFICATO: lettura dei file citati. PROPOSTA: allineare i docstring (nessun cambio di codice). ### Verifica fable A9 VERDETTO: CONFERMATO GRAVITA': basso PERCHE': letti: execution.py:11-12 ("micro-test", "deploy gated"; armato dal 23/06 per config) e :20-21 ("~$630/$430 su conto ~$600"); deribit.py:1-10 ("SOLA LETTURA", "inverse, amount in USD"); book.py:7,16 ("$300/asset", "($300)"; config 3000 + cap dinamico); tradesdb.py:5-8 ("ts_utc e' la data della barra", corretto il 23/08 in book_execute.py:276-279). CORREZIONE: ok.
Adriano added the bug label 2026-09-27 13:12:15 +00:00
Author
Owner

Parti in lavoro: B3,B4 -> unita' U3 (analisi su #26); C7,C9,C15 -> unita' U4 (analisi su #27). Il resto (A7,A9,B10,B11,B12,C3,C8,C13,C14) in un secondo giro.

Parti in lavoro: B3,B4 -> unita' U3 (analisi su #26); C7,C9,C15 -> unita' U4 (analisi su #27). Il resto (A7,A9,B10,B11,B12,C3,C8,C13,C14) in un secondo giro.
Author
Owner

ESITO: fatto sul ramo, non in produzione
RIF: gitea:Adriano/PythagorasGoal#35
COSA: correzione su lavoro/goldrake (pushato), analisi Opus, codice Sonnet, controllo finale Opus
FILE: commit ac21e1c 4725839 (B3 B4 C7 C9 C15; restano A7 A9 B10 B11 B12 C3 C8 C13 C14)
PROVA: /home/adriano/lavoro/PythagorasGoal pytest -q → 1166 passed, 3 skipped
MANCA: merge su main — richiede ok esplicito di Adriano (libro vivo). Chiusura con --soluzione dopo il merge.
PROSSIMO: ok di Adriano → merge lavoro/goldrake su main → git pull in /opt/docker/PythagorasGoal

ESITO: fatto sul ramo, non in produzione RIF: gitea:Adriano/PythagorasGoal#35 COSA: correzione su lavoro/goldrake (pushato), analisi Opus, codice Sonnet, controllo finale Opus FILE: commit ac21e1c 4725839 (B3 B4 C7 C9 C15; restano A7 A9 B10 B11 B12 C3 C8 C13 C14) PROVA: /home/adriano/lavoro/PythagorasGoal pytest -q → 1166 passed, 3 skipped MANCA: merge su main — richiede ok esplicito di Adriano (libro vivo). Chiusura con --soluzione dopo il merge. PROSSIMO: ok di Adriano → merge lavoro/goldrake su main → git pull in /opt/docker/PythagorasGoal
Adriano added the attesa:adriano label 2026-09-27 14:17:43 +00:00
Adriano removed the attesa:adriano label 2026-09-27 14:28:04 +00:00
Author
Owner

ESITO: parziale su main (841d4c7)
FATTO: B3 B4 C7 C9 C15
MANCA: A7 A9 B10 B11 B12 C3 C8 C13 C14 — secondo giro

ESITO: parziale su main (841d4c7) FATTO: B3 B4 C7 C9 C15 MANCA: A7 A9 B10 B11 B12 C3 C8 C13 C14 — secondo giro
Author
Owner

ANALISI (passo 1, Opus, 27/09/2026)

ANALISI U9 — gitea:Adriano/PythagorasGoal#35 punti B10, B11, B12, A9
CARTELLA: /home/adriano/lavoro/PG-u9 RAMO: lavoro/goldrake-u9 (da main 841d4c7)
Il testo di ogni rilievo (file:riga, scenario, verifica fable) e' nell'issue: issue --repo Adriano/PythagorasGoal --forge gitea mostra 35. Leggilo prima.

B10 — scripts/live/cuscino_watch.py:161-171 riconverti
PERCHE': oggi ok = rc==0, quindi un timeout dopo fill gia' avvenuti viene registrato come "FALLITA".

  1. Prima del subprocess usde_convert, leggere la quota USDE: stessa funzione di lettura che cuscino_watch usa gia', nessuna chiamata nuova inventata. Dopo il subprocess (anche su timeout o eccezione) rileggerla.
  2. Nel record: quota_prima, quota_dopo, esito in "ok" | "parziale" | "fallita".
    • "parziale" = rc != 0 e |quota_dopo - quota_prima| > 0,005.
    • Se la rilettura dopo fallisce: quota_dopo None, esito "fallita (quota dopo non leggibile)".
    • Il campo ok resta per compatibilita': True solo per "ok".
  3. Il testo del Telegram usa l'esito. "parziale" dice "vendita PARZIALE: quota da X a Y".
  4. Il commento di TIMEOUT_CONVERT_S: correggere il conto (~14 s per giro con le GET, 60 giri = ~840 s, quindi il tetto di 900 s e' stretto sul caso massimo). NON cambiare il valore.

B11 — src/live/venue_probe.py:75-77,106-116
Rimuovere il ramo atteso (finestra del martedi' 09:00-09:30): col giro al :47 non puo' mai essere vero.

  • Prima: grep di in_release_window, atteso, RELEASE in src/ scripts/ tests/.
  • Se un test lo esercita: aggiornarlo o rimuoverlo e dirlo.
  • Se il campo atteso e' letto a valle (es. un dict di diagnose), lasciarlo sempre False con un commento. Non rompere il formato.
  • Se la rimozione tocca piu' di ~3 file: al suo posto un docstring che dichiara il ramo morto e perche'. Scegli la via meno invasiva e dillo.

B12 — src/portfolio/sleeves.py:405-406 e scripts/live/edge_watch.py

  1. Pesi: sleeves.py importa W_TP01 e W_SKH da src.live.book invece dei letterali 0.75/0.25.
    • ATTENZIONE import circolari: book importa shadow e altri moduli. Se l'import a livello di modulo crea un ciclo, usare l'import locale dentro la funzione (come fa usde.py con book).
  2. edge_watch.py titolo (~:143): "criterio di kill scattato sul book (serie backtest dei sleeve, non il P&L eseguito)". Il criterio sul realizzato NON si aggiunge: e' uno sviluppo.

A9 — solo docstring e commenti, nessun cambio di codice

  • src/live/execution.py:11-12,20-22: via "micro-test"/"deploy gated". Il libro e' armato dal 23/06 (execution_enabled in config). MAX_AMOUNT e' il default del micro-test, sostituito da set_open_cap (#18). Via "~$630/$430 su conto ~$600".
  • src/live/deribit.py:1-10: non "SOLA LETTURA / inverse / amount in USD". Sono i perp lineari USDC; position_usd restituisce notional in USD col segno da direction (#17); gli ordini vanno in coin.
  • src/live/book.py:7,16,20: il cap e' dinamico (equity x max_notional_per_asset_frac) sul percorso fidato; quello fisso e' max_notional_per_asset_usd di config, non "$300". Nessun importo cablato nel testo: si citano le chiavi.
  • NON toccare src/live/tradesdb.py (lo fa un'altra unita').
    Verifica ogni frase contro il codice attuale prima di scriverla.

TEST

  • B10: tests per riconverti con subprocess finto (rc 0, rc 1 con quota mossa, timeout con quota mossa, rilettura fallita) e lettore quota finto. Nessuna rete, nessun Telegram: monkeypatch di notify, come nei test esistenti di cuscino_watch (grep tests/test_cuscino*).
  • B11: i test esistenti di venue_probe verdi.
  • B12: test che sleeves usa i pesi di book (monkeypatch di B.W_TP01 non serve; basta un assert che i valori coincidano e che il letterale non ci sia piu', se esiste un pattern simile nei test del repo; altrimenti solo la suite).
    Suite: cd /home/adriano/lavoro/PG-u9 && /opt/docker/PythagorasGoal/.venv/bin/python -m pytest -q -p no:cacheprovider. Baseline 1166 passed, 3 skipped.
    NON TOCCARE: TIMEOUT_CONVERT_S (valore), usde_convert.py, tradesdb.py, book_execute.py.
    COMMIT: uno per punto: "(#35 B10)", "(#35 B11)", "(#35 B12)", "(#35 A9)".
ANALISI (passo 1, Opus, 27/09/2026) ANALISI U9 — gitea:Adriano/PythagorasGoal#35 punti B10, B11, B12, A9 CARTELLA: /home/adriano/lavoro/PG-u9 RAMO: lavoro/goldrake-u9 (da main 841d4c7) Il testo di ogni rilievo (file:riga, scenario, verifica fable) e' nell'issue: `issue --repo Adriano/PythagorasGoal --forge gitea mostra 35`. Leggilo prima. B10 — scripts/live/cuscino_watch.py:161-171 `riconverti` PERCHE': oggi ok = rc==0, quindi un timeout dopo fill gia' avvenuti viene registrato come "FALLITA". 1. Prima del subprocess usde_convert, leggere la quota USDE: stessa funzione di lettura che cuscino_watch usa gia', nessuna chiamata nuova inventata. Dopo il subprocess (anche su timeout o eccezione) rileggerla. 2. Nel record: quota_prima, quota_dopo, esito in "ok" | "parziale" | "fallita". - "parziale" = rc != 0 e |quota_dopo - quota_prima| > 0,005. - Se la rilettura dopo fallisce: quota_dopo None, esito "fallita (quota dopo non leggibile)". - Il campo `ok` resta per compatibilita': True solo per "ok". 3. Il testo del Telegram usa l'esito. "parziale" dice "vendita PARZIALE: quota da X a Y". 4. Il commento di TIMEOUT_CONVERT_S: correggere il conto (~14 s per giro con le GET, 60 giri = ~840 s, quindi il tetto di 900 s e' stretto sul caso massimo). NON cambiare il valore. B11 — src/live/venue_probe.py:75-77,106-116 Rimuovere il ramo `atteso` (finestra del martedi' 09:00-09:30): col giro al :47 non puo' mai essere vero. - Prima: grep di `in_release_window`, `atteso`, `RELEASE` in src/ scripts/ tests/. - Se un test lo esercita: aggiornarlo o rimuoverlo e dirlo. - Se il campo `atteso` e' letto a valle (es. un dict di diagnose), lasciarlo sempre False con un commento. Non rompere il formato. - Se la rimozione tocca piu' di ~3 file: al suo posto un docstring che dichiara il ramo morto e perche'. Scegli la via meno invasiva e dillo. B12 — src/portfolio/sleeves.py:405-406 e scripts/live/edge_watch.py 1. Pesi: sleeves.py importa W_TP01 e W_SKH da src.live.book invece dei letterali 0.75/0.25. - ATTENZIONE import circolari: book importa shadow e altri moduli. Se l'import a livello di modulo crea un ciclo, usare l'import locale dentro la funzione (come fa usde.py con book). 2. edge_watch.py titolo (~:143): "criterio di kill scattato sul book (serie backtest dei sleeve, non il P&L eseguito)". Il criterio sul realizzato NON si aggiunge: e' uno sviluppo. A9 — solo docstring e commenti, nessun cambio di codice - src/live/execution.py:11-12,20-22: via "micro-test"/"deploy gated". Il libro e' armato dal 23/06 (execution_enabled in config). MAX_AMOUNT e' il default del micro-test, sostituito da set_open_cap (#18). Via "~$630/$430 su conto ~$600". - src/live/deribit.py:1-10: non "SOLA LETTURA / inverse / amount in USD". Sono i perp lineari USDC; position_usd restituisce notional in USD col segno da direction (#17); gli ordini vanno in coin. - src/live/book.py:7,16,20: il cap e' dinamico (equity x max_notional_per_asset_frac) sul percorso fidato; quello fisso e' max_notional_per_asset_usd di config, non "$300". Nessun importo cablato nel testo: si citano le chiavi. - NON toccare src/live/tradesdb.py (lo fa un'altra unita'). Verifica ogni frase contro il codice attuale prima di scriverla. TEST - B10: tests per riconverti con subprocess finto (rc 0, rc 1 con quota mossa, timeout con quota mossa, rilettura fallita) e lettore quota finto. Nessuna rete, nessun Telegram: monkeypatch di notify, come nei test esistenti di cuscino_watch (grep tests/test_cuscino*). - B11: i test esistenti di venue_probe verdi. - B12: test che sleeves usa i pesi di book (monkeypatch di B.W_TP01 non serve; basta un assert che i valori coincidano e che il letterale non ci sia piu', se esiste un pattern simile nei test del repo; altrimenti solo la suite). Suite: `cd /home/adriano/lavoro/PG-u9 && /opt/docker/PythagorasGoal/.venv/bin/python -m pytest -q -p no:cacheprovider`. Baseline 1166 passed, 3 skipped. NON TOCCARE: TIMEOUT_CONVERT_S (valore), usde_convert.py, tradesdb.py, book_execute.py. COMMIT: uno per punto: "(#35 B10)", "(#35 B11)", "(#35 B12)", "(#35 A9)".
Author
Owner

ANALISI (passo 1, Opus, 27/09/2026)

ANALISI U10 — gitea:Adriano/PythagorasGoal#35 punti C3, C8, C13, C14
CARTELLA: /home/adriano/lavoro/PG-u10 RAMO: lavoro/goldrake-u10 (da main 841d4c7)
Testo dei rilievi: issue --repo Adriano/PythagorasGoal --forge gitea mostra 35. Leggilo prima.

C3 — scripts/live/telegram_daily.py:57-65, "accensione a X"
tgt = max(0, mean(sg)): per accendere TP01 servono abbastanza flip perche' la media dei segni diventi > 0.

  • 2 negativi e 1 positivo: basta superare il riferimento negativo piu' basso.
  • 3 negativi: servono due flip, quindi il SECONDO piu' basso.
  • Formula generale: con segni in {-1,+1} e n orizzonti, k = numero minimo di flip da -1 a +1 perche' sum > 0. La soglia e' sorted(ref negativi)[k-1].
  • Implementala generale, non solo i due casi; lo stesso per segni 0 se esistono (controlla i valori possibili nel codice).
  • Se k > numero di negativi (impossibile), niente riga.

C8 — src/live/analista.py:207-211 testata Telegram

  • Se p["mov_giorno"] e' diverso da 0 (o assente/None: stesso trattamento di journal), la cifra e' p["trading_giorno"] con "(di cui $X movimenti)", non delta_equity grezzo.
  • L'etichetta "oggi" diventa "nel giorno": il cron gira alle 00:30 sul giorno chiuso.
  • Se trading_giorno e' None, resta delta_equity con l'etichetta nuova.

C13 — taglio per Telegram su testo gia' HTML

  • src/live/revisione.py:261-264: tagliare corpo PRIMA di html.escape.
  • src/live/analista.py:239-241: tagliare il corpo testuale PRIMA di comporre i tag /.
  • Il limite resta quello di oggi; si mantiene il margine per tag e testata.
  • Il marcatore di taglio (es. "…") si aggiunge dopo, fuori dall'escape.

C14 — scripts/live/telegram_daily.py:31-32,91-94

  • GATES cablati: non inventare una fonte. Se src/live/monitor_health.py ha gia' i gate con le date (campo gate nella tabella), leggili da li'. Se no, lasciali cablati con un commento che li lega a CLAUDE.md §4 e dillo nel rapporto.
  • Formato: giorni > 0 -> "(-Ng)"; 0 -> "(oggi)"; < 0 -> "(scaduto da Ng)". Mai "(−-1g)".
  • L'header fisso "Perche' non opera": solo se il libro e' davvero fermo. Guarda come il messaggio sa se ci sono posizioni. Se non lo sa senza una lettura nuova, usa un header neutro, es. "Gate e stato", e dillo.

TEST: per ognuno, funzioni pure con input finti.

  • C3: casi 2 neg + 1 pos, 3 neg, 1 neg + 2 pos (gia' acceso -> nessuna riga o come oggi).
  • C13: testo con "&" e "" a cavallo del taglio -> HTML valido, entita' e tag chiusi.
  • C14: date passate, di oggi, future.
    Monkeypatch di notify; nessun Telegram, nessuna rete.
    Suite: cd /home/adriano/lavoro/PG-u10 && /opt/docker/PythagorasGoal/.venv/bin/python -m pytest -q -p no:cacheprovider. Baseline 1166 passed, 3 skipped.
    NON TOCCARE: src/live/revisione.py oltre il taglio (MAX_CHARS_VOCE lo cambia un'altra unita'); journal.py.
    COMMIT: uno per punto: "(#35 C3)", "(#35 C8)", "(#35 C13)", "(#35 C14)".
ANALISI (passo 1, Opus, 27/09/2026) ANALISI U10 — gitea:Adriano/PythagorasGoal#35 punti C3, C8, C13, C14 CARTELLA: /home/adriano/lavoro/PG-u10 RAMO: lavoro/goldrake-u10 (da main 841d4c7) Testo dei rilievi: `issue --repo Adriano/PythagorasGoal --forge gitea mostra 35`. Leggilo prima. C3 — scripts/live/telegram_daily.py:57-65, "accensione a X" tgt = max(0, mean(sg)): per accendere TP01 servono abbastanza flip perche' la media dei segni diventi > 0. - 2 negativi e 1 positivo: basta superare il riferimento negativo piu' basso. - 3 negativi: servono due flip, quindi il SECONDO piu' basso. - Formula generale: con segni in {-1,+1} e n orizzonti, k = numero minimo di flip da -1 a +1 perche' sum > 0. La soglia e' sorted(ref negativi)[k-1]. - Implementala generale, non solo i due casi; lo stesso per segni 0 se esistono (controlla i valori possibili nel codice). - Se k > numero di negativi (impossibile), niente riga. C8 — src/live/analista.py:207-211 testata Telegram - Se p["mov_giorno"] e' diverso da 0 (o assente/None: stesso trattamento di journal), la cifra e' p["trading_giorno"] con "(di cui $X movimenti)", non delta_equity grezzo. - L'etichetta "oggi" diventa "nel giorno": il cron gira alle 00:30 sul giorno chiuso. - Se trading_giorno e' None, resta delta_equity con l'etichetta nuova. C13 — taglio per Telegram su testo gia' HTML - src/live/revisione.py:261-264: tagliare `corpo` PRIMA di html.escape. - src/live/analista.py:239-241: tagliare il corpo testuale PRIMA di comporre i tag <b>/<i>. - Il limite resta quello di oggi; si mantiene il margine per tag e testata. - Il marcatore di taglio (es. "…") si aggiunge dopo, fuori dall'escape. C14 — scripts/live/telegram_daily.py:31-32,91-94 - GATES cablati: non inventare una fonte. Se src/live/monitor_health.py ha gia' i gate con le date (campo `gate` nella tabella), leggili da li'. Se no, lasciali cablati con un commento che li lega a CLAUDE.md §4 e dillo nel rapporto. - Formato: giorni > 0 -> "(-Ng)"; 0 -> "(oggi)"; < 0 -> "(scaduto da Ng)". Mai "(−-1g)". - L'header fisso "Perche' non opera": solo se il libro e' davvero fermo. Guarda come il messaggio sa se ci sono posizioni. Se non lo sa senza una lettura nuova, usa un header neutro, es. "Gate e stato", e dillo. TEST: per ognuno, funzioni pure con input finti. - C3: casi 2 neg + 1 pos, 3 neg, 1 neg + 2 pos (gia' acceso -> nessuna riga o come oggi). - C13: testo con "&" e "<b>" a cavallo del taglio -> HTML valido, entita' e tag chiusi. - C14: date passate, di oggi, future. Monkeypatch di notify; nessun Telegram, nessuna rete. Suite: `cd /home/adriano/lavoro/PG-u10 && /opt/docker/PythagorasGoal/.venv/bin/python -m pytest -q -p no:cacheprovider`. Baseline 1166 passed, 3 skipped. NON TOCCARE: src/live/revisione.py oltre il taglio (MAX_CHARS_VOCE lo cambia un'altra unita'); journal.py. COMMIT: uno per punto: "(#35 C3)", "(#35 C8)", "(#35 C13)", "(#35 C14)".
Author
Owner

ESITO: fatto sul ramo, non in produzione
RIF: gitea:Adriano/PythagorasGoal#35
FILE: commit 829ebc7 (A7) 604fde6 (B10) e82f2ee (B11) 8e75e9c (B12) 213dd12 13c136c (A9) 31ec767 (C3) d80323f (C8) 1229170 (C13) 3af6e1f (C14) su lavoro/goldrake (pushato, HEAD d34b0a8)
PROVA: /home/adriano/lavoro/PythagorasGoal pytest -q → 1220 passed, 3 skipped
MANCA: merge su main con ok di Adriano; poi issue chiudi --soluzione

ESITO: fatto sul ramo, non in produzione RIF: gitea:Adriano/PythagorasGoal#35 FILE: commit 829ebc7 (A7) 604fde6 (B10) e82f2ee (B11) 8e75e9c (B12) 213dd12 13c136c (A9) 31ec767 (C3) d80323f (C8) 1229170 (C13) 3af6e1f (C14) su lavoro/goldrake (pushato, HEAD d34b0a8) PROVA: /home/adriano/lavoro/PythagorasGoal pytest -q → 1220 passed, 3 skipped MANCA: merge su main con ok di Adriano; poi issue chiudi --soluzione
Author
Owner

Soluzione

Primo giro: B3 B4 C7 C9 C15. Secondo giro: A7 min_order_usd da config (829ebc7); A9 docstring (213dd12, 13c136c); B10 riconversione parziale con quota prima/dopo (604fde6); B11 ramo atteso morto rimosso da diagnose (e82f2ee); B12 pesi da book e titolo edge_watch (8e75e9c); C3 soglia di accensione su k flip (31ec767); C8 testata trading_giorno 'nel giorno' (d80323f); C13 taglio Telegram prima dell'escape (1229170); C14 gate da monitor_health e formato giorni (3af6e1f).
Su main d34b0a8 dal 27/09/2026 17:31Z, produzione aggiornata. Test 1220 passed.

**Soluzione** Primo giro: B3 B4 C7 C9 C15. Secondo giro: A7 min_order_usd da config (829ebc7); A9 docstring (213dd12, 13c136c); B10 riconversione parziale con quota prima/dopo (604fde6); B11 ramo atteso morto rimosso da diagnose (e82f2ee); B12 pesi da book e titolo edge_watch (8e75e9c); C3 soglia di accensione su k flip (31ec767); C8 testata trading_giorno 'nel giorno' (d80323f); C13 taglio Telegram prima dell'escape (1229170); C14 gate da monitor_health e formato giorni (3af6e1f). Su main d34b0a8 dal 27/09/2026 17:31Z, produzione aggiornata. Test 1220 passed.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Adriano/PythagorasGoal#35