Il kill-switch della 4.0.0 chiudeva gli slot, non le posizioni, e «riusciva» con venti gambe ancora sul conto. Ora annulla gli ordini senza esito e ne attende la risoluzione, chiude basket, gambe in attesa e orfane (le esterne solo su richiesta o con risk.closeForeignOnKill), rilegge il conto finché le posizioni del bot non sono sparite e, se qualcosa resta, dichiara Halted-Residuo con l'elenco invece di «tutto chiuso». Il reset è una procedura in cinque passi (stato, file STOP, motivazione, riconciliazione con riscaldamento e picco, ripartenza con entrate bloccate) rifiutata finché il conto non è piatto. INotifier per le notifiche della Fase 5. Test (v)-(x). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
11 KiB
Schema del ledger e delle tabelle
Regole comuni: UTC ovunque, CultureInfo.InvariantCulture per numeri e date, CSV con separatore ; e ultima colonna motivazione, JSONL append-only. Nessuna riga viene mai modificata: le correzioni sono righe nuove con evento = correzione. Ogni riga porta run_id e, dove ha senso, config_hash (SHA-256 abbreviato di strategy.json canonicalizzato).
data/ledger/decisions.jsonl
Una riga per ogni valutazione di ogni basket alla chiusura di ogni barra M15 (ingresso, skip, aggiunta, posizione, uscita) più le uscite decise su una quotazione intermedia e gli esiti di esecuzione. Le feature sono quelle disponibili al momento della decisione: è la regola anti look-ahead, e il dataset di addestramento è questo file, non una ricostruzione.
| Campo | Tipo | Significato |
|---|---|---|
ts |
ISO 8601 UTC | istante della valutazione |
run_id |
testo | yyyyMMdd-HHmmss-xxxxxx della sessione del bot |
config_hash |
testo | hash di strategy.json in vigore |
basket |
testo | A/B, es. EURUSD/USDCHF |
basket_id |
testo | id del basket aperto (B<yyyyMMddHHmmss>-<AB>), vuoto se piatto; collega a baskets.csv |
cross |
testo | cross sintetico (EURCHF) |
mode (Paper |
Demo |
Live; i file scritti prima del 2026-09-16 pomeriggio portano i nomi precedenti DemoApprove/DemoAuto) |
preset |
testo | CONSERVATIVE, MODERATE, AGGRESSIVE |
evento |
testo | skip, segnale_ingresso, ingresso, rifiuto, leg_risk_unwind, posizione, segnale_aggiunta, aggiunta, segnale_uscita, uscita, correzione; dalla 5.0 anche le righe di evento (senza feature, solo ts, run_id, evento, basket_id, campi propri e motivazione): pending (gamba senza esito, con leg, client_ref, order_id), pending_risolto (con esito, fonte, position_id), orfana_adottata e orfana_chiusa (con position_id, strumento, pnl, exit_reason), movimento_di_cassa (con importo, saldo_prima, saldo_dopo, chiusure_nel_frattempo, cassa_cumulata), margin_guard (con equity, margine_usato), kill_switch_avviato, kill_switch_concluso (con stato = Halted o Halted-Residuo, chiuse, residuo, annullati, pnl), residuo_chiuso, reset_rifiutato, reset_concluso |
decision |
testo | Skip, Enter, Add, Exit, Hold |
buy_cross |
bool | verso deciso (compra il cross = compra entrambe le gambe nei cinque basket) |
z, z_in_eff |
numero | z-score del cross e soglia effettiva (scalata dalla vol prevista) |
D_pips |
numero | divergenza in pip dall'ancora (solo PipDivergence) |
rho_W, rho_20 |
numero | correlazione rolling dei rendimenti su window e windowShort |
halfLife |
numero | emivita OLS in barre (null se λ ≥ 0) |
atrA, atrB |
numero | ATR(14) in pip |
sigmaX, ewmaVolX |
numero | deviazione standard del livello del cross sulla finestra; vol EWMA dei rendimenti del cross |
sigmaForecast, sigmaAverage30d |
numero | vol prevista 1-4 h e media 30 g (null finché il livello 8.5 non è attivo) |
costPips, breakEvenWinRate |
numero | costo stimato in pip-equivalenti di A; win rate di pareggio |
spreadA, spreadB, markupA, markupB |
numero | spread correnti in pip; markup dell'API in pip |
hourSin, hourCos, dow |
numero | ora sul cerchio; giorno della settimana (0 = domenica) |
minutesToNextHigh, minutesSinceLastHigh, surpriseLast |
numero/null | calendario per le valute del basket |
netSentDiff_1h/4h/24h, hawkishDiff, riskOff, newsCount |
numero | sentiment (valuta lunga − valuta corta del cross) |
regimeTrend |
numero | forza di trend (ADX-like) del cross |
lastNOutcomes |
numero | media degli ultimi esiti (null finché non c'è storia) |
p_ML, mlActive |
numero, bool | probabilità del meta-modello e se è gate o ombra |
equity, openBaskets |
numero | equity e basket aperti al momento |
priceA, priceB, pipsOpen, pnlOpenUsd, barsHeld |
numero | stato della posizione (se aperta) |
unitsA, unitsB, notionalUsd, lossAtStopUsd, effectiveLeverage, marginUsd |
numero | sizing (solo su Enter); marginUsd = margine previsto delle due gambe (5.0) |
sizing_bound |
testo | quale vincolo ha deciso la size (5.0): risk, margin, leverage, units |
reasonCodes |
array | codici: no_signal, rho_low, rho_short_low, half_life, blackout_before, blackout_after, weekend, just_opened, session, max_baskets, same_cross, ml_gate, cost_gate, sizing, kill_switch, equity_stop, daily_loss, entries_blocked, data_quality, warmup, not_bar_close, enter, add, hold, tp_pips, tp_z, stop_z, stop_max_loss, spread_anomaly, time_stop, rho_break; dalla 5.0 margin (nessun margine per un nuovo basket), margin_guard (equity / margine usato sotto la soglia), min_exposure (la size a margine non raggiunge l'esposizione minima) |
motivazione |
testo | la frase, in italiano, con i numeri |
data/ledger/baskets.csv
Una riga per basket chiuso. label = 1 se pnl_net_usd > 0, altrimenti 0: è l'etichetta dei livelli 1-3.
basket_id;run_id;basket;mode;preset;opened_utc;closed_utc;buy_cross;entry_z;exit_z;pnl_gross_usd;pnl_net_usd;pips_gross;cost_pips;cost_usd;slippage_pips;adds;bars_held;exit_reason;equity_at_entry;p_ml_at_entry;label;durata_min;motivazione
pips_gross è la somma dei pip delle due gambe ai prezzi di esecuzione (la colonna "Pips" della UI), cost_pips il costo stimato all'ingresso, slippage_pips la differenza fra quotazione vista e prezzo eseguito sommata sulle gambe, exit_reason uno dei codici sopra più manual, closed_by_broker, leg_closed_by_broker, end_of_data, e dalla 5.0 leg_risk_unwind (gamba A eseguita in ritardo e richiusa, o B non coperta dal margine), margin_guard (chiuso dalla guardia del margine), orphan_closed (gamba orfana del bot adottata e chiusa alla riconciliazione), bonifica_orfana (chiusa dalla bonifica con conferma), kill_switch/equity_stop anche per le gambe singole. Le righe di una gamba singola hanno entry_z, exit_z, pips_gross e cost_* vuoti e buy_cross = verso della gamba.
data/ledger/orders.jsonl (dalla 5.0)
Una riga per ogni ordine inviato e per ogni cambio del suo stato (append-only): la prima riga di un client_ref dice cosa è stato chiesto, l'ultima come è finita. Scritta dal registro degli ordini (OrderTracker) attraverso il ledger.
| Campo | Significato |
|---|---|
ts, run_id, mode |
come in decisions.jsonl |
basket, basket_id |
slot (EURUSD/USDCHF) e istanza (B2026…-EURUSDUSDCHF) |
strumento, instrument_id, verso |
la gamba; verso = long/short dell'ordine (per una chiusura è il verso opposto alla posizione) |
leg |
A, B, Add, Close, Unwind |
unita_richieste, unita_eseguite |
differiscono quando il server riduce l'ordine (osservato il 2026-09-16) |
prezzo_richiesto, prezzo_eseguito, slippage_pip |
quotazione vista all'invio, prezzo del server, differenza in pip con il segno del costo |
stato, stato_id |
l'ultima parola del server (Submitted, Received, Placed, Filled, Rejected, …, Unknown quando non ha risposto), con l'id numerico di eToro |
esito |
Pending, Filled, Rejected, Cancelled |
order_id, position_id, client_ref |
le tre chiavi |
fee |
commissioni riportate dal server all'esecuzione |
evento |
inviato, stato, risolto |
motivazione |
la motivazione della decisione o l'errore del server |
data/state/pending_orders.json (dalla 5.0)
Il registro degli ordini: savedUtc e l'array orders con gli stessi campi di orders.jsonl più checks, lastCheckUtc, source (venue, lookup, lookup-v1, positions). Contiene tutti gli ordini senza esito e quelli risolti nelle ultime 48 ore (servono a riconoscere una posizione come propria). Scritto prima di ogni chiamata HTTP e a ogni cambio di stato, con .tmp + File.Move. Un file illeggibile viene messo da parte come pending_orders.json.illeggibile-<data>. In modalità Paper il file è pending_orders_paper.json.
data/state/baskets_state.json (campi aggiunti dalla 5.0)
peakNetEquity (picco dell'equity al netto dei movimenti di cassa), cumulativeCashFlow, lastBalance e lastBalanceUtc (per riconoscere un deposito avvenuto a bot spento), pendingEntries (un elemento per basket in PendingA/PendingB: name, state, basketId e il piano pending con unità, TP, stop, riferimenti cliente e la gamba A eseguita), haltResidue (le posizioni del bot rimaste sul conto dopo un kill-switch: positionId, symbol, isBuy, units, openedUtc, origin, basket, reason). peakEquity resta per compatibilità e vale peakNetEquity + cumulativeCashFlow.
reports/bonifica_YYYYMMDD.csv (dalla 5.0)
Una riga per orfana chiusa dalla bonifica: ts;position_id;strumento;verso;unita;aperta_utc;pnl_realizzato;basket;motivazione.
results/trials.csv
Una riga per configurazione provata nel backtest; N del Sharpe deflazionato = numero di righe.
trial_id;preset;signalMode;exitMode;averaging;lot_multiplier;z_in;z_out;z_stop;TP;W;rho_min;cost_multiple;basket_stop;n_baskets;win_rate;pnl_net;sharpe;maxdd;break_even_cost;avg_cost_pips;p1_pnl;p5_pnl;psr;dsr;motivazione
break_even_cost = media per basket di (pip eseguiti + costo stimato), cioè i pip "mid-to-mid" catturati: il costo di giro che azzera il risultato. p1_pnl, p5_pnl = percentili 1 % e 5 % del P&L per basket (la coda che il win rate nasconde).
reports/falsificazione.csv
test;variante;n_baskets;win_rate;pnl_net;sharpe;maxdd;p1_pnl;p5_pnl;break_even_cost;avg_cost_pips;psr;dsr;motivazione
knowledge/calibration.csv
Win rate e P&L netto medio per bucket: dimensione;bucket;n;win_rate;pnl_medio;pnl_totale;motivazione, con dimensioni |z|, rho_W, ora, giorno, minuti_evento, sentiment, preset, basket.
knowledge/preregistrazione.csv
Una riga per forward test: data;config_hash;modalita;durata_minima;n_minimo_basket;sharpe_atteso;win_rate_atteso;dd_stop;stop_basket_consecutivi;esito;motivazione.
knowledge/proposals.csv
data;origine;parametro;valore_attuale;valore_proposto;evidenza;stato;motivazione — le proposte del ciclo settimanale; stato ∈ {proposta, in forward, accettata, respinta}. Nessuna proposta cambia i parametri live da sola.
knowledge/models_registry.csv, knowledge/forward_registry.csv
versione;data;tipo;n_train;auc_wf;brier;logloss;stato;motivazione (stato ∈ shadow, challenger, champion, ritirato) e data;config_hash;modalita;basket;pnl_net;sharpe;dd;stato;motivazione.