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:
@@ -0,0 +1,109 @@
|
||||
"""SH01 — Shape-ML: direzione predetta dalla FORMA del segnale (ML walk-forward).
|
||||
|
||||
FAMIGLIA NUOVA, distinta da tutto l'esistente. Non e' una regola fissa su bande/canali
|
||||
(fade) ne' momentum/rotazione (honest) ne' spread (pairs): una LogisticRegression legge
|
||||
la MORFOLOGIA della finestra recente (body/shadow delle candele, rendimenti, pendenza,
|
||||
curvatura, posizione di max/min, RSI, estensione) e predice il segno del rendimento a H
|
||||
barre. Entra a close[i] solo se la probabilita' supera una soglia (selettivita').
|
||||
|
||||
E' l'UNICO edge sopravvissuto alla ricerca sui pattern-di-forma (2026-05-29): le altre
|
||||
4 famiglie testate con agenti paralleli su harness onesto sono RUMORE (analog kNN forma
|
||||
grezza, encoding candele UP/DOWN/DOJI, DTW+template geometrici, PIP/pivot) — confermano
|
||||
la dominanza mean-reversion. Vedi scripts/analysis/shape_*_research.py e docs/diary.
|
||||
|
||||
Logica (engine onesto verificato in scripts/analysis/shape_ml_research.py):
|
||||
feature di forma X[i] da o/h/l/c[i-W+1..i] (causali: solo dati fino a close[i])
|
||||
walk-forward a blocchi: scaler+modello fittati SOLO sul passato con esito noto
|
||||
(finestre e con e+H <= inizio_blocco-1), poi predicono il blocco corrente
|
||||
proba(classe) >= thresh -> entra a close[i] nella direzione predetta, exit a H barre
|
||||
fee 0.10% RT (single-leg). NESSUN look-ahead (check espliciti: perturbare il futuro
|
||||
non cambia ne' le feature a i ne' le predizioni fino a i).
|
||||
|
||||
VALIDAZIONE DURA (netto fee, leva 3x, pos 0.15, OOS = ultimo 30%, config W24 H12 th0.58,
|
||||
scripts/analysis/shape_ml_validate.py):
|
||||
- MULTI-ASSET expanding: robusti BTC, ETH, ADA; scartati LTC/SOL/XRP.
|
||||
BTC : FULL +219% / OOS +42% / Sharpe 2.72 / DD 23% / 8-9 anni+ / accOOS 56% (regge fee 0.2%: +60/+26)
|
||||
ETH : FULL +80% / OOS +144% / Sharpe 1.21 / DD 61% / 6/9 anni+ / accOOS 55% (piu' volatile -> secondario)
|
||||
ADA : FULL +707% / OOS +57% / Sharpe 3.22 / DD 39% / 7/8 anni+ (robusto solo expanding)
|
||||
- WALK-FORWARD ROLLING (train fisso 2 anni): regge solo BTC (FULL +166% / OOS +96% / Sharpe 2.05).
|
||||
-> l'edge si appoggia in parte alla memoria lunga: BTC e' il piu' solido.
|
||||
- STRESS leva 2x + slippage doppio (fee 0.20% RT): BTC OK (FULL +40% / OOS +17% / Sharpe 1.24),
|
||||
ETH marginale (FULL +7% / OOS +73% / Sharpe 0.37).
|
||||
- GRIGLIA (W,H,thresh) su BTC: 5/27 celle robuste a fee 0.2%, su una CRESTA stretta
|
||||
(W24, H8-12), non altopiano largo -> rischio overfit moderato. Per prudenza si sceglie
|
||||
la config robusta sul PIU' ALTO numero di test (W24 H12 th0.58), non il PnL massimo
|
||||
(W24 H8 rende di piu' ma accOOS ~49% = piu' drift che segnale).
|
||||
|
||||
USO CONSIGLIATO: NON motore standalone (per-asset e' troppo stretto/fragile fuori da BTC),
|
||||
ma DIVERSIFICATORE di portafoglio. Corr daily col MASTER +0.08 (quasi scorrelato).
|
||||
Aggiungere lo sleeve shape (BTC+ETH) al MASTER migliora l'OOS: Sharpe 4.33->5.10,
|
||||
DD 4.7%->4.2% (scripts/analysis/shape_ml_validate.py sez. 5).
|
||||
|
||||
LIVE: richiede un worker capace di RIALLENARE periodicamente il modello (come il legacy
|
||||
signal_engine ML, non lo StrategyWorker a regola fissa). Da wirare prima del paper live.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
import pandas as pd
|
||||
|
||||
PROJECT_ROOT = Path(__file__).resolve().parents[2]
|
||||
sys.path.insert(0, str(PROJECT_ROOT))
|
||||
|
||||
from src.strategies.base import Strategy, Signal # noqa: E402
|
||||
from scripts.analysis.explore_lab import get_df, evaluate, robust # noqa: E402
|
||||
from scripts.analysis.shape_ml_research import ml_wf_entries # noqa: E402
|
||||
|
||||
# Config robusta scelta (cresta W24 H8-12; H12 th0.58 = la piu' robusta sui test).
|
||||
CONFIG = dict(W=24, H=12, model="logit", thresh=0.58)
|
||||
|
||||
# Asset con edge robusto. BTC primario (regge ogni stress); ETH secondario (diversificatore
|
||||
# piu' volatile). ADA robusto solo expanding -> tenuto fuori dal set live conservativo.
|
||||
ASSETS = ["BTC", "ETH"]
|
||||
|
||||
|
||||
class ShapeMLStrategy(Strategy):
|
||||
name = "SH01_shape_ml"
|
||||
description = "Direzione predetta dalla forma del segnale (LogisticRegression walk-forward), exit a H barre"
|
||||
default_assets = ASSETS
|
||||
default_timeframes = ["1h"]
|
||||
fee_rt = 0.001
|
||||
leverage = 3.0
|
||||
position_size = 0.15
|
||||
|
||||
def generate_signals(self, df: pd.DataFrame, ts: pd.DatetimeIndex, **params) -> list[Signal]:
|
||||
cfg = {**CONFIG, **{k: params[k] for k in ("W", "H", "model", "thresh") if k in params}}
|
||||
# last_block_only (live, 2026-06-07): il runner passa la storia FULL (parquet
|
||||
# bootstrap + feed) e qui si fitta/predice solo l'ultimo blocco del walk-forward
|
||||
# (segnali identici al WF completo per costruzione, 1 fit invece di ~140).
|
||||
# La ri-validazione punto-10 ha mostrato che il regime corto (train 365g) NON
|
||||
# e' robusto (BTC negativo a fee 2x, trade-rate 22% vs 10%): l'edge richiede
|
||||
# il training expanding full-history. Vedi sh01_trainwindow_validate.py.
|
||||
ents = ml_wf_entries(df, W=cfg["W"], H=cfg["H"], model=cfg["model"], thresh=cfg["thresh"],
|
||||
last_block_only=bool(params.get("last_block_only")))
|
||||
c = df["close"].values
|
||||
out: list[Signal] = []
|
||||
for e in ents:
|
||||
out.append(Signal(idx=e["i"], direction=e["d"], entry_price=float(c[e["i"]]),
|
||||
metadata={"max_bars": e["max_bars"]}))
|
||||
return out
|
||||
|
||||
|
||||
def run():
|
||||
print("=" * 96)
|
||||
print(" SH01 — Shape-ML | direzione dalla FORMA (LogisticRegression walk-forward) | netto fee 0.10% RT, leva 3x")
|
||||
print("=" * 96)
|
||||
print(f" config: {CONFIG} (W=finestra forma, H=orizzonte/exit, thresh=soglia proba)")
|
||||
for a in ASSETS:
|
||||
df = get_df(a, "1h")
|
||||
ents = ml_wf_entries(df, **CONFIG)
|
||||
res = evaluate(f"{a}", ents, df)
|
||||
print(f" ^ {'ROBUSTO (FULL+OOS+, regge fee 0.2%, ~tutti anni+)' if robust(res) else 'edge presente ma con anni negativi (diversificatore)'}")
|
||||
print("\n Uso: diversificatore di portafoglio (corr ~0.08 col MASTER), non motore standalone.")
|
||||
print(" Live: serve worker con retraining periodico del modello (vedi docstring).")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
run()
|
||||
Reference in New Issue
Block a user