Files
PythagorasGoal/Old/scripts/strategies/SH01_shape_ml.py
T
Adriano Dal Pastro 14522262e6 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>
2026-06-19 15:20:59 +00:00

110 lines
6.0 KiB
Python

"""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()