14522262e6
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>
74 lines
2.9 KiB
Python
74 lines
2.9 KiB
Python
"""EXIT-07 — TP dinamico che DECADE col tempo (verso breakeven).
|
|
|
|
PRIOR (vincolante, ieri SCARTATO un ladder 80/20): il TP delle fade sta alla
|
|
MEDIA, e li' il movimento e' esaurito -> il prezzo spesso NON arriva al TP e il
|
|
trade muore a max_bars (close) o sullo SL. Idea di questa famiglia: invece di
|
|
tenere il TP fisso al target ambizioso (la media), farlo DECADERE col passare
|
|
delle barre verso un target piu' modesto (breakeven che copre le fee, o meta'
|
|
strada). Cosi' un trade che s'e' avvicinato ma non ha toccato il TP pieno puo'
|
|
essere chiuso in profitto/pareggio prima di scadere a max_bars potenzialmente
|
|
in perdita. SL FISSO (sl0) invariato. horizon = max_bars invariato.
|
|
|
|
TP attivo nel bar j:
|
|
frac(j) = clamp( ((j - i) / mb) * speed , 0, 1 )
|
|
tp(j) = tp0 + frac(j) * (target_fin - tp0)
|
|
- frac dipende SOLO da j (indice di tempo) e da costanti note all'entrata
|
|
(i, mb, speed) -> NESSUN dato > j-1 -> anti-look-ahead OK per costruzione.
|
|
- long (d=+1): tp0 > entry; target_fin <= tp0 -> il TP SCENDE verso entry.
|
|
- short (d=-1): tp0 < entry; target_fin >= tp0 -> il TP SALE verso entry.
|
|
- speed>1: il TP raggiunge il target finale prima della fine (clamp a 1).
|
|
|
|
target_fin (param "target"):
|
|
- "breakeven": entry*(1 + d*0.003) -> copre 0.3% (~ fee 0.10%RT + margine).
|
|
Per long sta sopra entry, per short sotto: chiudere li' NON e' in perdita.
|
|
- "halfway" : (entry + tp0)/2 -> meta' strada fra entry e il TP pieno.
|
|
|
|
GRID: speed in {0.5, 1.0, 1.5} x target in {breakeven, halfway} (6 celle).
|
|
"""
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
|
|
from exit_lab import ExitPolicy, evaluate # noqa: E402
|
|
|
|
|
|
class TpDecay(ExitPolicy):
|
|
name = "tp_decay"
|
|
|
|
def __init__(self, ctx, i, d, entry, tp0, sl0, mb, **params):
|
|
super().__init__(ctx, i, d, entry, tp0, sl0, mb, **params)
|
|
self.speed = float(params.get("speed", 1.0))
|
|
target = str(params.get("target", "breakeven"))
|
|
if target == "breakeven":
|
|
self.target_fin = entry * (1.0 + d * 0.003)
|
|
elif target == "halfway":
|
|
self.target_fin = 0.5 * (entry + tp0)
|
|
else:
|
|
raise ValueError(f"target sconosciuto: {target}")
|
|
# mb puo' essere 0 in teoria; protezione
|
|
self.mb_eff = max(int(mb), 1)
|
|
|
|
def levels(self, j: int):
|
|
# frac dipende SOLO dal tempo (j - i), mb, speed: costanti note all'entrata
|
|
frac = ((j - self.i) / self.mb_eff) * self.speed
|
|
if frac < 0.0:
|
|
frac = 0.0
|
|
elif frac > 1.0:
|
|
frac = 1.0
|
|
tp = self.tp0 + frac * (self.target_fin - self.tp0)
|
|
return tp, self.sl0, 1.0
|
|
|
|
|
|
GRID = [
|
|
{"speed": 0.5, "target": "breakeven"},
|
|
{"speed": 1.0, "target": "breakeven"},
|
|
{"speed": 1.5, "target": "breakeven"},
|
|
{"speed": 0.5, "target": "halfway"},
|
|
{"speed": 1.0, "target": "halfway"},
|
|
{"speed": 1.5, "target": "halfway"},
|
|
]
|
|
|
|
|
|
if __name__ == "__main__":
|
|
evaluate(TpDecay, GRID)
|