Files
PythagorasGoal/Old/scripts/analysis/fractal_argo_workflow.js
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

176 lines
11 KiB
JavaScript

export const meta = {
name: 'fractal-argo-search',
description: 'Ricerca a ~100 agenti: strategia FRATTALI del segnale x REGIME ARGO (DVOL/funding/VRP) validata OOS',
phases: [
{ title: 'Search', detail: '92 agenti: griglia frattale x regime x asset + wildcard' },
{ title: 'Verify', detail: 'verifica avversariale dei survivor (look-ahead, fee 0.2%, altro asset/split)' },
{ title: 'Synth', detail: 'classifica, sceglie vincitori, propone implementazione' },
],
}
const API = `
=== regime_lab API (gia pronta, dati FRESCHI in cache) ===
from scripts.analysis.regime_lab import load_features, report
from scripts.analysis.explore_lab import robust, atr, ema, rsi
df = load_features(ASSET, TF) # ASSET in {BTC,ETH}, TF in {1h,4h,1d}
# Colonne (tutte CAUSALI, valore a barra i usa solo dati <= i):
# OHLCV: open high low close volume timestamp
# REGIME (ARGO-proxy backtestabile): dvol, dvol_pct (percentile rolling 0..1),
# rv (realized vol ann.), vrp = dvol-rv (>0 = vol sopravvalutata ~ ARGO GEX+ range),
# funding, funding_z (z-score rolling), dvol_chg (DVOL salita/discesa, proxy term-structure)
# FRATTALI: hurst (>0.5 persistente/trend, <0.5 anti-persistente/mean-rev), higuchi (FD: alta=frastagliato),
# vratio (vol breve/lunga), frac_up/frac_dn (Williams pivot bool: swing high/low confermati, CAUSALI)
# NB: dvol e' NaN prima del 2021-03 (storico DVOL) -> salta le barre con dvol NaN se usi il regime.
# Costruisci 'entries': lista dict {i, d(+1/-1), tp, sl, max_bars}. INGRESSO ESEGUIBILE:
# i, d, tp, sl decisi con dati <= close[i]. tp/sl in PREZZO (o None). Esempio fade:
ent=[]
c=df['close'].values; a=atr(df,14); ma=df['close'].rolling(50).mean().values; sd=df['close'].rolling(50).std().values
for i in range(300, len(c)-1):
if np.isnan(sd[i]) or np.isnan(df['dvol_pct'].iloc[i]): continue
if df['vrp'].iloc[i] > 0 and c[i] < ma[i]-2.5*sd[i]: # GATE regime + SEGNALE frattale/tecnico
ent.append({'i':i,'d':1,'tp':ma[i],'sl':c[i]-2*a[i],'max_bars':24})
res = report('NOME', ent, df) # -> {full:{ret,sharpe,dd,trades,win,exposure}, oos:{...}, sweep, sweep_oos, pos_yrs, n_yrs}
ok = robust(res) # True = full+oos>0 E regge fee 0.2% RT E anni ~tutti positivi
print('ROBUST', ok, 'trd', res['full']['trades'], 'OOSsharpe', round(res['oos']['sharpe'],2),
'OOSret', round(res['oos']['ret']), 'fee02OOS', round(res['sweep_oos'][0.002]))
`
const CONTEXT = `
PROGETTO PythagorasGoal: trading crypto BTC/ETH. Edge dimostrato = SOLO mean-reversion (fade) + pairs.
ASTICELLA ALTA: il portafoglio PORT06 e' gia a Sharpe OOS 8.19 / DD 2.3%. Una strategia nuova vale solo
se ha edge NETTO validato OOS e robusto.
PRIORI ONESTI (non ignorarli): i FRATTALI sono stati gia esplorati e quasi tutti RUMORE (shape_lab:
analog kNN solo BTC-overfit; PIP/pivot 0/48 robuste; DTW peggiora). Le OPZIONI sono state SCARTATE
(W18/19/21 VRP). L'unico edge frattale validato e SH01 (shape-ML logit, diversificatore). MA: la
combinazione FRATTALE-del-segnale x REGIME-ARGO (gating su DVOL/funding/VRP) e' NUOVA e non testata ->
e' qui che potrebbe esserci valore: il regime puo dire QUANDO il segnale frattale funziona.
OBIETTIVO: trovare una strategia che combini un SEGNALE FRATTALE con un GATE/INTERAZIONE DI REGIME
(ARGO-proxy: DVOL percentile, VRP, funding) e che superi la validazione onesta (robust()=True).
METODOLOGIA OBBLIGATORIA: ingresso ESEGUIBILE senza look-ahead (le colonne regime_lab sono gia causali;
le TUE entries devono usare solo dati <= i). Backtest NETTO fee (report() fa gia sweep 0.0-0.2% RT + OOS
ultimo 30%). robust()=True e' il gate minimo. Diffida dell'overfit: poche entries o edge solo full e
non-oos = rumore. Riporta ONESTAMENTE anche i fallimenti.
` + API
const SCHEMA = {
type: 'object',
properties: {
strategy: { type: 'string', description: 'nome + 1 frase: segnale frattale + gate regime' },
family: { type: 'string' }, angle: { type: 'string' }, asset: { type: 'string' }, tf: { type: 'string' },
trades: { type: 'integer' },
full_ret: { type: 'number' }, oos_ret: { type: 'number' },
full_sharpe: { type: 'number' }, oos_sharpe: { type: 'number' }, oos_dd: { type: 'number' },
fee02_oos_ret: { type: 'number', description: 'OOS ret a fee 0.2% RT' },
robust: { type: 'boolean', description: 'robust()=True' },
promising: { type: 'boolean', description: 'vale una verifica avversariale (robust o quasi, non overfit)' },
edge_desc: { type: 'string', description: 'perche funziona / perche e rumore, con i numeri' },
},
required: ['strategy', 'asset', 'tf', 'trades', 'oos_sharpe', 'robust', 'promising', 'edge_desc'],
}
const FAMILIES = [
['hurst', 'Hurst regime: fade quando hurst<0.5 (anti-persistente), o trend quando hurst>0.5. Soglia hurst come segnale o gate.'],
['higuchi', 'Fractal dimension Higuchi: FD alta = frastagliato/range (fade), FD bassa = liscio/trend (momentum).'],
['williams', 'Williams pivot (frac_up/frac_dn, causali): fade del pivot (reversione allo swing) o breakout del pivot.'],
['vratio', 'volatility_ratio: >1 espansione vol (breakout/fade del breakout), <1 compressione (range/squeeze).'],
['analog', 'analog kNN sulla FORMA (puoi usare scripts.analysis.shape_lab.analog_signals(df,...)): forecast causale segno a H barre, gatealo col regime.'],
['multiscale', 'multi-scala: combina hurst+higuchi+vratio in un indice di "regime frattale" (trend vs chop) come segnale.'],
['candle', 'pattern candele frattali (src.fractal.patterns: extract_body_ratios/shadow, find_patterns): sequenze multi-barra come segnale.'],
]
const ANGLES = [
['none', 'NESSUN gate regime: segnale frattale puro (baseline per misurare il valore marginale del regime).'],
['dvol_high', 'agisci solo con dvol_pct alto (>0.6..0.8): vol elevata (spesso mean-reversion piu forte).'],
['dvol_low', 'agisci solo con dvol_pct basso (<0.3..0.4): calma/range.'],
['vrp', 'VRP=vrp colonna: VRP>0 (vol sopravvalutata, analogo ARGO GEX+ -> range/fade); confronta con VRP<0. Gate o peso.'],
['funding', 'funding_z estremo: troppi long (funding_z alto) -> fade ribassista; troppi short -> fade rialzista (flusso ARGO via perp).'],
['dvol_chg', 'dvol_chg: DVOL in salita (espansione vol/stress -> trend) vs discesa (ritorno calma -> range).'],
]
const ASSETS = ['BTC', 'ETH']
phase('Search')
// 7 famiglie x 6 angoli x 2 asset = 84 agenti griglia
const gridSpecs = []
for (const [fam, fdesc] of FAMILIES)
for (const [ang, adesc] of ANGLES)
for (const asset of ASSETS)
gridSpecs.push({ fam, fdesc, ang, adesc, asset })
const gridTasks = gridSpecs.map((s) => () => agent(
CONTEXT +
`\n\nIL TUO CELLA:\n- FAMIGLIA FRATTALE: ${s.fam} -> ${s.fdesc}\n- ANGOLO REGIME: ${s.ang} -> ${s.adesc}\n- ASSET: ${s.asset}\n\n` +
`Progetta la MIGLIORE strategia in questa cella: un SEGNALE basato sulla famiglia frattale ${s.fam}, ` +
`condizionato/interagito col regime ${s.ang}. Scrivi uno script in /tmp (cd /opt/docker/PythagorasGoal && ` +
`uv run python /tmp/<tuofile>.py), prova SIA TF=1h SIA TF=1d (e se vuoi 4h), itera 2-4 varianti di soglia/` +
`direzione/exit, e RIPORTA la migliore (quella con oos_sharpe piu alto e robust se possibile). Usa report()+robust(). ` +
`Privilegia mean-reversion (l'edge del progetto) ma testa anche momentum dove il regime lo motiva. ` +
`Mai look-ahead. Se tutto e rumore, dillo onestamente (promising=false). Ritorna lo schema.`,
{ label: `srch:${s.fam}/${s.ang}/${s.asset}`, phase: 'Search', schema: SCHEMA }))
// 8 wildcard: mandato aperto
const wildTasks = Array.from({ length: 8 }, (_, k) => () => agent(
CONTEXT +
`\n\nSEI UN AGENTE WILDCARD #${k + 1}. Mandato APERTO: inventa una combinazione FRATTALE-del-segnale x ` +
`REGIME-ARGO NON banale e non nella griglia ovvia. Idee: interazione hurst*vrp (mean-rev solo se ` +
`anti-persistente E vol sopravvalutata); Williams pivot come TP/SL adattivo gateato da dvol; analog kNN ` +
`pesato per funding; size/exit modulati dal regime; combinare 2 segnali frattali con conferma di regime. ` +
`Asset e TF a tua scelta (prova entrambi gli asset). Costruisci, testa onesto (report()+robust()), riporta ` +
`la migliore. Diversifica dagli altri: varia idea in base a #${k + 1}. Schema in output.`,
{ label: `wild:${k + 1}`, phase: 'Search', schema: SCHEMA }))
const searchResults = (await parallel([...gridTasks, ...wildTasks])).filter(Boolean)
// survivor = robust, oppure promising con oos_sharpe alto e abbastanza trade
const survivors = searchResults.filter(r =>
(r.robust || (r.promising && (r.oos_sharpe || 0) >= 1.0)) && (r.trades || 0) >= 30)
log(`Search: ${searchResults.length} testati, ${survivors.length} survivor da verificare`)
phase('Verify')
const VSCHEMA = {
type: 'object',
properties: {
strategy: { type: 'string' }, confirmed: { type: 'boolean' },
reason: { type: 'string', description: 'esito audit look-ahead + fee0.2% + altro asset + split alternativo' },
oos_sharpe_recheck: { type: 'number' }, killed_by: { type: 'string' },
},
required: ['strategy', 'confirmed', 'reason'],
}
let verified = []
if (survivors.length) {
verified = (await parallel(survivors.map(s => () => agent(
CONTEXT +
`\n\nVERIFICA AVVERSARIALE di un candidato survivor:\n${JSON.stringify(s, null, 1)}\n\n` +
`Tuo compito: PROVARE A FALSIFICARLO. (1) Ricostruisci la strategia (chiedi i dettagli dal suo edge_desc; ` +
`riusa regime_lab). (2) AUDIT look-ahead: ogni colonna/calcolo usa solo dati <= i? Il gate regime e' noto a i? ` +
`(3) Regge fee 0.2% RT in OOS? (4) Regge sull'ALTRO asset (se BTC prova ETH e viceversa)? (5) Regge a uno SPLIT ` +
`OOS alternativo (es. train<=2024, test 2025-26)? (6) Numero trade sufficiente e non concentrato in 1 anno? ` +
`Default a confirmed=FALSE se incerto o se sopravvive solo per overfit. Sii spietato. Schema in output.`,
{ label: `verify:${(s.strategy || '').slice(0, 24)}`, phase: 'Verify', schema: VSCHEMA })))).filter(Boolean)
}
const confirmed = verified.filter(v => v.confirmed)
phase('Synth')
const synthesis = await agent(
CONTEXT +
`\n\nHai i risultati di ${searchResults.length} agenti di ricerca e ${verified.length} verifiche avversariali.\n\n` +
`SURVIVOR CONFERMATI:\n${JSON.stringify(confirmed, null, 1)}\n\n` +
`TUTTI I SURVIVOR (anche non confermati):\n${JSON.stringify(survivors, null, 1)}\n\n` +
`TOP 15 per oos_sharpe fra tutti i testati:\n${JSON.stringify(
searchResults.slice().sort((a, b) => (b.oos_sharpe || 0) - (a.oos_sharpe || 0)).slice(0, 15), null, 1)}\n\n` +
`Produci la SINTESI FINALE (italiano) per il decisore:
1) VERDETTO: esiste una strategia frattale x ARGO con edge validato OOS? quale/i (confermate)?
2) Tabella dei top candidati: strategia, asset/tf, OOS Sharpe, OOS ret, DD, robust, confermato?
3) Il regime ARGO (DVOL/VRP/funding) AGGIUNGE valore al segnale frattale (vs angolo 'none')? In quali celle?
4) Cosa e' rumore e perche (coerente coi priori: frattali deboli, opzioni scartate).
5) Se c'e un vincitore: piano di implementazione (file in scripts/strategies/, MODULE_MAP, validazione finale).
Se NON c'e: dillo chiaro, niente forzature.
Cita NUMERI reali (OOS Sharpe, ret, trades). Onesta brutale: deve battere PORT06, non solo essere >0.`,
{ label: 'synthesis', phase: 'Synth' })
return { searchResults, survivors, confirmed, synthesis }