MAX_AMOUNT per ordine (0,01 BTC / 0,25 ETH) tarato sul conto da $600: blocca ingressi e flip col conto a $4.583 #18
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Revisione 2026-09-27 (goldrake): rilievo Opus 5.5, verifica avversariale fable. Sola lettura, nessun codice toccato.
Rilievo A1 [bug-critico]
FILE: PG:src/live/execution.py:24 (MAX_AMOUNT) + :64-67 (_submit)
COSA: tetto hard per ORDINE d'apertura tarato su un conto da ~$600 (BTC 0.01 / ETH 0.25 = ~$843 / ~$673 ai prezzi del 27/09) su un conto oggi da $4.583: morde prima del cap di config e fa fallire in eccezione ogni ingresso da flat sopra quella taglia.
SCENARIO: equity $4.583, ETH 2.694. TP01 rientra da flat su ETH con tp_frac 0,44 (valore di oggi) -> net = 0,545830,750,44 = $756 -> 0,2807 ETH > 0,25 -> GuardrailError dentro rebalance_signed -> catturata dall'isolamento per asset in book_execute.py:311 -> "asset ETH fallito" ogni ora, ingresso MAI eseguito finche' il segnale resta. Stesso per BTC con tp_frac >= 0,49 ($859 > 0,0184.324). SKH01 da solo ($573 ETH = 0,2126) usa gia' l'85% del tetto: un -15% di ETH o +18% di equity e anche gli ingressi SKH falliscono. Mentre fallisce, ensure_disaster_sl (stesso try, riga 292) non gira per quell'asset.
PROVA: VERIFICATO: data/live/book_executions.jsonl -> ordini SKH ETH 0,2108/0,2117/0,2146/0,2139 ETH (11-23/09), BTC 0,0068-0,0073; posizioni attuali BTC $810 (0,0096 BTC), ETH $756 (0,2807 ETH) raggiunte a gradini (nessun ingresso da flat dopo il versamento del 04/09, per questo non e' ancora scattato); equity_seen.json 4583,05; grep MAX_AMOUNT: citato solo in execution.py e microtest.py, nessuna menzione in CLAUDE.md/config. Stesso valore in TradingBook/src/live/execution.py (diff vuoto), ma l'ombra non invia: il confronto ombra/vivo NON vedra' la divergenza come difetto dell'ombra.
PROPOSTA: derivare il tetto anti-fat-finger dal cap di config (es. amount_max = 1.1 * cap_per_asset * scala / mark, passato da book_execute) oppure spezzare l'apertura in tranche <= MAX_AMOUNT; in ogni caso un test che fallisca se n_assetequityfrac/mark > MAX_AMOUNT.
Verifica fable A1 VERDETTO: CONFERMATO-RIDIMENSIONATO
GRAVITA': alto
PERCHE': execution.py:24 MAX_AMOUNT {BTC 0.01, ETH 0.25} e :64-67 (GuardrailError se amount > cap su ogni apertura, incluse
book-opendi rebalance_signed :180-181). Aritmetica verificata: equity_seen 4583, ETH 2694 -> ingresso TP01 da flat con tp 0,44 = $756 = 0,2807 ETH > 0,25. Caso ancora piu' concreto e gia' possibile OGGI: flip SKH short->long (delta = 2 x 0,5 x 4583 x 0,25 = $1.146 -> 0,0136 BTC > 0,01 / 0,425 ETH > 0,25) o salto di tp_frac >= 0,3 in un giorno (misurato nel log: max delta giornaliero tp BTC 0,299, ETH 0,294 — al limite). Nel log 2296 giri, transizioni SKH viste solo via flat (+0->+1, -1->+0), mai -1->+1 diretto; tp_frac 0.0 registrato (18/07, 05/08, 19/08). MAX_AMOUNT non e' citato in CLAUDE.md/docs (grep -> 0). RIDIMENSIONATO perche' l'esito e' un ORDINE NON INVIATO + allerta "asset fallito" ogni ora (nessun ordine sbagliato, nessuna perdita diretta), ma nel flip la close() e' gia' eseguita (fill reale) e la riapertura fallisce per sempre: l'asset resta flat contro il segnale. Nella stessa try (book_execute.py:301-311) salta anche ensure_disaster_sl di quell'asset.CORREZIONE: ok. Preferire il tetto derivato da config (amount_max = 1,1 x cap_per_asset x scala / mark, passato da book_execute) alle tranche: le tranche moltiplicano gli ordini market. Aggiungere il test "n_asset x equity x frac / mark > MAX_AMOUNT deve passare".
ANALISI (passo 1, Opus) — unita' U1, ramo lavoro/goldrake-u1, repo gitea:Adriano/PythagorasGoal
RIF: #17 (D1), #18 (A1), #24 (A5)
FILE: src/live/deribit.py, src/live/execution.py, tests/ (nuovo tests/test_execution_u1.py)
sizein abs() edirectiona parte.Nuova regola: s = float(size or size_currency or 0); dir = str(p.get("direction","")).lower();
dir in ("sell","short") -> -abs(s); dir in ("buy","long") -> abs(s); altrimenti (assente/"zero") -> s cosi' com'e' (compatibile con un gateway che un giorno mandi il segno).
Cercare con grep in src/ e scripts/live/ (escluso scripts/research, Old) ogni altro lettore di
positions(o di["size"]/.get("size")di una posizione e applicare la stessa regola SOLO se legge posizioni perp del libro; elencare nel rapporto quelli trovati.Verifica a valle: close() e ensure_disaster_sl() decidono lato e stop da
pos > 0: con il segno giusto uno short produce close BUY reduce_only e stop SOPRA il mark (disaster_stop_price long=False). Test che lo provano passando per positions() mockato (NON mockare position_usd).self._open_cap: dict[str, float] = {}; metodoset_open_cap(instrument, usd_cap, mark)-> amount_max = 1.10 * usd_cap / mark (usd_cap>0, mark>0 altrimenti ValueError)._submitsul ramo non reduce_only usaself._open_cap.get(instrument, MAX_AMOUNT[instrument]).trader.set_open_cap(inst, r["cap_per_asset"] * r["scala"], mark)prima di rebalance_signed). Scrivi nel rapporto la firma esatta.ensure_disaster_sl: la lettura di posizione+open_orders in try; su eccezione ritorna {"state": "unknown", "notes": ": "} SENZA cancellare ne' piazzare. Aggiornare il docstring (stati possibili).
Chiamanti di open_orders: grep; shadow.shadow_report lo chiama gia' dentro try/except (ok, non toccare shadow.py: e' di U2).
TEST (tutti in tests/test_execution_u1.py, client finto che sostituisce _post/positions, nessuna rete):
Suite completa:
cd <worktree> && /opt/docker/PythagorasGoal/.venv/bin/python -m pytest -q -p no:cacheprovider-> baseline 1098 passed, 3 skipped. Nessun test esistente deve rompersi; se uno esistente blinda il comportamento vecchio, aggiornalo e dillo.NON TOCCARE: scripts/live/book_execute.py, src/live/shadow.py, src/live/book.py (U2); config/live.json; tutto sotto /opt/docker/PythagorasGoal (produzione); nessuna chiamata di rete, nessun ordine.
ESITO: fatto sul ramo, non in produzione
RIF: gitea:Adriano/PythagorasGoal#18
COSA: correzione su lavoro/goldrake (pushato), analisi Opus, codice Sonnet, controllo finale Opus
FILE: commit
f79fb54841d4c7PROVA: /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
Soluzione
src/live/execution.py: set_open_cap(instrument, capscala, mark) -> tetto 1,10cap/mark per le aperture; book_execute lo chiama prima di rebalance_signed. MAX_AMOUNT resta solo default del micro-test.
COMMIT:
f79fb54841d4c7, su main dal 27/09/2026 (merge con ok di Adriano). Produzione aggiornata.