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 }
