chore(reset): v2.0.0 — storico certificato Deribit mainnet, ripartenza pulita

Reset del progetto su fondamenta verificate dopo la scoperta che l'intera
libreria "validata OOS" era artefatto di feed contaminato (print fantasma del
feed Cerbero TESTNET + storico Binance/USDT).

- Storico ricostruito da Deribit MAINNET (ccxt pubblico, tokenless) e
  CERTIFICATO (certify_feed.py): BTC/ETH puliti su TUTTA la storia
  (mediana 2-6 bps vs Coinbase USD), integrita' OHLC + coerenza resample
  (maxΔ 0.00) + cross-venue OK. Alt esclusi (illiquidi/divergenti: LTC/DOGE
  50-82% barre flat; XRP/BNB non certificabili).
- Verdetto sul feed pulito: FADE / PAIRS / XS01 / TSM01 morti (ogni
  portafoglio Sharpe -2.3..-3.0, DD ~40%); solo SH01 e frammenti HONEST
  con segnale residuo, da ri-validare in isolamento.
- Cleanup "restart pulito": strategie, stack live (src/live, src/portfolio,
  runner/executor, yml, docker), ~100 script ricerca/gate, waste/games/
  portfolios, dati non certificati + cache e 60+ diari -> archiviati in Old/
  (preservati, non cancellati). Diario consolidato in un unico documento.
- Skeleton ricerca tenuto: Strategy ABC + indicatori + src/fractal +
  src/backtest/engine + load_data; tool dati certificati (rebuild_history,
  certify_feed, audit_feed, multi_source_check).
- Universo dati ATTIVO: solo BTC/ETH (5m/15m/1h); guardrail fisico
  (load_data su alt -> FileNotFoundError). Esecuzione DISABILITATA, conto flat.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Adriano Dal Pastro
2026-06-19 15:16:03 +00:00
parent 8401a280b9
commit 14522262e6
383 changed files with 1971 additions and 779 deletions
+129
View File
@@ -0,0 +1,129 @@
"""Netting delle chiusure market (v1.1.25): close_amount tenta il reduce-only e
riesegue il RESIDUO in market puro quando il netting di conto lo cappa/respinge
(audit 2026-06-11: 3 gambe pairs orfane + 1 close cappato). Il chiamante riceve
UN Fill combinato. Nessuna rete: _submit monkeypatchato."""
from src.live.execution import ExecutionClient, Fill
def _fill(inst, side, amount, filled, px, verified=True, state="filled", fee=0.05):
return Fill(inst, side, 0.0, amount, px if filled else None, 0.0, fee,
f"oid-{side}-{filled}", state, verified, filled_amount=filled)
def _client_with(submits, allowance=float("inf")):
"""ExecutionClient con _submit finto e guard del netting stubbato (il guard
reale legge conto+libri via HTTP/filesystem; qui si inietta il gap)."""
ec = ExecutionClient()
calls = []
def fake_submit(instrument, side, amount, notional, reduce_only, label=None,
order_type="market", price=None):
calls.append(dict(amount=amount, reduce_only=reduce_only, label=label))
return submits.pop(0)(instrument, side, amount)
ec._submit = fake_submit
ec._net_close_allowance = lambda *a, **k: allowance
return ec, calls
INST = "ETH_USDC-PERPETUAL"
def test_full_reduce_only_no_fallback():
# caso normale: il reduce-only filla tutto -> NESSUN secondo ordine
ec, calls = _client_with([
lambda i, s, a: _fill(i, s, a, filled=a, px=1700.0),
])
f = ec.close_amount(INST, "sell", 0.103, label="w1")
assert len(calls) == 1 and calls[0]["reduce_only"] is True
assert f.verified and abs(f.filled_amount - 0.103) < 1e-9
assert "netting" not in (f.notes or "")
def test_capped_reduce_only_nets_residual():
# reduce-only CAPPATO (filla 0.078 su 0.105) -> residuo 0.027 in market puro
ec, calls = _client_with([
lambda i, s, a: _fill(i, s, a, filled=0.078, px=1700.0),
lambda i, s, a: _fill(i, s, a, filled=a, px=1702.0),
])
f = ec.close_amount(INST, "sell", 0.105, label="w1")
assert len(calls) == 2
assert calls[0]["reduce_only"] is True and calls[1]["reduce_only"] is False
assert abs(calls[1]["amount"] - 0.027) < 1e-9
assert calls[1]["label"] == "w1|net"
assert f.verified and abs(f.filled_amount - 0.105) < 1e-9
# prezzo medio pesato: (0.078*1700 + 0.027*1702) / 0.105
exp_px = (0.078 * 1700.0 + 0.027 * 1702.0) / 0.105
assert abs(f.fill_price - exp_px) < 1e-6
assert abs(f.fee_usd - 0.10) < 1e-9 # fee sommate
assert "netting" in f.notes
def test_rejected_reduce_only_nets_full_amount():
# reduce-only RESPINTO (error, 0 fill) -> tutto l'amount in market puro
ec, calls = _client_with([
lambda i, s, a: _fill(i, s, a, filled=0.0, px=None, verified=False, state="error", fee=0.0),
lambda i, s, a: _fill(i, s, a, filled=a, px=1701.0),
])
f = ec.close_amount(INST, "buy", 0.027, label="pair")
assert len(calls) == 2 and abs(calls[1]["amount"] - 0.027) < 1e-9
assert f.verified and abs(f.filled_amount - 0.027) < 1e-9
assert f.fill_price == 1701.0
assert "netting" in f.notes
def test_net_leg_also_fails_reports_partial():
# anche il market puro fallisce -> Fill combinato NON verified, filled = solo r-o
ec, calls = _client_with([
lambda i, s, a: _fill(i, s, a, filled=0.05, px=1700.0),
lambda i, s, a: _fill(i, s, a, filled=0.0, px=None, verified=False, state="error", fee=0.0),
])
f = ec.close_amount(INST, "sell", 0.105, label="w1")
assert len(calls) == 2
assert not f.verified
assert abs(f.filled_amount - 0.05) < 1e-9 # solo il fillato vero nel ledger
def test_stale_state_guard_blocks_naked_order():
# quota gia' chiusa (DSL in outage / flatten manuale): reduce-only filla 0 e
# il gap conto-vs-libri e' 0 -> NESSUN ordine market nudo (code-review 2026-06-11)
ec, calls = _client_with([
lambda i, s, a: _fill(i, s, a, filled=0.0, px=None, verified=False, state="error", fee=0.0),
], allowance=0.0)
f = ec.close_amount(INST, "buy", 0.105, label="w1")
assert len(calls) == 1 # solo il reduce-only, niente fallback
assert not f.verified and f.filled_amount == 0.0
assert "netting NEGATO" in f.notes
def test_guard_unknown_fails_safe():
# guard non calcolabile (rete): FAIL-SAFE, niente ordine nudo
ec, calls = _client_with([
lambda i, s, a: _fill(i, s, a, filled=0.0, px=None, verified=False, state="error", fee=0.0),
], allowance=None)
f = ec.close_amount(INST, "buy", 0.105, label="w1")
assert len(calls) == 1
assert "non calcolabile" in f.notes
def test_guard_caps_residual_to_allowance():
# gap parziale: il residuo nudo e' cappato a quanto i libri giustificano
ec, calls = _client_with([
lambda i, s, a: _fill(i, s, a, filled=0.0, px=None, verified=False, state="error", fee=0.0),
lambda i, s, a: _fill(i, s, a, filled=a, px=1700.0),
], allowance=0.027)
f = ec.close_amount(INST, "sell", 0.105, label="w1")
assert len(calls) == 2
assert abs(calls[1]["amount"] - 0.027) < 1e-9
assert not f.verified # 0.027 < 0.105: chiusura parziale onesta
assert abs(f.filled_amount - 0.027) < 1e-9
def test_dust_residual_no_fallback():
# residuo da artefatto float (1e-17): NON deve diventare un lotto minimo nudo
ec, calls = _client_with([
lambda i, s, a: _fill(i, s, a, filled=a - 1e-17, px=1700.0),
])
f = ec.close_amount(INST, "sell", 0.105, label="w1")
assert len(calls) == 1
assert f.verified