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>
32 lines
1.5 KiB
Python
32 lines
1.5 KiB
Python
"""TEMPLATE for a blind-signal agent. COPY this, rename, implement `signal`.
|
|
|
|
You are given two anonymized, overlaid price curves ("A" and "B"), rebased to 100.
|
|
You do NOT know what they are. Find a way to ANTICIPATE the next move.
|
|
|
|
Rules (enforced automatically — break them and you are disqualified):
|
|
* `signal(df)` returns float array len(df). position[i] in [-1,+1] = how much of
|
|
equity to hold during the NEXT bar (sign=long/short, 0=flat). The evaluator
|
|
shifts it -> you trade bar i+1 with a decision made at close[i].
|
|
* CAUSAL/ONLINE only: position[i] uses ONLY rows 0..i. No .shift(-k), no centered
|
|
windows, no fitting a model on the whole df then predicting the whole df.
|
|
If you train a model, use an EXPANDING/WALK-FORWARD scheme (refit using only
|
|
past rows) or fit once on an EARLY fixed warmup and freeze.
|
|
* Tune ONLY on split='train'. The held-out tail is scored by the orchestrator.
|
|
|
|
Score it:
|
|
uv run python scripts/research/blind/blind_eval.py --module <this file> --split train
|
|
Make sure the output has "causality": {"ok": true, ...}.
|
|
"""
|
|
import numpy as np
|
|
import blindlib as bl
|
|
|
|
|
|
def signal(df):
|
|
c = df["close"].values.astype(float)
|
|
# --- EXAMPLE: vol-targeted dual-timescale momentum (replace with your idea) ---
|
|
fast = c / bl.sma(c, 20) - 1.0
|
|
slow = c / bl.sma(c, 100) - 1.0
|
|
raw = np.sign(fast) * 0.5 + np.sign(slow) * 0.5 # -1..1 direction
|
|
pos = bl.vol_target(raw, df, target_vol=0.20, vol_win_days=30, leverage_cap=1.0)
|
|
return np.clip(pos, -1.0, 1.0)
|