usde_convert: ordini limit GTC mai cancellati, cuscino_watch dopo 6h rimanda il delta pieno #26
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 B1 [bug]
FILE: pg:scripts/live/usde_convert.py:249-252,277-278
COSA: ordine limit spot USDE_USDC senza time_in_force e senza cancel: un ordine accettato e non (o parzialmente) fillato resta APERTO sul book, e nessuno lo vede.
SCENARIO: SCOPERTO con bid 0.9985 (indice 0.998 > depeg_warn 0.99, banda PX_MIN 0.995 ok) -> px_ord = max(bid-5tick, CAP_SELL 0.999) = 0.9990, non incrocia -> Deribit lo accetta GTC (default) -> "accettato ma non fillato — mi fermo", rc=1. L'ordine resta vivo; 6h dopo cuscino_watch rilegge i saldi (l'USDE impegnato e' ancora nell'equity) e manda un'ALTRA vendita per lo stesso delta: se si fillano entrambi la quota scende sotto 0.64 di un intero delta (possibile ECCEDENTE -> riacquisto, un giro di spread). Stesso caso lato buy con ask > CAP_BUY 1.0010. Parziale: ogni iterazione con fill parziale lascia il residuo aperto e ricalcola il delta pieno dai saldi.
PROVA: VERIFICATO:
uv run pythonoffline su usde_convert.piano(1300,3280,0.998,0.64,...,bid=0.9985) -> side sell, amount 346, px_ordine 0.999, ok=True (non incrocia il bid 0.9985); piano(...,ask=1.0012) -> buy @1.001 ok=True. Lettura — payload place_order senza time_in_force/post_only; nessuna chiamata cancel/get_open_orders su USDE_USDC in usde_convert.py ne' cuscino_watch.py (DeribitRead.open_orders esiste ma mappa solo gli strumenti di _CONTRACT). PRESUNTO: default GTC del gateway (non letto il codice di cerbero-mcp).PROPOSTA: passare "time_in_force": "immediate_or_cancel" (o fill_or_kill) nel place_order; in alternativa, dopo un fill < amt, cancellare l'ordine per order_id prima di proseguire/uscire.
Verifica fable B1 VERDETTO: CONFERMATO
GRAVITA': alto
PERCHE': cerbero-mcp
src/cerbero_mcp/exchanges/deribit/tools.py:160-168(PlaceOrderReq: instrument_name, side, amount, type, price, reduce_only, post_only, label, leverage — NESSUNtime_in_force) eclient.py:1637-1670(place_ordernon mandatime_in_forceaprivate/buy|sell) -> Deribit applica il defaultgood_til_cancelled. In PGscripts/live/usde_convert.py:249-252payload senza tif/post_only; unicocancel_orderdel repo e'src/live/execution.py:193(bracket dei perp), mai chiamato su USDE_USDC;usde_convert.py:277-278sufilled<=0esce con l'ordine vivo, e su fill parziale prosegue ricalcolando il delta dai saldi (leggi_statoleggeequity, che include l'USDE impegnato).cuscino_watch.py:161-165: da SCOPERTO riprova dopoRIPRISTINO_MIN_ORE6h col delta pieno. Il gateway espone/tools/cancel_order(routers/deribit.py:263) ma PG non lo usa qui. Gateway non modificato dalla PRESUNZIONE del revisore: confermata.CORREZIONE: la proposta «passare time_in_force nel place_order» NON FUNZIONA cosi' com'e':
PlaceOrderReqe' un BaseModel pydantic senzaextra="allow"(solo i modelli alle righe 28 e 43 lo hanno) -> il campo verrebbe IGNORATO in silenzio e l'ordine resterebbe GTC. Due strade: (a) aggiungeretime_in_force: str | NoneaPlaceOrderReq+client.place_orderin cerbero-mcp e poi passarlo da PG; (b) solo in PG, senza toccare il gateway: dopo ogni ordine confilled < amtchiamare/mcp-deribit/tools/cancel_orderconorder["order_id"](e a inizio diusde_convert --eseguicancellare gli ordini aperti su USDE_USDC viaget_open_orders, cheDeribitRead.open_ordersgia' interroga ma solo per gli strumenti di_CONTRACT). (b) e' verificabile con un test sul mock del client; (a) e' la soluzione pulita ma tocca un secondo repo.ANALISI (passo 1, Opus) — unita' U3, ramo lavoro/goldrake-u3, repo gitea:Adriano/PythagorasGoal
RIF: #26 (B1), #29 (B2, B8), #31 (B7), #35 (solo B3, B4)
FILE: scripts/live/usde_convert.py, scripts/live/usde_watch.py, scripts/live/fee_watch.py, src/live/venue_watch.py, scripts/live/venue_watch.py, tests/
a) funzione
cancella_residui(c) -> list[str]: legge gli ordini aperti sullo spot U.SPOT (USDE_USDC) e cancella SOLO quelli con label che inizia per "usde-quota-". Per sapere come chiedere gli ordini aperti di uno spot leggi (SOLA LETTURA) /opt/docker/cerbero-mcp/src/cerbero_mcp/exchanges/deribit/tools.py e client.py (get_open_orders: parametri accettati; cancel_order: {"order_id"}). Se la lettura fallisce -> solleva (non si ordina al buio).b) in main() con --esegui: chiamare cancella_residui PRIMA del ciclo (stampare quanti) e, nel ciclo, dopo ogni ordine con filled < amt cancellare quell'order_id (
c._post("/mcp-deribit/tools/cancel_order", {"order_id": ...})), registrarlo nel record (cancellato: true/errore). Se la cancel fallisce: stampa, registra e FERMA il ciclo (break) — mai un secondo ordine con un residuo vivo.c) il record finale e l'exit code non cambiano significato.
allertati= condizioni il cui invio e' riuscito;nuove = att_now - {c in att_prev se c in prev.get("allertati", att_prev)}— compatibilita': un record vecchio senzaallertativale come tutto allertato. fee_watch: save_state solo se l'invio (quando serviva) e' riuscito.TEST (tests/test_usde_u3.py ecc., client finto, nessuna rete, time.sleep patchato):
Suite completa:
cd <worktree> && /opt/docker/PythagorasGoal/.venv/bin/python -m pytest -q -p no:cacheprovider(baseline 1098 passed, 3 skipped).NON TOCCARE: src/live/usde.py (formula del cuscino: e' #28, altra unita'), cuscino_watch.py (salvo leggerlo), config/live.json, /opt/docker/cerbero-mcp (sola lettura), /opt/docker/PythagorasGoal. Nessuna rete, nessun ordine, nessun Telegram (notify va mockato nei test).
ESITO: fatto sul ramo, non in produzione
RIF: gitea:Adriano/PythagorasGoal#26
COSA: correzione su lavoro/goldrake (pushato), analisi Opus, codice Sonnet, controllo finale Opus
FILE: commit
f0193f07234625PROVA: /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
scripts/live/usde_convert.py: cancella_residui all'avvio (USDC+USDE, solo label usde-quota-), cancel dell'ordine parziale nel ciclo, stop se il cancel fallisce.
COMMIT:
f0193f07234625, su main dal 27/09/2026 (merge con ok di Adriano). Produzione aggiornata.