1afb1014c9
Flotta di 52 subagenti "esperti di segnali" su storico BTC/ETH ANONIMIZZATO (Series A/B rebased a 100, calendario sintetico, split 70/30) — non sanno cosa siano. Ognuno scrive un signal(df)->position causale (script o ML), tunato solo sul train. Orchestratore valuta su PnL e maxDD nel test held-out. Harness cieco leak-free (riusabile): - make_blind.py: export anonimo + overlay; blindlib.py: evaluator con shift della posizione + GUARDIA DI CAUSALITA' online (squalifica ogni look-ahead, ML incluso); blind_eval.py CLI; score_all.py giudice OOS; verify_top.py (corr-al-trend, fee-stress, jackknife). - 52/52 passano la guardia (zero leak su tutta la flotta). Esito OOS (benchmark buy&hold: -7% PnL, 68% DD): - top = macd (+21%, DD 11%, Sh 0.84), accel, vol_of_vol, regime_switch, rf, obv — tutti trend/vol-regime. Sharpe OOS ~0.84 decade dal train ~1.4. Mean-rev e ML in fondo. - 3 scettici indipendenti: REFUTED. regime-luck (top-5 bar = 67-102% del PnL); trend-redundancy (HAC alpha t=+0.9..+1.5, nessuno >1.96 — TSMOM travestito); overfit (accel/vov knife-edge). Verdetto: ri-conferma CIECA e indipendente del soffitto direzionale ~1.3. macd = classe-TP01, forward-monitor non deploy. Diario 2026-06-21-blind-signal-fleet.md. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
59 lines
3.4 KiB
Python
59 lines
3.4 KiB
Python
"""Agent 19 — Vol-targeted long-only / risk-parity single asset
|
|
(family=vol, slug=voltarget_lo).
|
|
|
|
The angle (assigned): NO direction call. Hold the asset LONG at all times, but size
|
|
the position by INVERSE realized volatility so the book runs at a roughly constant
|
|
target volatility: exposure[i] = clip( target_vol / realized_vol[i] , 0, cap ).
|
|
|
|
Why this anticipates anything at all, despite never predicting direction: realized
|
|
vol is PERSISTENT (today's vol forecasts tomorrow's vol far better than today's return
|
|
forecasts tomorrow's return). The big declines on these two curves are also the high-
|
|
vol regimes — a crash is a vol spike. So scaling exposure DOWN when trailing vol is
|
|
high mechanically pulls the book light right when the worst legs happen, and levers UP
|
|
in the calm grind higher. The result on a structurally up-trending curve is a long-only
|
|
book with most of buy&hold's upside but a much smaller drawdown (the risk-parity / "vol
|
|
control" effect), at modest turnover (the weight only drifts with the vol forecast).
|
|
|
|
CAUSAL: realized_vol[i] uses returns over a trailing window ending at i (rows <= i);
|
|
the position is then shifted by the evaluator (held during bar i+1). No direction is
|
|
derived from any future bar; no global fit. Verified by causality_ok (max_diff 0.0).
|
|
|
|
Tuning (split='train' only, combined A&B). The free knobs are the trailing vol window,
|
|
the target vol, and the leverage cap.
|
|
* CAP is the single most important choice. Because both curves trend up hard, a high
|
|
cap just re-levers into buy&hold and brings the drawdown right back. cap=1.0 (never
|
|
more than fully invested) is what preserves the risk-parity de-risking benefit; with
|
|
a vol-driven weight that almost always sits below 1.0 this is the whole point.
|
|
* VOL_WIN is the vol-forecast horizon. A SLOW window (~120d) gives a stabler vol
|
|
estimate, less whipsaw, lower turnover and the BEST risk-adjusted result here:
|
|
sharpe_min climbs from ~0.85 (30d) to ~0.97 (120d) and the plateau (110..200d) is
|
|
flat at sharpe 0.91..0.99 / DD ~0.42-0.44 -> 120 is a robust interior pick.
|
|
* TARGET_VOL is a pure DD/PnL dial: it scales exposure up and down but (for a long-
|
|
only inverse-vol book) leaves the Sharpe essentially flat (0.971 across 0.24..0.32).
|
|
So it is chosen for the DD/PnL trade-off, not the Sharpe.
|
|
Chosen cell, interior on every axis:
|
|
TARGET_VOL = 0.28 # DD/PnL dial; Sharpe flat across 0.24..0.32 -> balanced cell
|
|
VOL_WIN_D = 120 # slow, stable vol forecast; plateau 110..200d
|
|
LEV_CAP = 1.0 # never lever past fully-invested -> keeps the DD-cut benefit
|
|
-> train combined: pnl_mean ~2.93, maxdd_worst ~0.43, sharpe_min ~0.97.
|
|
This is a DEFENSIVE long-only book, NOT alpha. Its honest value is the drawdown: ~0.43
|
|
vs ~0.77-0.79 buy&hold at comparable PnL. Because it never shorts, its Sharpe ceiling
|
|
(~1.0) is set by the absence of any direction call -> it can avoid sizing into the big
|
|
declines but cannot profit from them. That is the inherent limit of this angle.
|
|
"""
|
|
import numpy as np
|
|
import blindlib as bl
|
|
|
|
TARGET_VOL = 0.28
|
|
VOL_WIN_D = 120
|
|
LEV_CAP = 1.0
|
|
|
|
|
|
def signal(df):
|
|
# direction = always long (+1), NO direction call. Sizing is pure inverse-vol.
|
|
direction = np.ones(len(df))
|
|
pos = bl.vol_target(direction, df, target_vol=TARGET_VOL,
|
|
vol_win_days=VOL_WIN_D, leverage_cap=LEV_CAP)
|
|
# long-only risk-parity: clip to [0, cap] (no shorts by construction)
|
|
return np.clip(np.nan_to_num(pos, nan=0.0), 0.0, LEV_CAP)
|