============================================================ ALGO - DOCUMENT HEADER ------------------------------------------------------------ Doc ID : B3 Title : EA - OUTPUT SPEC (CANONICAL, ALL REQUIRED) Filename : B3 - EA - OUTPUT SPEC (CANONICAL, ALL REQUIRED) - V09.txt Version : V18 Updated : 2026-04-25 16:35 (Europe/Rome) Status : SINGLE SOURCE OF TRUTH (EA CONTRACT) Changelog : - V18: introdotta l'estensione canonica opzionale `logic_occurrences` per audit occurrence-based, provenance esplicita e collegamento tra occurrences e trade; chiarita la non inferibilita' locale delle occorrenze selezionate. - V17: introdotta l'estensione canonica `logic_state` per esporre serie booleane state-based bar-per-bar di Conditions, Pattern e Position State; chiarito che i consumer che richiedono state-based logic non devono inferirla implicitamente da eventi sparsi. - V16: chiarito esplicitamente che `mre` e' il minimo EXEC ammesso del Pattern e puo' quindi essere uguale o piu' fine del `pattern_tf`; vietato interpretarlo come vincolo a restare sullo stesso tf logico del Pattern. - V15: formalizzato che un evento logico puo' opzionalmente esporre in `meta` un `runtime_anchor_dt` operativo distinto dal proprio `cert_dt` logico; per dataset BAR_START puo' opzionalmente esporre anche `logical_bar_start_dt` per evitare ambiguita' di lookup sul close anchor. - V14: reso hard-law che il mapping logical->EXEC non puo' usare exact-match su logical close anchor; il criterio canonico e' "latest EXEC close anchor <= logical close anchor" e il CORE puo' rifiutare script non conformi. - V13: formalizzato che se il logical close anchor precede il primo close disponibile del dataset EXEC caricato nel run, il segnale va trattato come bootstrap/range truncation e saltato, non come errore fatale. - V12: chiarito esplicitamente che per dataset etichettati BAR_START il campo `dt` grezzo non puo' essere usato come logical close anchor; `cert_dt` e mapping logico -> EXEC devono usare il close anchor canonico della barra logica. - V11: formalizzato che una condizione o conferma su sottostante esterno deve usare un proprio pattern_context/pattern_symbol separato; vietato comprimere dati multi-underlying in colonne extra del dataframe del simbolo tradato. - V10: formalizzato che PATTERN_REGISTRY deve essere staticamente ispezionabile dai consumer ALGO; ammessi letterali puri e riferimenti a costanti top-level staticamente risolvibili, vietata costruzione dinamica. - V09: formalizzato che il mapping barra logica -> EXEC deve usare l'anchor temporale canonico della barra logica e non la sola coincidenza di data calendario; chiarita la gestione dei daily/session-based bars etichettati su close di sessione e giorni non-trading. - V08: formalizzata la struttura obbligatoria dettagliata di ai_description, incluse tabelle Markdown per Variables e Constants e sezione ChartTrade Semantics. - V07: chiarito che per eventi/condizioni certificati al close della barra logica, cert_dt deve rappresentare il close logico e non lo start della barra. - V06: formalizzato che i consumer devono leggere pattern_tf dal PATTERN_REGISTRY invece di ricalcolarlo quando gia' presente. - V06: formalizzata la retrocompatibilita' report-only sui campi legacy timeframes / meta.pattern_timeframe per run storici. - V05: chiarita la semantica obbligatoria di start vs cert negli events. - V05: formalizzate onset su EXEC, persistence, no-lookahead e plotting sul fenomeno reale. - V04: introdotto il modello Pattern Source Family / Pattern TF derivato / EXEC_TF / MRE. - V04: distinta la semantica di Variables e Constants dentro i Parameters. - V04: aggiornata la firma concettuale dell'EA con pattern_contexts invece di pattern_dfs flat. - V04: esplicitata la semantica start_dt vs cert_dt per le Conditions. ============================================================ B3 - EA - OUTPUT SPEC (CANONICAL, ALL REQUIRED) Versione: V18 Status : SINGLE SOURCE OF TRUTH (EA CONTRACT) ============================================================ 0) SCOPO ============================================================ Questo documento definisce il contratto canonico dell'EA in ALGO: - input contract - naming top-level - PATTERN_REGISTRY - semantica di Pattern, Conditions, Parameters, EXEC_TF e MRE - schema trade/event - regole su datetime e output hygiene ============================================================ 1) HARD-LAW ============================================================ - Zero optional sul contratto pubblico salvo ove esplicitato. - Zero extra keys non approvate. - Zero fallback. - Zero alias. - Zero normalizzazioni. - Token timeframe identici a quelli del DB. - ai_description sempre presente. - pattern_registry sempre presente. - trades sempre chiusi. - datetime output sempre UTC ISO-8601 con Z. ============================================================ 2) INPUT CONTRACT CANONICO DELL'EA ============================================================ Firma canonica logica: run_backtest(symbol, timeframe, period, params, df_exec, pattern_contexts) Semantica: - symbol: simbolo operativo del run - timeframe: EXEC_TF del run - period: periodo logico del run - params: parametri strategici pubblici - df_exec: dataframe del dataset operativo di esecuzione - pattern_contexts: dict che mappa pattern_id -> contesto dati del Pattern Ogni pattern_context deve contenere almeno: - pattern_id - pattern_symbol - pattern_tf - source_family - dfs_by_tf Regole: - pattern_tf e' derivato dal Pattern Registry ed e' il piu' piccolo tf fra le Conditions del Pattern. - dfs_by_tf deve contenere tutti i dataframe richiesti dalle Conditions del Pattern. - Il runtime passa dataframe gia' risolti dal DB; l'EA non deduce dataset_id. - L'EA non costruisce timeframe a partire da df_exec. - Se una parte della logica usa un sottostante esterno o un simbolo diverso dal simbolo tradato del run, quel blocco deve vivere in un pattern_context separato con proprio pattern_id e pattern_symbol. - Non e' consentito comprimere dati multi-underlying nel dataframe del simbolo tradato tramite colonne synthetic extra tipo `vix_close`. ============================================================ 3) TIMEFRAME TOKENS CANONICI ============================================================ Token ammessi alla data di questa spec: - S1 - M1, M3, M5, M10, M15, M30 - H1, H2, H4, H6 - D - W - M - Y - EXEC Regole: - Daily canonico = D - EXEC e' ammesso solo come tf logico per events/registry di entry ed exit o rilevazioni intrabar. - EXEC non e' un token timeframe DB e non puo' essere usato come timeframe di dataset. ============================================================ 4) TOP-LEVEL OUTPUT SCHEMA (ALL REQUIRED) ============================================================ Chiavi top-level obbligatorie: - contract_id - contract_version - generated_at_utc - symbol - timeframe - period - strategy_name - strategy_version - strategy_code - strategy_type - strategy_params - pattern_registry - ai_description - trades - build - meta Chiavi top-level opzionali approvate: - logic_state - logic_occurrences Valori canonici: - contract_id = "ALGO_EA_OUTPUT" - contract_version = "B3-V04" - strategy_type = "EA" - timeframe = EXEC_TF del run Nota importante: - La versione di questo documento e la `contract_version` del payload non sono la stessa cosa. - Questo documento puo' evolvere per chiarimenti, governance, retrocompatibilita' e semantica operativa senza cambiare necessariamente il payload contract. - Fino a modifica esplicita dello schema payload e del validator, `contract_version` resta `B3-V04`. ============================================================ 5) STRATEGY_PARAMS ============================================================ strategy_params deve contenere almeno: - variables - constants variables deve contenere almeno: - initial_capital - position_size - commission_per_trade - slippage_ticks constants deve contenere almeno: - tick_size - point_value Regole: - Variables = parametri modificabili via UI. - Constants = parametri visibili ma non modificabili via UI. - strategy_params non deve contenere chiavi runtime interne. - Il DB continua a governare i contract specs reali quando previsti dalle policy di runtime. ============================================================ 6) PATTERN_REGISTRY ============================================================ pattern_registry e' obbligatorio e contiene: - registry_version - parameters - patterns - meta parameters contiene: - variables - constants Ogni pattern contiene almeno: - pattern_id - pattern_symbol - title - summary - pattern_tf - mre - conditions - entries - exits - completion_rule Ogni condition contiene almeno: - condition_id - description - easy_language - tf - certification_rule Ogni entry contiene almeno: - entry_id - description - easy_language - tf - fill_policy Ogni exit contiene almeno: - exit_id - description - easy_language - tf - fill_policy Regole: - pattern_tf e' il piu' piccolo tf fra le Conditions del Pattern. - mre e' il Minimum Required EXEC del Pattern. - `mre` puo' essere uguale o piu' fine del `pattern_tf`. - Un Pattern con `pattern_tf = D` puo' dichiarare, ad esempio, `mre = D`, `H1` o `M1` se la logica operativa richiede un EXEC piu' preciso. - `mre` non puo' essere piu' grossolano del `pattern_tf`. - Gli event_id emessi nei trades devono esistere nel pattern_registry. - Tutti i tf non-EXEC devono usare solo token timeframe canonici del DB. - `pattern_registry` deve essere machine-readable e staticamente ispezionabile dai consumer ALGO. - Sono ammessi: - dict/list/tuple/constant literal puri - riferimenti a costanti top-level staticamente risolvibili, per esempio `PATTERN_TF = "D"` e poi `"pattern_tf": PATTERN_TF` - Non sono ammessi: - helper function calls - dict merge dinamici - string formatting runtime - imported symbols non staticamente risolti - costruzione del registry dipendente dal runtime - I consumer downstream (UI/API/reports/audit) devono leggere pattern_tf dal campo esplicito del PATTERN_REGISTRY quando presente; non devono ricalcolarlo dalle Conditions se il metadata canonico e' gia' disponibile. - In retrocompatibilita' report-only, run storici possono ancora esporre timeframes o meta.pattern_timeframe; questi campi legacy non sostituiscono il contratto canonico ma possono essere letti solo per visualizzare correttamente dati gia' persistiti. - In fase di design dell'EA, il pattern_registry deve riflettere solo eventi con semantica auditabile chiara. - Le Conditions pensate per comparire in charttrade devono essere definite anche in termini di utilita' visiva: fenomeno osservato, punto reale di start e punto canonico di conferma. - Non devono essere emesse Conditions solo per "riempire" il chart con marker se quelle Conditions non aggiungono chiarezza auditiva al trade. ============================================================ 7) AI_DESCRIPTION ============================================================ - ai_description deve esistere sempre. - Deve essere testo umano strutturato, dettagliato e auditabile. - Non puo' essere una descrizione libera troppo breve o vaga. - Deve includere obbligatoriamente queste sezioni, nello stesso campo `ai_description`: - `Strategy Overview` - `Pattern Logic` - `Detailed Condition Semantics` - `Variables` - `Constants` - `ChartTrade Semantics` - `Operational Notes` - La sezione `Variables` deve contenere una tabella Markdown con colonne: - `Variable` - `Meaning` - `Effect on strategy` - La sezione `Constants` deve contenere una tabella Markdown con colonne: - `Constant` - `Meaning` - `Effect on execution / PnL` - La sezione `Pattern Logic` deve spiegare almeno: - Pattern - Conditions - Entry - Exit - tf logici - `pattern_tf` - `MRE` - La sezione `Detailed Condition Semantics` deve spiegare ogni Condition presente nel PATTERN_REGISTRY con una sottosezione identificabile dal suo `condition_id` canonico, per esempio `P1C1`. - Per ogni Condition deve dichiarare almeno: - formula o regola operativa in linguaggio auditabile - parametri/default coinvolti - regola esatta di pass/fail, inclusa la strictness degli operatori (`>`, `>=`, `<`, `<=`) - significato di mercato della Condition - ruolo della Condition dentro il Pattern - warm-up/data availability quando rilevante - onset/start e certificazione quando rilevanti per charttrade o audit - La sezione `ChartTrade Semantics` deve spiegare almeno: - quali eventi sono visibili - quali eventi non sono visibili - perche' ogni evento visibile merita di comparire - dove viene ancorato sul chart - come leggere `start_dt/start_price` vs `cert_dt/cert_price` - eventuale mapping tra barra logica e barra `EXEC` - La sezione `Operational Notes` deve spiegare almeno: - single-position o multi-position - force-exit se presente - eventuali assunzioni runtime rilevanti ============================================================ 8) TRADE SCHEMA (ALL REQUIRED) ============================================================ Ogni trade deve contenere: - id - side - qty - entry_dt - entry_price - entry_bar - exit_dt - exit_price - exit_bar - stop_price - mae_ticks - mfe_ticks - mae_points - mfe_points - mae_ccy_1c - mfe_ccy_1c - pnl_gross - commission - slippage - pnl_net - events - meta Regole: - stop_price puo' essere null. - events deve essere lista non vuota. - meta deve esistere sempre. ============================================================ 9) EVENT SCHEMA (ALL REQUIRED) ============================================================ Ogni event deve contenere: - event_id - event_type - tf - start_dt - start_price - cert_tf - cert_dt - cert_price - meta Event type ammessi: - CONDITION - PATTERN - ENTRY - EXIT Regole: - Una Condition puo' avere start_dt su EXEC e cert_dt sul suo tf logico. - ENTRY ed EXIT usano canonically tf = EXEC. - PATTERN usa il tf della condition finale che ne certifica il completamento. - trade.events deve includere almeno CONDITION, PATTERN, ENTRY, EXIT. - start_dt/start_price rappresentano sempre il primo onset valido del fenomeno. - cert_dt/cert_price rappresentano sempre la conferma canonica dell'evento. - start e cert non sono intercambiabili e non devono essere collassati in un solo timestamp/prezzo. - Se un evento o una Condition certifica al close della barra logica e non esiste un onset precedente distinto, sia start_dt sia cert_dt possono coincidere con il close logico della barra; usare lo start della barra come cert_dt in quel caso e' semanticamente scorretto. - Se una Condition viene osservata intrabar su EXEC ma richiede persistence fino alla close del proprio tf logico, l'EA deve scartare l'onset non persistente. - L'EA non puo' usare lookahead per anticipare certificazioni, entry o sopravvivenza futura di un setup. - Gli eventi destinati alla rappresentazione in charttrade devono essere scelti intenzionalmente durante la progettazione dell'EA. - Se un evento non ha una collocazione visiva chiara sul fenomeno reale, e' preferibile non emetterlo come marker chart-oriented. ============================================================ 10) DATETIME / TIMEZONE ============================================================ Input data: - df_exec.dt e pattern_contexts[*].dfs_by_tf[*].dt sono BAR START in America/New_York. - Regola canonica aggiuntiva: alcuni dataset logici di Pattern, soprattutto daily/session-based, possono essere etichettati dal DB con il timestamp canonico del close logico della sessione invece che con un puro bar-start calendariale. - In questi casi l'EA non deve reinterpretare quel timestamp usando sola aritmetica di calendario o semplice uguaglianza di `date`. Output data: - generated_at_utc, entry_dt, exit_dt, start_dt, cert_dt sono UTC ISO-8601 con Z. ============================================================ 11) COSTI / PNL ============================================================ Per ogni trade: - commission = variables.commission_per_trade * qty - slippage = variables.slippage_ticks * constants.tick_size * constants.point_value * qty - pnl_net = pnl_gross - commission - slippage ============================================================ 12) MAE / MFE (CANONICO) ============================================================ Campi obbligatori: - mae_ticks - mfe_ticks - mae_points - mfe_points - mae_ccy_1c - mfe_ccy_1c Identita' obbligatorie: - mae_points = mae_ticks * tick_size - mfe_points = mfe_ticks * tick_size - mae_ccy_1c = mae_points * point_value - mfe_ccy_1c = mfe_points * point_value ============================================================ 13) BUILD / META ============================================================ build e' obbligatorio e deve contenere almeno: - algo_version - runtime_version - ea_template_version - validator_version - git_commit - python_version - build_machine - dataset_timezone - output_timezone - dt_convention meta e' obbligatorio. - Serve solo per metadata ammessi dal contratto. - Non deve diventare un contenitore di chiavi arbitrarie fuori controllo. - Per gli eventi logici (`CONDITION` / `PATTERN`) e' ammesso, quando necessario, esporre in `event.meta`: - `runtime_anchor_dt` - `runtime_anchor_price` - `logical_bar_start_dt` - Questi campi servono solo a chiarire: - l'anchor runtime operativo distinto dalla certificazione logica - il bar-start reale del dataset logico quando `cert_dt` usa il close anchor canonico e il dataset e' etichettato `BAR_START` - Questi campi non sostituiscono `start_dt/start_price` o `cert_dt/cert_price`; li completano. ============================================================ 13-bis) LOGIC_STATE (OPTIONAL EXTENSION, STATE-BASED LOGIC) ============================================================ `logic_state` e' l'estensione canonica usata per esporre stati booleani bar-per-bar di: - Conditions - Pattern - Position State Scopo: - fornire ai consumer ALGO una rappresentazione state-based esplicita e auditabile - evitare inferenze implicite o ricostruzioni silenziose a partire da eventi sparsi - permettere al Logic Indicator di leggere uno stato booleano reale sul tf sorgente Se presente, `logic_state` deve essere un dict con: - schema_version - series - meta Valori canonici: - `logic_state.schema_version = "LS-V01"` Ogni elemento di `logic_state.series` deve contenere: - state_id - state_type - state_tf - visual_preset - points - meta `state_type` ammessi: - CONDITION - PATTERN - POSITION Semantica: - `state_id` identifica l'entita' logica. - per `CONDITION` deve corrispondere a un `condition_id` del `pattern_registry` - per `PATTERN` deve corrispondere a un `pattern_id` del `pattern_registry` - per `POSITION` identifica uno stato posizione esplicito, ad esempio `POS` - `state_tf` e' il tf sorgente reale dello stato - usa token timeframe canonici - puo' essere `EXEC` per stati di posizione o altri stati che vivono sul tf operativo - `visual_preset` dichiara la semantica visuale canonica dello stato - `points` e' la serie booleana esplicita sul tf sorgente Ogni punto di `points` deve contenere: - dt - value Regole: - `dt` deve essere UTC ISO-8601 con Z. - `dt` rappresenta il BAR_START canonico della barra del `state_tf` a cui il boolean si riferisce. - `value` deve essere boolean puro (`true` / `false`). - La serie deve essere ordinata cronologicamente in modo strettamente crescente. - Non e' ammesso carry-forward implicito. - Non e' ammessa semantica "sottintesa": se una barra del range esportato deve risultare falsa, il punto deve esistere con `value = false`. - Il consumer che richiede state-based logic non deve ricostruirla implicitamente da soli eventi runtime se `logic_state` manca. - `logic_state` non sostituisce `events`: lo integra. - `logic_state` non deve contenere metriche, alias o stati derivati non auditabili. - Lo stato posizione canonico (`POSITION`) deve rappresentare la realta' operativa della posizione sul tf sorgente reale, tipicamente `EXEC`. ============================================================ 13-ter) LOGIC_OCCURRENCES (OPTIONAL EXTENSION, OCCURRENCE-BASED AUDIT) ============================================================ `logic_occurrences` e' l'estensione canonica usata per esporre occorrenze discrete e relazioni causali di: - Conditions - Pattern - Entry - Exit - Position State Scopo: - fornire ai consumer ALGO una rappresentazione occurrence-based esplicita e auditabile - distinguere l'entita' astratta dalla sua occorrenza concreta sul mercato - permettere al Logic Indicator e alle viste audit di capire quale anchor / candidate / confirmation sia stata davvero usata - evitare inferenze silenziose a partire da soli marker prezzo, naming convenzionale o eventi sparsi Se presente, `logic_occurrences` deve essere un dict con: - schema_version - items - meta Valori canonici: - `logic_occurrences.schema_version = "LO-V01"` Ogni elemento di `logic_occurrences.items` deve contenere: - occurrence_id - entity_id - entity_type - logic_label_short - logic_label_long - semantic_role - status - occurrence_tf - start_dt - start_price - cert_dt - cert_price - depends_on_occurrence_ids - used_by_trade_ids - meta `entity_type` ammessi: - CONDITION - PATTERN - ENTRY - EXIT - POSITION `semantic_role` ammessi: - anchor - candidate - confirmation - filter - gate - pattern_complete - entry_trigger - exit_trigger - position_state - invalidation - replacement `status` ammessi: - candidate - surviving_candidate - certified - selected - superseded - invalidated Semantica: - `occurrence_id` identifica un caso concreto osservato nel run e deve essere univoco nel payload. - `entity_id` identifica la regola astratta: - per `CONDITION` deve corrispondere a un `condition_id` del `pattern_registry` - per `PATTERN` deve corrispondere a un `pattern_id` del `pattern_registry` - per `ENTRY` deve corrispondere a un `entry_id` del `pattern_registry` - per `EXIT` deve corrispondere a un `exit_id` del `pattern_registry` - per `POSITION` identifica uno stato posizione esplicito, ad esempio `POS` - `logic_label_short` e `logic_label_long` servono alla leggibilita' utente e non sostituiscono `entity_id`. - `occurrence_tf` e' il tf sorgente reale dell'occorrenza e usa token timeframe canonici. - `start_dt/start_price` e `cert_dt/cert_price` mantengono la stessa semantica canonica degli `events`. - `depends_on_occurrence_ids` esplicita la provenance dell'occorrenza: - deve essere lista, anche vuota - i riferimenti devono puntare a `occurrence_id` esistenti nello stesso blocco - `used_by_trade_ids` esplicita quali trade usano causalmente quella occorrenza: - deve essere lista, anche vuota - ogni id deve corrispondere a un `trade.id` del payload - `meta` puo' contenere dettagli aggiuntivi auditabili, per esempio: - `trade_seqs` - `supersedes_occurrence_id` - `invalidates_occurrence_id` - `runtime_anchor_dt` - `runtime_anchor_price` Relazione con `logic_state`: - `logic_state` descrive stati booleani densi bar-per-bar. - `logic_occurrences` descrive occorrenze discrete, selezioni causali e relazioni tra occorrenze. - I due blocchi sono complementari e non si sostituiscono a vicenda. - Quando il Logic Indicator deve spiegare quale occorrenza concreta e' stata usata dal trade, i consumer devono preferire `logic_occurrences` a ricostruzioni implicite. ============================================================ 14) VISUALIZATION / AUDIT SEMANTICS ============================================================ Regole canoniche: - Il marker principale di chart per un event deve rappresentare start_dt/start_price. - cert_dt/cert_price appartengono alle viste testuali di audit o a pannelli secondari. - Per eventi strutturali, il marker deve stare sul punto strutturale reale del fenomeno, non sulla successiva barra di conferma. - Se il run e' visualizzato su un timeframe piu' fine di EXEC_TF, la UI non deve inventare precisione di plotting superiore a quella realmente disponibile. - La selezione degli eventi da rappresentare in charttrade deve essere decisa in fase di creazione dell'EA, non lasciata implicita. - Per ogni Condition / Pattern / Entry / Exit che si vuole vedere in charttrade, il design dell'EA deve stabilire ex ante: - perche' quell'evento e' utile all'audit umano - quale punto reale del fenomeno deve essere plottato - se la conferma deve rimanere solo nella vista testuale - Se un Pattern vive su un tf logico piu' grosso di EXEC, il mapping verso EXEC deve usare l'anchor temporale canonico della barra logica (`cert_dt` o altro anchor dichiarato), non la sola coincidenza di data calendario. - Per dataset daily/session-based, l'EA non deve assumere che la barra logica daily cada sempre su un giorno trading di calendario. - E' ammesso che una barra daily logicamente valida sia etichettata con un timestamp che cade su sabato, domenica o altro giorno non-trading di calendario, se quello e' il timestamp canonico del dataset risolto dal DB. - In questi casi il mapping corretto verso EXEC deve essere definito rispetto al tempo canonico della barra logica, ad esempio "ultimo EXEC close <= logical close anchor", e non rispetto a `trade_date == daily_date`. - Fare affidamento a un exact-match del tipo `exec_by_anchor.get(logical_close_anchor)` e' un anti-pattern hard-fail: rompe su intraday EXEC, holiday sessions, session split e dataset close-anchored. - Il CORE puo' rifiutare in fase di registrazione/update/run gli EA che implementano o descrivono un mapping logical->EXEC basato su exact-match dell'anchor. - Fare affidamento alla sola coincidenza `date(logical_bar) == date(exec_bar)` e' un anti-pattern, perche' rompe su sessioni overnight, weekend labels e dataset close-anchored. - Se il dataset della barra logica e' etichettato `BAR_START`, usare il `dt` grezzo della barra come `logical close anchor` e' un anti-pattern: il close anchor canonico va derivato dalla barra stessa secondo il suo tf/session semantics e poi usato sia per `cert_dt` sia per il mapping logico -> EXEC. - Per dataset futures higher-TF session-based (`D/W/M`) con source vendor date-only, il DB puo' persistere `dt` come true bar start operativo della barra e non come label midnight di calendario; gli EA e i consumer devono trattare quel `dt` come source of truth del bar start. - Se il `logical close anchor` di un segnale cade prima del primo close disponibile nel dataset EXEC realmente caricato per il run, l'EA deve trattare quel tratto come bootstrap/range truncation e saltare il segnale; non deve hard-failare il backtest. - Se il payload espone `logic_occurrences`, i consumer non devono ignorare relazioni come `depends_on_occurrence_ids` o `used_by_trade_ids` e sostituirle con inferenze locali piu' deboli. - Una occorrenza visibile sul chart non deve essere assunta implicitamente come quella usata dal trade se il payload distingue tra occorrenze candidate, selezionate, superseded o invalidate. ============================================================ 15) ERROR SEMANTICS ============================================================ Se manca un dataframe richiesto da una Condition o da un Pattern: - il sistema deve fallire con errore esplicito. - l'EA non deve ricostruire timeframe. - il runtime non deve sostituire source family o dataset. ============================================================ FINE B3 ============================================================