============================================================ ALGO - DOCUMENT HEADER ------------------------------------------------------------ Doc ID : B2 Title : CORE - OVERVIEW & ARCHITECTURE (Hard-law) Filename : B2 - CORE - OVERVIEW & ARCHITECTURE - V10.txt Version : V11 Updated : 2026-04-25 16:35 (Europe/Rome) Status : ACTIVE (DOCUMENTO FONDAMENTALE / HARD-LAW) Changelog : - V11: formalizzati `trade_id` / `trade_seq` come identita' macchina/umana del trade; introdotte le nozioni canoniche di Logic Occurrence, provenance e selected occurrence per audit/UI. - V10: formalizzato che il runtime CORE deve calcolare e rendere esplicito il primo `EXEC close` disponibile e il `backtestable start` dell'overlap pattern/EXEC; l'assenza di EXEC nella parte iniziale del pattern range non va trattata come errore fatale. - V09: chiarito che il nuovo strategy_code ufficiale e' assegnato da ALGO in modo sequenziale; strategy_version esiste solo nel contesto di una strategia gia' identificata. - V08: formalizzata la distinzione tra draft tecnico EA e registrazione ufficiale in DB, che richiede conferma esplicita dell'utente. - V07: formalizzato che UI/API/reports non devono ricalcolare metadata canonici gia' esposti dal PATTERN_REGISTRY. - V07: formalizzata la retrocompatibilita' report-only per run storici con metadata Pattern legacy. - V06: formalizzato l'obbligo di metadata macchina affidabili per UI/API/runtime sui requisiti Pattern. - V06: formalizzato il comportamento fail-closed quando i metadata canonici non sono risolvibili. - V05: formalizzata l'identita' del run con run_id macchina + run_seq umano persistito in DB. - V05: formalizzato che UI/API devono leggere il run_seq dal DB e non calcolare ordinali locali. - V04: chiarita la semantica canonica di start_dt/start_price vs cert_dt/cert_price. - V04: formalizzate onset su EXEC_TF, persistence, no-lookahead e plotting sul fenomeno reale. - V04: formalizzate le regole UI su precisione di plotting e resolved data wins. - V03: ridefinito il modello canonico Pattern / Condition / Parameters / EXEC_TF / MRE. - V03: formalizzato EXEC_TF come unico termine canonico per il timeframe operativo del run. - V03: formalizzata la Pattern Source Family come unita' di sourcing dati. - V03: formalizzato il supporto concettuale a EA multi-pattern e multi-market. ============================================================ B2 - CORE - OVERVIEW & ARCHITECTURE (Hard-law) Versione: V11 Status : ACTIVE (HARD-LAW) ============================================================ 0) SCOPO DEL DOCUMENTO ============================================================ Questo documento definisce: - il glossario canonico unico di ALGO - l'architettura end-to-end - il contratto concettuale fra UI, API, runtime, EA, validator, CORE e DB - le regole di governance che impediscono divergenze future Se c'e' conflitto fra documenti: - B2 = visione architetturale, glossario e hard-law di sistema - B3 = contratto canonico dell'EA - B4 = regole operative per sviluppo umano/AI - B5 = template tecnico ufficiale - B6 = enforcement del contratto EA - B7 = definizione numerica del CORE ============================================================ 1) GLOSSARIO / CANONICAL TOKENS ============================================================ 1.1 Principio guida - In ALGO non esistono sinonimi, alias o mapping impliciti. - Un token canonico deve essere identico in tutti i layer che lo usano. - Se il DB usa un token, quello e' il token canonico di progetto. 1.2 Token timeframe canonici del DB Token supportati alla data del documento: - S1 - M1, M3, M5, M10, M15, M30 - H1, H2, H4, H6 - D - W - M - Y Regole: - Daily canonico = D - Vietati: D1, 1D, DAILY e qualunque altro alias - I token timeframe devono comparire identici in tutti i layer che li usano 1.3 Dataset - dataset_id = identita' primaria del dataset nel DB. - timeframe = risoluzione temporale del dataset, non la sua identita'. - Possono esistere piu' dataset con lo stesso timeframe. 1.4 Pattern - Un Pattern e' un gruppo logico coerente di Conditions, Entries ed Exits. - Un Pattern non e' una singola formula. - Un Pattern non e' un singolo timeframe. - Un Pattern e' sia unita' logica sia unita' di sourcing dati. - Pattern diversi possono rappresentare blocchi logici separati della stessa operazione complessiva. - Piu' Pattern possono concorrere insieme alla readiness di una singola entry condivisa. - La suddivisione in piu' Pattern puo' essere usata per chiarezza semantica anche quando la logica sarebbe riducibile a un solo Pattern con piu' Conditions. 1.5 Condition - Una Condition e' una regola booleana verificabile sul mercato. - Ogni Condition appartiene esplicitamente a un solo Pattern. - Ogni Condition dichiara sempre il proprio tf logico. - Una Condition puo' avere start_dt osservato su EXEC_TF e cert_dt definito sul proprio tf logico. - Non ogni verita' logica dell'EA deve diventare automaticamente un marker di chart. - Le Conditions destinate a comparire in audit/charttrade devono essere progettate anche come eventi visivi, non solo come regole booleane interne. - Per ogni Condition che deve essere rappresentata in charttrade, l'EA design deve esplicitare: - quale fenomeno reale del mercato rappresenta - quale punto reale del fenomeno corrisponde a start_dt/start_price - quale punto di conferma corrisponde a cert_dt/cert_price - se il marker principale di chart deve mostrare start oppure se l'evento deve rimanere solo testuale in audit - Se una Condition non ha una semantica visiva chiara e utile all'audit, non deve essere emessa solo per produrre marker rumorosi o fuorvianti. 1.6 Parameters - I Parameters sono i valori usati da Conditions, Entries ed Exits. - I Parameters si dividono in: - Variables = modificabili dall'utente via UI - Constants = visibili all'utente ma non modificabili via UI 1.7 Pattern Source Family - La Pattern Source Family e' la scelta dati fatta per un Pattern. - Non coincide con un singolo dataset a timeframe fisso. - Nel DB reale attuale e' descritta tramite attributi strutturali del dataset, ad esempio: - vendor - origin - session - timezone - boundary - shift - calendar - variant - Il runtime puo' ricevere Pattern contexts gia' espliciti oppure una Source Family strutturale da risolvere. - In entrambi i casi, il runtime deve arrivare a dataset espliciti per tutti i tf richiesti dalle Conditions del Pattern. 1.7.1 Dataset boundary semantics - `boundary = TRADING` indica una griglia dati ancorata alla giornata operativa di borsa/sessione. Per CME futures ETH/NQ con `timezone = America/New_York` e `calendar = CME_NQ_GLOBEX`, la giornata operativa riparte alle `18:00 ET`. - `boundary = CALENDAR` indica una griglia dati ancorata al giorno civile/calendario, quindi midnight/civil grid (`00:00`, `04:00`, `08:00`, ... per H4), non alla ripartenza della sessione futures. - `shift` e' un offset sulla griglia dichiarata da `boundary`; non deve essere usato per mascherare una boundary semanticamente sbagliata. Se un H4 parte da `00:00/04:00/...`, non e' `TRADING shift=120`: e' un dataset `CALENDAR shift=0`, salvo definizione esplicita contraria. - Per dataset session-based futures ricostruiti da ALGO e ancorati a `18:00 ET`, usare `boundary = TRADING` e `shift = 0`. 1.7.2 Dataset variant semantics - `variant = RAW` indica un dataset vendor-native/originale, non ricostruito da ALGO. - `variant = DENSE` indica un dataset derivato/ricostruito da ALGO con griglia completa del timeframe dichiarato. Per ogni bucket previsto dalla griglia di `boundary/session/calendar/shift`, se il mercato e' operativo ma nel parent non esistono trade/barre effettive per quel bucket, ALGO puo' materializzare una barra sintetica zero-volume con `open = high = low = close = previous_close`. Questo riempimento e' parte esplicita del dataset persistito, non un fallback o carry-forward implicito fatto da EA/UI. - `variant = SPARSE` indica un dataset derivato/ricostruito da ALGO che preserva solo barre effettivamente presenti nel parent o nei dati/eventi sorgente. Non densifica tutti i bucket teorici della griglia e non crea barre zero-volume di riempimento per i vuoti di trading. - `variant` non deve descrivere la boundary temporale (`TRADING`/`CALENDAR`) e non deve essere usato al posto di `origin`. Un dataset ALGO ricostruito da M1 per H4 session-aware deve usare `origin = DERIVED`, `boundary = TRADING` e un `variant` coerente con la politica di densificazione scelta. 1.8 Pattern TF - Il Pattern TF e' il piu' piccolo timeframe fra tutte le Conditions del Pattern. - E' una proprieta' derivata. - Serve come etichetta sintetica e informativa. - Non e' un input dati che l'utente deve scegliere. 1.9 EXEC_TF - EXEC_TF e' il timeframe operativo scelto dall'utente in fase di backtest. - Serve per entry, exit, fill e rilevazioni intrabar quando richieste dalla logica. - EXEC_TF non sostituisce il tf logico delle Conditions. 1.10 MRE - MRE = Minimum Required EXEC. - E' il minimo livello di precisione operativa richiesto dalla logica dell'EA o del Pattern. - L'utente puo' scegliere un EXEC_TF uguale o piu' fine di MRE. - L'utente non puo' scegliere un EXEC_TF piu' grossolano di MRE. 1.11 AI_DESCRIPTION / ai_description - AI_DESCRIPTION = nome concettuale / nome costante nel codice EA. - ai_description = chiave top-level nell'output EA. - Significato: spiegazione umana, semplice e leggibile della strategia. 1.12 PATTERN_REGISTRY - Registro macchina di pattern, conditions, entries, exits, parameters e semantica eventi dichiarati dall'EA. - Deve essere coerente con gli event_id emessi nei trades. - Non e' testo libero: e' struttura dati canonica. - Le informazioni che UI, API e runtime usano per capire quali Pattern siano attivi, quali tf siano richiesti, quale MRE si applichi e quali context/dataset servano devono essere disponibili in forma macchina affidabile e deterministica. - Quando un metadata canonico e' gia' esposto in modo esplicito nel PATTERN_REGISTRY (ad esempio pattern_tf o mre), i consumer downstream non devono ricalcolarlo da strutture piu' deboli come Conditions, testo libero o naming convenzionale. - Non e' ammesso dipendere solo da parsing fragile del file EA, da testo libero o da deduzioni implicite per abilitare/disabilitare campi canonici del backtest. 1.13 contract_specs - Fonte DB delle specifiche contrattuali del simbolo. - Campi rilevanti: tick_size, point_value, currency, exchange. - Questi valori governano PNL, slippage, MAE/MFE currency-based. 1.14 strategy_code / strategy_version - `strategy_code` ufficiale di un nuovo EA e' assegnato da ALGO in modo sequenziale. - AI e sviluppatore non devono inventare, proporre o promuovere unilateralmente un nuovo `strategy_code` canonico. - `strategy_version` ha senso solo nel contesto di una strategia gia' identificata da ALGO tramite `strategy_code`. - Se si lavora su una nuova versione di una strategia esistente, il `strategy_code` deve essere gia' noto e confermato; solo allora si puo' parlare di `strategy_version`. - Fino ad assegnazione ufficiale da ALGO, si possono usare solo nomi descrittivi provvisori non canonici nelle discussioni e nei draft. 1.14-bis draft tecnico EA vs registrazione ufficiale - Un draft tecnico EA puo' essere implementato, validato e proposto senza essere ancora promosso a registrazione ufficiale. - La registrazione ufficiale in DB di un nuovo EA richiede: assegnazione del `strategy_code` da parte di ALGO e conferma esplicita dell'utente su naming e testi ufficiali. - L'aggiornamento ufficiale di Name, Description, AI Description o strategy_version di una strategia gia' esistente richiede conferma esplicita dell'utente. - In assenza di conferma esplicita, il sistema puo' preparare artefatti tecnici e testi proposti, ma non deve considerarli identita' ufficiale gia' approvata. 1.15 start_dt / start_price - start_dt e start_price rappresentano il primo onset valido del fenomeno osservato. - start non coincide automaticamente con la barra di certificazione. - Per eventi strutturali, start deve rappresentare il punto strutturale reale del fenomeno. 1.16 cert_dt / cert_price - cert_dt e cert_price rappresentano la conferma canonica dell'evento. - cert puo' appartenere a una barra successiva rispetto a start. - start e cert devono avere semantica esplicita e non intercambiabile. 1.17 run_id / run_seq / trade_id / trade_seq - run_id = identificatore macchina persistito del backtest run. - run_seq = identificatore umano sequenziale persistito del backtest run. - run_seq non e' un numero calcolato lato UI, non e' un ordinamento locale e non e' un alias derivato. - Se il run e' persistito in DB, run_id e run_seq devono essere letti dal DB e riportati in modo coerente in tutte le pagine e API che mostrano il run. - La UI puo' usare run_seq come label umana del run, ma non deve inventarlo, ricalcolarlo o sostituirlo con ordinali locali. - trade_id = identificatore macchina persistito del trade dentro il run. - trade_seq = identificatore umano sequenziale persistito del trade dentro il run. - trade_seq non e' un numero calcolato lato UI, non e' un ordinamento locale e non e' un alias derivato da trade_id. - Se il trade e' persistito in DB, trade_id e trade_seq devono essere letti dal DB e riportati in modo coerente in tutte le pagine e API che mostrano quel trade. - La UI puo' usare trade_seq come label umana del trade, ma non deve inventarlo, ricalcolarlo o rinumerarlo localmente. 1.18 Logic Occurrence - Una Logic Occurrence e' un'occorrenza concreta, identificabile e auditabile di una Condition, Pattern, Entry, Exit o Position State. - L'entita' astratta (ad esempio `P1C1`) e la sua occorrenza concreta non sono la stessa cosa. - entity_id = regola astratta definita nel PATTERN_REGISTRY. - occurrence_id = caso concreto osservato sul mercato durante il run. - Una Logic Occurrence puo' essere candidata, certificata, selezionata, superseded o invalidata. 1.19 Occurrence Dependency / Provenance - Una Logic Occurrence puo' dipendere esplicitamente da una o piu' altre occurrences. - La provenance deve essere machine-readable, non ricostruita per inferenza debole lato UI. - Se una occorrenza usa un anchor precedente per confronto o conferma, il legame deve essere esplicito via occurrence_id. 1.20 Selected Occurrence / Used-by-trade - Non ogni occorrenza visibile sul chart e' automaticamente quella usata dal trade. - Se una occorrenza e' causalmente rilevante per il trade, il payload deve poter dichiarare in modo esplicito se e' stata usata dal trade e da quale trade_seq / trade_id. - Lo scopo e' permettere audit visivo immediato di "cosa e' successo, dove, quando e con quale riferimento". ============================================================ 2) COS'E' ALGO (E COSA NON E') ============================================================ ALGO e' una piattaforma che: - esegue backtest tramite EA che producono trades chiusi + events - valida l'output EA - calcola metriche, equity, drawdown e analytics nel CORE - presenta risultati in UI e salva dati in DB in modo coerente ALGO NON e': - un posto dove l'EA calcola analytics o metriche CORE - un sistema che prova a far funzionare contratti incompleti - un framework che ammette output quasi giusti o naming inventati ============================================================ 3) PRINCIPI NON NEGOZIABILI (HARD-LAW) ============================================================ P-01 Separazione dei ruoli - EA = descrive cosa e' successo. - CORE = calcola cosa significa. P-02 DB wins - Il DB e' la source of truth per timeframe reali, dataset reali, source family e contract specs. - Il DB e' anche la source of truth per l'identita' persistita del run (`run_id`, `run_seq`). P-03 Output contract strict - L'output EA deve rispettare B3. - Zero extra keys non approvate. P-04 Zero fallback / zero alias / zero normalizzazioni - Nessuna ricostruzione implicita di timeframe. - Nessuna conversione implicita di token. - Nessun dataset sostitutivo mostrato in preview. P-05 Determinismo - Stessi input -> stessi output. P-06 No lookahead - L'EA usa solo dati disponibili fino al timestamp logico del segnale. P-07 Trades sempre chiusi - Nessuna posizione aperta nell'output EA. P-08 Timezone globale - Input market data: dt = BAR START in America/New_York. - Output EA: UTC ISO-8601 con Z. - CORE: opera in UTC. - UI/API che mostrano market data o trade persistiti non devono convertire gli orari verso timezone locali del browser o dell'utente: devono mostrare il timestamp DB cosi' come rappresenta la semantica canonica del dataset/oggetto persistito. - Per dataset futures session-based `D/W/M` con vendor rows date-only, `prices.dt` non deve essere una fake civil-midnight label: deve rappresentare il vero bar start operativo della barra higher-TF secondo la semantica di sessione/exchange adottata. P-09 Pattern-level sourcing - La scelta dati dei Pattern avviene a livello di Pattern Source Family, non a livello di singola Condition. - Tutte le Conditions di un Pattern devono usare la stessa Pattern Source Family. P-10 Multi-market consentito - Uno stesso EA puo' contenere Pattern su symbol diversi. - La sincronizzazione fra Pattern avviene tramite dt. P-11 Onset reale prima della certificazione - Un evento puo' iniziare su EXEC_TF e certificare sul proprio tf logico. - Il sistema deve distinguere sempre onset osservato e conferma canonica. P-12 Persistence esplicita - Se la logica di una Condition richiede persistence fino alla certificazione, l'EA deve verificarla esplicitamente. - Un onset intrabar non persistente non puo' essere promosso implicitamente a Condition certificata. P-13 Metadata canonici machine-readable - I requisiti canonici di un EA che governano UI/API/runtime devono essere determinabili in forma macchina affidabile. - Questo include almeno: Pattern in uso, pattern_tf, MRE, source family richiesta e necessita' di pattern_contexts/dataset espliciti. - Un EA non e' considerato UI-runnable se questi metadata non sono risolvibili in modo deterministico. - Se il metadata canonico e' gia' persistito nel run o dichiarato nel PATTERN_REGISTRY, UI/API/reports devono leggerlo da quella fonte esplicita e non ricalcolarlo localmente. P-14 Fail-closed sui metadata irrisolti - Se UI o API non riescono a determinare in modo affidabile un requisito canonico del run, il sistema deve fallire in modo esplicito. - E' vietato mostrare "NOT IN USE", abilitare submit o costruire payload incompleti quando il Pattern esiste ma i suoi metadata non sono stati risolti correttamente. - Meglio un errore esplicito di metadata non risolti che una UI apparentemente valida ma semanticamente falsa. ============================================================ 4) CONTRATTO DI BACKTEST (UI -> API -> RUNTIME) ============================================================ Un backtest ALGO e' definito almeno da: - exec_symbol - exec_tf - exec_dataset_id - period - params strategici - pattern_contexts Ogni pattern_context contiene almeno: - pattern_id - pattern_symbol - e uno fra: - datasets_by_tf - source_family Regole: - La UI/API non devono usare campi top-level legacy come pattern_timeframe o pattern_dataset_id. - pattern_contexts e' il contratto canonico del backtest per i contesti Pattern. - datasets_by_tf e' una dichiarazione esplicita di dataset per tf all'interno di un Pattern context. - source_family e' una dichiarazione strutturale che il runtime puo' usare per risolvere i dataset richiesti dalle Conditions del Pattern. - Il runtime deve risolvere automaticamente i dataset richiesti dalle Conditions del Pattern quando il context non li dichiara gia' tutti in modo esplicito. - Se manca anche uno solo dei dataset richiesti da un Pattern, il backtest deve fallire con errore esplicito. - La UI puo' abilitare o disabilitare i controlli del backtest solo sulla base di metadata canonici machine-readable affidabili. - Se i metadata necessari a determinare un pattern_context non sono risolti, la UI deve bloccare il submit e mostrare un errore esplicito di metadata canonici non risolti. ============================================================ 5) ARCHITETTURA END-TO-END ============================================================ 5.1 Data Layer - Espone datasets, prices, source families e contract_specs. - prices e' sempre legato a dataset_id. - Il DB deve permettere di risalire dalla Pattern Source Family ai dataset necessari per i tf richiesti. 5.2 UI Backtest - Mostra algoritmi, EXEC_TF disponibili e contesti Pattern coerenti con il contratto `pattern_contexts`. - Non usa campi legacy top-level per i Pattern. - Deve mostrare errori chiari se il contesto Pattern non copre tutti i tf richiesti dalle Conditions. - Quando mostra un run salvato, deve usare il `run_seq` persistito in DB come label umana coerente cross-page. 5.3 API / Backend - Riceve exec_tf, exec_dataset_id e pattern_contexts. - Valida coerenza symbol/dataset/source_family dei Pattern contexts. - Risolve i dataset effettivi richiesti dalle Conditions. - Non corregge silenziosamente payload incoerenti. - Deve persistere e restituire `run_id` e `run_seq` come identita' ufficiali del run. 5.4 Runtime / Engine - Carica df_exec dal dataset operativo selezionato. - Per ogni Pattern risolve i dataframe necessari alle sue Conditions partendo dalla Pattern Source Family. - Deve calcolare in modo esplicito il primo `EXEC close` disponibile e il `backtestable start` coerente con l'overlap fra dataset logici Pattern ed EXEC. - Deve rendere questo overlap disponibile al runtime/EA e al result payload come metadata di audit, cosi' il sistema non resta cieco sui tratti non ancora eseguibili. - Se il pattern range inizia prima del primo `EXEC close` disponibile, quel tratto iniziale e' bootstrap/range truncation, non un errore fatale del backtest. - Invoca l'EA con i contesti Pattern gia' risolti. - Non effettua fallback, alias o ricostruzioni implicite. 5.5 EA Layer - Usa df_exec e i contesti Pattern passati dal runtime. - Produce output B3-compatible. - Espone PATTERN_REGISTRY e ai_description. - Non calcola metriche CORE. 5.6 Validation Layer - Valida schema, coerenza numerica, registry, eventi, datetime e token timeframe. 5.7 CORE / Analytics - Usa solo trades validati. - Calcola holding time, equity, returns, metrics, drawdown. 5.8 UI / Audit Visualization - Il chart deve plottare il fenomeno nella sua posizione reale di start, non su una barra tecnica arbitraria di conferma. - Le viste testuali di audit possono mostrare sia start sia cert. - Se il run e' risolto da dati persistiti, resolved data wins. - La UI non deve reintrodurre fallback a sorgenti piu' deboli quando il dato risolto e' disponibile. - La UI non deve calcolare, inferire o rinumerare localmente il run quando `run_seq` persistito e' disponibile. - La UI non deve calcolare, inferire o rinumerare localmente il trade quando `trade_seq` persistito e' disponibile. - Reports/UI/API non devono ricalcolare pattern_tf o altri metadata Pattern se il run persistito li espone gia' nel PATTERN_REGISTRY; per run storici legacy e' ammessa solo una retrocompatibilita' report-only esplicita, senza promuovere i campi legacy a nuovo contratto canonico. - Se il timeframe corrente della chart e' piu' fine di EXEC_TF, la UI non deve fingere una precisione di fill superiore a quella reale del run. - La qualita' della visualizzazione dipende da una progettazione esplicita degli eventi gia' in fase di definizione dell'EA. - Prima dell'implementazione di un nuovo EA, ideatore e sviluppatore devono concordare quali Conditions / Patterns / Entries / Exits siano davvero utili da rappresentare in charttrade. - Sono vietati marker di chart aggiunti senza una semantica auditabile chiara oppure ancorati a punti che non rappresentano il fenomeno reale osservato. - Se il payload espone Logic Occurrences, la UI deve preferire quelle per spiegare nessi causali, anchor selezionati e occorrenze usate dal trade; non deve ricostruire silenziosamente questi legami da soli marker o da naming convenzionale. - Un Logic Indicator orientato all'audit utente non deve limitarsi a stati booleani quando la lettura causale richiede di distinguere occorrenze diverse della stessa entita' astratta. ============================================================ 6) ERROR SEMANTICS ============================================================ Il sistema deve fermarsi con errore esplicito quando: - exec_dataset_id e' mancante o incoerente - pattern_contexts e' mancante o incoerente quando richiesto dall'EA - manca uno dei dataset richiesti dalle Conditions di un Pattern - l'EA usa token timeframe non canonici - l'output EA viola B3/B6 Sono vietate le correzioni silenziose. ============================================================ 7) GOVERNANCE DOCUMENTALE ============================================================ - B2 contiene il glossario canonico e i principi di sistema. - B3 contiene la spec EA canonica. - B4 contiene le regole per scrivere/correggere EA. - B5 e' il template tecnico ufficiale. - B6 e' il validator ufficiale. - B7 e' la spec numerica del CORE. Regole: - Ogni modifica di naming o contratto richiede aggiornamento coerente di B2/B3/B4/B5/B6/B7/B8. - Se cambia il modello di sourcing Pattern o EXEC_TF, il primo documento da aggiornare e' B2. ============================================================ FINE B2 ============================================================