Files
PythagorasGoal/scripts/waste/SQ02_squeeze_antifake_vol.py
T
Adriano Dal Pastro 9879b46688 refactor(strategie): tieni solo MR01 mean-reversion, squeeze -> waste
L'analisi out-of-sample fee-aware ha dimostrato che l'intera famiglia
squeeze-breakout (SQ01-04, MT01, ML01, AD01, CM01, PD01) non ha edge:
le accuratezze storiche 76-82% erano un artefatto di look-ahead (ingresso
a close[i-1] con direzione decisa da close[i]). Sotto ingresso onesto a
close[i] e fee reali tutte perdono, anche a fee zero.

- nuova MR01_bollinger_fade (mean-reversion): edge netto validato OOS,
  robusto su griglia parametri e fino a 0.20% fee RT. BTC 1h n50 k2.5: +201% OOS, DD 15%
- 9 strategie squeeze spostate in scripts/waste/
- strategy_loader + strategies.yml: solo MR01 (BTC/ETH 1h)
- signal_engine.train: validazione OOS (accuratezza test + signal precision)
- scripts/analysis/strategy_research.py: harness di ricerca fee-aware

NOTA: lo StrategyWorker va aggiornato per usare gli exit TP/SL passati in
metadata prima di tradare MR01 dal vivo (ora esce solo a hold_bars/stop fisso).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 20:22:11 +00:00

88 lines
2.7 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""SQ02 — Squeeze Breakout + Anti-Fakeout + Volume Confirmation.
Migliora SQ01 con due filtri:
1. Anti-fakeout: scarta breakout dove la candela ritraccia >60% del range
2. Volume confirm: volume al breakout deve essere >1.3× la media durante squeeze
IN:
- OHLCV DataFrame
- Parametri: bb_window (14), sq_threshold (0.8), retrace_limit (0.6),
vol_multiplier (1.3)
OUT:
- Lista di Signal filtrati
- BacktestResult
Risultati tipici:
BTC 15m: 79.7% acc, 1250 trades, DD 6.5%, €5.23/day — SOLIDO 9/9 anni
ETH 15m: 78.6% acc, 942 trades, DD 3.4%, €4.33/day
BTC 1h: 78.0% acc, 473 trades, DD 3.5%, Sharpe 6.57
"""
from __future__ import annotations
import sys
sys.path.insert(0, ".")
import numpy as np
import pandas as pd
from src.strategies.base import Strategy, Signal
from src.strategies.indicators import keltner_ratio, detect_squeezes
class SqueezeAntifakeVol(Strategy):
name = "SQ02_antifake_vol"
description = "Squeeze + antifakeout + volume confirmation"
default_assets = ["BTC", "ETH"]
default_timeframes = ["15m", "1h"]
def generate_signals(self, df: pd.DataFrame, ts: pd.DatetimeIndex,
**params) -> list[Signal]:
c = df["close"].values
h = df["high"].values
l = df["low"].values
v = df["volume"].values
n = len(c)
bb_w = params.get("bb_window", 14)
sq_thr = params.get("sq_threshold", 0.8)
retrace_limit = params.get("retrace_limit", 0.6)
vol_mult = params.get("vol_multiplier", 1.3)
kcr = keltner_ratio(c, h, l, bb_w)
events = detect_squeezes(c, h, l, kcr, sq_thr)
signals = []
for ev in events:
i = ev["idx"]
if i < 1 or i >= n:
continue
first_ret = (c[i] - c[i - 1]) / c[i - 1] if c[i - 1] > 0 else 0
if abs(first_ret) < 0.001:
continue
br = h[i] - l[i]
if br > 0:
if c[i] > c[i - 1]:
if (h[i] - c[i]) / br > retrace_limit:
continue
else:
if (c[i] - l[i]) / br > retrace_limit:
continue
avg_v = np.mean(v[ev["sq_start"]:i])
if avg_v > 0 and v[i] <= avg_v * vol_mult:
continue
signals.append(Signal(
idx=i,
direction=1 if first_ret > 0 else -1,
entry_price=c[i - 1],
metadata={"dur": ev["dur"], "vol_ratio": v[i] / avg_v if avg_v > 0 else 0},
))
return signals
if __name__ == "__main__":
strategy = SqueezeAntifakeVol()
strategy.report()