# Documentazione Completa — MultiAgent TR_Agent EA ## Indice 1. [MultiAgentTest.mq5](#1-multiagenttestmq5) 2. [Core/Orchestrator.mqh](#2-coreorchestratormqh) 3. [Core/NeuralNet.mqh](#3-coreneuralnetmqh) 4. [Core/Statistics.mqh](#4-corestatisticsmqh) 5. [Core/Signal.mqh](#5-coresignalmqh) 6. [Core/MarketData.mqh](#6-coremarketdatamqh) 7. [Core/PeriodCalculator.mqh](#7-coreperiodcalculatormqh) 8. [Agents/AgentBase.mqh](#8-agentsagentbasemqh) 9. [Agents/MAAgent.mqh](#9-agentsmaagentmqh) 10. [Agents/MomentumAgent.mqh](#10-agentsmomentumagentmqh) 11. [Agents/PatternHunter.mqh](#11-agentspatternhuntermqh) 12. [Agents/RegimeADX.mqh](#12-agentsregimeadxmqh) 13. [Agents/RegimeConsensus.mqh](#13-agentsregimeconsensusmqh) 14. [Agents/RegimeDetector.mqh](#14-agentsregimedetectormqh) --- ## 1. MultiAgentTest.mq5 ### Scopo Main EA file: punto d'ingresso di MetaTrader 5. Gestisce OnInit (setup), OnTick (per-barra), OnTrade (chiusure), e OnDeinit (salvataggio e report). ### Input Parameters - **Inp_Symbol**: Simbolo da tradare (vuoto = simbolo corrente) - **Inp_TF**: Timeframe di esecuzione (default = CURRENT = timeframe del chart) - Funziona su QUALSIASI timeframe (M1, M5, M15, M30, H1, H4, D1, W1, MN1) - I periodi degli agenti (Hurst, MA, Momentum, ADX) si adattano automaticamente - Il buffer dati scala con la barra: 300+ barre sono sempre sufficienti - L'unica differenza tra timeframes è la granularità degli ingressi - **Inp_Lot**: Lotto fisso (sostituito da AdaptiveBaseLot se >0) - **Inp_MinZ**: Soglia minima z-score per entrata (0=adattiva) - **Inp_WMin**: Peso minimo per agente (0=auto) - **Inp_BufferBars**: Barre nel buffer (0=auto) - **Inp_SLRiskATR**: SL fisso in ATR (0=adattivo) - **Inp_TPRiskATR**: TP fisso in ATR (0=adattivo) - **Inp_HurstPeriod, Inp_ADXPeriod**: Periodi fissi (0=auto) - **Inp_UseNeural**: True = neural orchestrator, False = softmax classico - **Inp_TrainMode**: Colleziona campioni e allena NN in backtest - **Inp_NNHidden**: Neuroni hidden layer - **Inp_RiskFraction**: Frazione di capitale da rischiare per trade (default 0.20 = 20%) - **Inp_UseReversalClose**: Se true, chiude posizioni quando il segnale si inverte. Se false, long e short coesistono ### OnInit 1. Legge parametri di mercato (spread, digits, punto) 2. Crea Orchestrator con gli input 3. Crea e registra 6 agenti: RegimeDetector (Hurst), RegimeADX, RegimeConsensus, MAAgent, MomentumAgent, PatternHunter 4. Verifica buffer dati sufficiente 5. Carica modello NN esistente (se Inp_UseNeural) ### OnTick - Lavora su **new bar** (compare i tempi) - Prepara MarketData (prezzi, indicatori) - Chiama `orchestrator.Analyze(data)` per z-score combinato - Ottiene FinalSignal da GetFinalSignal() - Chiama `ManagePositions(data, fs)` per apertura/chiusura - Trailing stop su tutte le posizioni ### OnTrade - Rileva trade chiusi da SL/TP (non da reversal) - Calcola il ritorno in ATR - Chiama `orchestrator.OnTradeClose()` che: - Aggiorna MAE/MFE stats - Colleziona campione NN con peso = |return| + 1 - Chiama agente Learn() con ritorno normalizzato - Aggiorna health (Sharpe rolling) - Salva stato ogni saveInterval trade ### ManagePositions 1. Update MAE/MFE per tutti gli aperti (intra-barra high/low) 2. TrailStops: muove SL su tutte le posizioni 3. Chiudi posizioni con segnale invertito (reversal) 4. Aggiorna SL sul terminale via PositionModify 5. Apri nuova posizione OGNI BARRA con |z| > minZ (aggressivo multi-position) - SL width da AdaptiveSLWidth (MAE-based con EVT fallback) - Lotto = AdaptiveBaseLot × |z| (scalato dal segnale) - Nessun TP fisso: uscita via trailing stop o reversal ### OnDeinit - Salva: stato agenti, correlazioni, RunningStats, NN (inline) - Stampa report: PrintAgentStats, PrintNeuralStats, loss history CSV - Aggiorna summary ### Principi Chiave - **Multi-position**: ogni barra con segnale apre UNA NUOVA posizione - **Nessun TP fisso**: uscita via reversal o trailing stop - **SL adattivo**: da distribuzione MAE dei trade vincenti - **Training online**: campioni collezionati in backtest, NN allenata in OnDeinit --- ## 2. Core/Orchestrator.mqh ### Scopo Cervello del sistema: orchestrazione agenti, combinazione z-score, gestione multi-position, trailing stop, training NN, stato persistente. ### Strutture Dati **TrackedTrade**: traccia ogni posizione aperta: - ticket, entryPrice, entryATR, entryZ, slPrice, isBuy - highestPrice, lowestPrice (per MAE/MFE tracking) - maeATR, mfeATR (massimo movimento avverso/favorevole in ATR) - barsHeld, active - entryFeatures[NN_FEATURES] (per training NN) - entryZScores[MAX_AGENTS] (per agent learning) **BarSnapshot**: cache storica per autocorrelazione: - combinedZ, timestamp ### Membri Principali - `agents[MAX_AGENTS]`: array di IAgent* - `combinedZ`: z-score combinato pesato - `agentWeights[MAX_AGENTS]`: pesi EWMA basati su correlazione - `corrMeanX/Y, corrCov, corrVarX/Y`: RunningCorrelation per coppia agente-combinedZ - `returnStats, combinedZStats, maeStats, mfeStats, maeWinStats`: distribuzioni empiriche - `openTrades[maxOpenTrades]`: tutte le posizioni aperte - `m_neuralNet, m_trainBuffer`: rete neurale e buffer training - `m_riskFraction`: frazione di capitale da rischiare (default 20%) - `rollingReturns[ROLLING_TRADES]`: per Sharpe rolling ### Metodi Principali **AddAgent**: registra agente, inizializza correlazioni, ri-inizializza RunningStats con alpha/min derivati da agentCount. **Analyze** (fase 1-3): 1. **Aggrega**: raccoglie z-score da tutti gli agenti 2. **Interact**: agenti leggono z-score altrui (via SHARED_) 3. **Combina**: pesi EWMA basati su correlazione agente-combinedZ, softmax con temperatura adattiva (o NN) **OnTradeOpen**: registra nuova posizione in openTracks[], copia entryZScores ed entryFeatures **OnTradeClose**: - Calcola ritorno in ATR - Aggiorna MAE/MFE stats - Colleziona training sample NN con peso = |return| + 1 - Chiama agent.Learn() per auto-calibrazione - Aggiorna rolling Sharpe - Salva stato ogni saveInterval **UpdateOpenTrades**: per ogni barra, aggiorna MAE/MFE da high/low **TrailStops**: implementa trailing stop: - Calcola trail trigger da MFE mean (o EVT fallback) - Calcola trail offset da MAE win mean (o EVT fallback) - Se profitto > trigger, muove SL a entry ± (profitto - offset) **AdaptiveSLWidth**: SL width da MAE distribuzione: - Fallback: combinedZStats.Std() × sqrt(N) o EVT_SL - Con dati: max(fallback, maeWinStats.Mean() + maeWinStats.Std()) **AdaptiveTrailTrigger**: da MFE mean (o EVT) **AdaptiveTrailOffset**: da MAE win mean (o EVT) **AdaptiveMinZ**: soglia entrata = StdErr(combinedZ) = Std/sqrt(N) — bassa per trading frequente **AdaptiveBaseLot**: lotto = balance × riskFraction / 100000 — chiamante scala per |z| **GetTradesToClose**: reversal detection: buy chiusi se currentZ < -minZ, sell se > minZ **SaveState / LoadState (v6)**: - Salva: versione, agenti (pesi, bias, predError, predCorr, lastZScore), correlazioni, RunningStats, NN - NN salvato inline (handle file embedded) - Carica: stessi campi, ripristino buffer NN **TrainNN**: allena CNeuralNet con buffer campioni, pesi per sample importance **InitNeuralNet**: configura architettura NN, inizializza He con iperparametri derivati: - dropout = 1/sqrt(hidden) - L2 = 1/max(totalParams, 100) - β₁ = 1 − 1/max(hidden, 10) - β₂ = 1 − 1/max(hidden×100, 1000) - BN momentum = 1 − 1/max(hidden×5, 50) - BN ε = DATA_EPS(1.0) ### Principi Chiave - **Zero magic constants**: ogni soglia derivata da distribuzioni empiriche o EVT - **Multi-position aggressivo**: ogni barra con segnale apre posizione - **Trailing stop adattivo**: MAE/MFE guidano trigger e offset - **NN opzionale**: cade a softmax se non inizializzata - **Persistenza**: tutto (incluso NN) salvato inline in file stato --- ## 3. Core/NeuralNet.mqh ### Scopo Rete neurale feed-forward: 1 hidden layer ReLU, dropout, BatchNorm, Softmax output, Adam optimizer. Training online con batch_size=1 per compatibilità MT5. ### Architettura - Input → W1 (fanIn×hidden) + b1 → ReLU → Dropout → BatchNorm → W2 (hidden×3) + b2 → Softmax - Output: [P(Buy), P(Flat), P(Sell)] - Hidden size: input Inp_NNHidden (default 6) ### CNeuralNet **Inizializzazione**: He Init `sqrt(6/fanIn)` per ReLU. **Forward**: 1. z1 = W1×x + b1 → ReLU(z1) → h1 2. Dropout: mask binaria con probabilità 1-dropoutRate 3. BatchNorm (train): EMA runningMean/runningVar, gamma/beta learnable 4. z2 = W2×h1_norm + b2 → Softmax → output [0,1]³ **Loss**: CCE (Cross-Entropy) pesata + L2: - L = -Σ weight × target_i × log(p_i) + 0.5×L2×(∥W1∥² + ∥W2∥²) **Backward (Adam)**: - dL/dz2 = weight × (output − target) (CCE+Softmax combinata) - dL/dW2 = h1_normᵀ × dL/dz2 - dL/dh1_norm = W2 × dL/dz2 - BNBackward: dL/dh1_drop = gamma/sqrt(var) × dL/dh1_norm - Dropout backward: passa gradiente solo dove mask=1 - dL/dz1 = dL/dh1_raw ⊙ ReLU'(z1) - dL/dW1 = xᵀ × dL/dz1 - Adam update per W1, b1, W2, b2, bnGamma, bnBeta **Iperparametri architettura-derivati** (zero magic constants): - dropout = 1/sqrt(hidden) - L2 = 1/max(totalParams, 100) - β₁ = 1 − 1/max(hidden, 10) - β₂ = 1 − 1/max(hidden×100, 1000) - ε = DATA_EPS(1.0) - BN momentum = 1 − 1/max(hidden×5, 50) - BN ε = DATA_EPS(1.0) **Save/Load v3**: pesi salvati in formato binario compatto, inline nello stato. **LossHistory**: array epoch-loss, dump CSV. ### NNTrainBuffer Buffer circolare di campioni per training NN. **Struttura**: NNTrainSample { features[8], target[3], weight }. **Metodi**: - Add(features, target, weight): aggiunge campione - Trim(maxSamples): rimuove i più vecchi - ToMatrices(features, targets): esporta per training - GetWeights(): vettore dei pesi campione - SaveCsv(filename): dump per debug - PrintStats/PrintFeatureStats: diagnostica dataset ### Principi Chiave - **Batch size = 1**: forzato da MT5, BN usa running stats non batch stats - **Loss pesata**: trade con grande impatto pesano di più nel training - **Inline nel file stato**: NN salvato dentro .model per portabilità tester→live - **Zero magic**: dropout, L2, β₁, β₂, ε, BN momentum/ε tutti derivati --- ## 4. Core/Statistics.mqh ### Scopo Statistiche in tempo reale: EWMA, RunningStats (media/variance online), RunningCorrelation, DATA_EPS. ### DATA_EPS(x) - `MathMax(MathSqrt(DBL_EPS), MathAbs(x) * MathSqrt(DBL_EPS))` - Soglia floating-point di qualità: scala con la magnitudine dei dati - Radice quadrata del DBL_EPS standard (≈1.49e-8), non epsilon assoluto 1e-15 ### EWMA EWMA univariato con fattore α: - mean += α × (x − mean) - var = (1−α) × (var + α × (x−mean)²) (metodo di Finch) ### RunningStats Media e varianza online con EWMA: - alpha = 1/(N_agenti × 10), minSamples = N_agenti × 5 - Count(), Mean(), Std(), Var(), Skew() - Ready(): count >= minSamples - Save/Load: formato binario ### RunningCorrelation Correlazione online tra due variabili: - Stessa logica EWMA di RunningStats - Update(x, y), Correlation(), Count(), Ready() - Utilizzata per: correlazione agente-combinedZ, weight update ### Funzioni EVT - `EVT_MaxAbsZ(N) = sqrt(2 × log(2 × N))`: expected maximum |z| di N gaussiane - `RStatsAlpha() = 1.0 / max(agentCount × 10, 10)` - `RStatsMinSamp() = max(agentCount × 5, 10)` ### Principi Chiave - **Online**: tutte le statistiche sono incrementali, nessun buffer storico - **EWMA**: pesa più i dati recenti - **DATA_EPS**: soglia scalabile, non epsilon assoluto - **EVT**: Extreme Value Theory per fallback senza dati --- ## 5. Core/Signal.mqh ### Scopo Strutture dati di segnale e stato. ### FinalSignal Rappresenta il segnale finale dopo orchestrazione: - direction: +1 (Buy), -1 (Sell), 0 (Flat) - zScore: z-score combinato (firmato) - totalAgents: numero agenti attivi - agreeingCount: quanti agenti concordano con direzione - contributingAgents: stringa nomi agenti concordanti ### TrackedTrade Rappresenta una posizione aperta tracciata: - ticket, entryPrice, entryATR, entryZ, slPrice, isBuy - highestPrice, lowestPrice: per MAE/MFE intra-barra - maeATR, mfeATR: massimo movimento avverso/favorevole in ATR - barsHeld: barre da apertura - active: true se posizione ancora aperta - entryFeatures[8]: feature snapshot all'apertura (per NN) - entryZScores[MAX_AGENTS]: z-score agenti all'apertura (per learning) ### BarSnapshot - combinedZ, timestamp: per calcolo autocorrelazione ### Principi Chiave - **TrackedTrade è auto-contenuta**: porta tutto ciò che serve per learning e training - **Multi-position**: array di TrackedTrade fino a maxOpenTrades --- ## 6. Core/MarketData.mqh ### Scopo Fornitore dati di mercato: prezzi, spread, indicatori nativi MT5. ### MarketData - Symbol() / Timeframe() - High(shift), Low(shift), Close(shift), Open(shift) - Spread(): spread corrente in punti - ATR(period): iATR nativo - ATR(period, shift): iATR con shift - Ma(period, shift, method, applied): iMA nativo - Momentum(period, shift): iMomentum nativo - ADX(period, shift): iADX nativo (Main, PlusDI, MinusDI) ### Principi Chiave - **Indicatori nativi MT5**: iMA, iATR, iMomentum, iADX — nessuna implementazione custom - **Cache**: i valori sono calcolati su richiesta con handle MT5 - **ATR period derivato**: max(N+1, min(buffer/15, 50)) — scala con agenti e buffer --- ## 7. Core/PeriodCalculator.mqh ### Scopo Calcolo dei periodi adattivi per ogni agente. ### Funzioni - `HurstPeriod(bufferBars, hurstPeriodInput)`: periodo per calcolo Hurst - `ADXPeriod(bufferBars, adxPeriodInput)`: periodo per ADX - `MAPeriod(bufferBars, ...)`: periodo per MA - `MomentumPeriod(bufferBars, ...)`: periodo per Momentum Ogni funzione: - Se input > 0: usa input fisso - Se input = 0: calcola da bufferBars usando formula adattiva --- ## 8. Agents/AgentBase.mqh ### Scopo Classe base astratta per tutti gli agenti. Definisce interfaccia, stato persistente, meccanismi di calibrazione. ### IAgent (interfaccia) ``` virtual void Analyze(MarketData&) = 0; virtual void Learn(double actualReturn) = 0; virtual double GetZScore() = 0; ``` ### Membro - name, enabled, weight, lastZScore - predictionError: RunningStats dell'errore di predizione (bias) - predCorr: RunningCorrelation tra predetto e reale - combinedZStats: RunningStats locale per normalizzare z-score ### AgentBase (implementazione parziale) **CalibrateZ(z)**: normalizza z-score usando combinedZStats locale: - Se ha dati: z_score = (z − mean) / std - Se non ha dati: z_score = z / EVT_MaxAbsZ(max(2N, 2)) **Learn(actualReturn, subSignals)**: - Calcola predictionError: differenza tra lastZScore e actualReturn normalizzato - Aggiorna predCorr: correla lastZScore con actualReturn - Tutti gli agenti ereditano questo comportamento **Save/Load v3**: salva nome, peso, lastZScore, predictionError, predCorr, combinedZStats. ### Principi Chiave - **Auto-calibrazione**: ogni agente normalizza i propri z-score - **Autovalutazione**: predictionError (bias) + predCorr (allineamento direzionale) - **Zero magic**: fallback EVT per normalizzazione --- ## 9. Agents/MAAgent.mqh ### Scopo Agente Moving Average: confronta prezzo corrente con MA per generare z-score. ### Funzionamento 1. Calcola MA a periodo adattivo (iMA nativo) 2. Prezzo relativo: (close − MA) / ATR 3. Normalizza via CalibrateZ() per produrre z-score ~N(0,1) 4. Learn(): traccia sub-signals priceToMaCorr e slopeCorr ### Sub-signals - priceToMaCorr: RunningCorrelation tra (close-MA)/ATR e ritorno - slopeCorr: RunningCorrelation tra pendenza MA e ritorno ### Output - Z-score positivo: prezzo sopra MA (trend rialzista) - Z-score negativo: prezzo sotto MA (trend ribassista) - Segnale tanto più forte quanto più il prezzo è lontano dalla MA (in ATR) ### Principi Chiave - **MA period adattivo**: da PeriodCalculator - **Unità ATR**: normalizza la distanza prezzo-MA in termini di volatilità - **Auto-calibrazione**: CalibrateZ mantiene output ~N(0,1) - **Apprendimento**: traccia correlazione sub-signals per miglioramento --- ## 10. Agents/MomentumAgent.mqh ### Scopo Agente Momentum: cattura accelerazione del prezzo via iMomentum nativo. ### Funzionamento 1. Calcola Momentum = iMomentum(period) = close − close[period-1] 2. Momento normalizzato: momentum / ATR (in unità di volatilità) 3. Seconde differenze per accelerazione: momentum − momentum[shift] 4. Combina momentum + accel con RunningStats pesato 5. CalibrateZ() per z-score finale ### Sub-signals - momCorr: RunningCorrelation tra momentum e ritorno - accelCorr: RunningCorrelation tra accelerazione e ritorno ### Output - Z-score positivo: momentum positivo (trend in accelerazione) - Z-score negativo: momentum negativo - Pesa accelerazione quando ha alta correlazione col ritorno ### Principi Chiave - **iMomentum nativo MT5**: no implementazione custom - **Doppio segnale**: momentum + accelerazione - **Adattivo**: peso accelerazione basato su correlazione storica --- ## 11. Agents/PatternHunter.mqh ### Scopo Agente di pattern recognition cross-agente: identifica pattern negli z-score degli altri agenti. ### Funzionamento 1. Analizza z-score di tutti gli agenti (da SHARED_ variabili) 2. Classifica pattern in codici -10..+10: - Pattern di accordo: tutti concordi (z-std basso) - Pattern di divergenza: agenti divisi (z-std alto) - Pattern di reversal: cambio direzione rispetto a barra precedente - Pattern di momentum: accelerazione/decelerazione 3. Ogni pattern code ha RunningStats locale (patternStats[code+10]) 4. Z-score = winRate del pattern corrente (CalibrateZ normalizza) ### Learn() - patternStats[patternCode+10] aggiornato con esito trade - Traccia win rate per ogni pattern ### Output - Timeframe lungo: convergenza/dominanza di certi pattern - Z-score positivo: pattern storicamente vincente per Buy - Z-score negativo: pattern storicamente vincente per Sell ### Principi Chiave - **Cross-agente**: non guarda il prezzo ma il comportamento degli altri agenti - **Pattern statistics**: ogni pattern ha RunningStats di performance - **Auto-apprendimento**: più trade → migliori stime win rate per pattern --- ## 12. Agents/RegimeADX.mqh ### Scopo Agente di regime basato su ADX: rileva trend vs range tramite iADX nativo. ### Funzionamento 1. iADX(period, shift): ADX Main, +DI, -DI 2. Regime score = (+DI − -DI) / ADX_Main (direzione normalizzata per forza trend) 3. CalibrateZ() per output ~N(0,1) ### Output - Z-score positivo: +DI > -DI → trend rialzista - Z-score negativo: -DI > +DI → trend ribassista - Magnitudo: forza del trend (ADX alto) + direzionalità ### Principi Chiave - **iADX nativo MT5**: no implementazione custom - **Unità di forza trend**: regime score normalizzato da ADX - **Risposta rapida**: reagisce a cambiamenti di regime DI --- ## 13. Agents/RegimeConsensus.mqh ### Scopo Agente di consenso: combina Hurst + ADX per determinazione robusta del regime. ### Funzionamento 1. Legge Hurst da RegimeDetector (via SHARED_) 2. Legge ADX da RegimeADX (via SHARED_) 3. Consensus score = peso × Hurst + (1-peso) × ADX 4. Peso da RunningStats della correlazione di ciascuno col ritorno 5. CalibrateZ() per output finale ### Learn() - Sub-signals: hurstCorr (corr Hurst-ritorno), adxCorr (corr ADX-ritorno) - Aggiorna pesi basati su correlazione storica ### Output - Z-score positivo: regime identificato come trend rialzista - Z-score negativo: regime trend ribassista - Zero: regime incerto (Hurst range-bound + ADX basso) ### Principi Chiave - **Consenso multi-regime**: Hurst + ADX complementari - **Pesi adattivi**: aggiornati via Learn() basato su performance - **Stabilità**: consenso filtra falsi segnali di un singolo regime detector --- ## 14. Agents/RegimeDetector.mqh ### Scopo Agente di detection basato su Hurst Exponent: misura tendenza al trend/mean-reversion del mercato. ### Funzionamento 1. Hurst via DFA (Detrended Fluctuation Analysis) con fallback R/S 2. Hurst = 0.5 → random walk 3. Hurst > 0.5 → trending (buy quando close sopra MA, sell sotto) 4. Hurst < 0.5 → mean-reverting (buy quando close sotto MA, sell sopra) 5. Z-score = (Hurst - 0.5) × factor × (close-MA)/ATR 6. CalibrateZ() per output finale ### DFA Algorithm 1. Prezzo logaritmico: y_i = log(close_i) 2. Trend locale: sottrai media su finestra mobile 3. Fluttuazione: RMS dei residui 4. Hurst = log(F(n) / F(n/2)) / log(2) ### Fallback R/S - Se DFA fallisce (dati insufficienti): R/S classico - Range = max(cumsum) − min(cumsum) - R/S = range / std dei log-returns ### Output - Z-score positivo: mercato trending rialzista - Z-score negativo: mercato trending ribassista - Magnitudo: forza del fenomeno (quanto Hurst si discosta da 0.5 × forza trend) ### Principi Chiave - **Implementazione manuale**: nessun indicatore nativo (Hurst non esiste in MT5) - **DFA primario, R/S fallback**: robustezza - **Direzionalità**: combina Hurst con posizione prezzo-MA - **Lento ma fondamentale**: identifica regime macro, non trading frequency --- ## Filosofia Generale del Sistema ### Multi-Agente con Orchestrazione Neurale 6 agenti specializzati producono z-score normalizzati ~N(0,1). L'orchestratore combina: - Classic: pesi EWMA basati su correlazione storica + softmax con temperatura adattiva - Neural: CNeuralNet che impara la combinazione non-lineare ottimale ### Zero Magic Constants Ogni numero nel sistema è derivato da: - **Distribuzioni empiriche**: RunningStats di MAE/MFE/ritorni - **EVT (Extreme Value Theory)**: fallback senza dati per SL, trigger, offset - **Architettura NN**: dropout, L2, β₁, β₂, ε da hidden size - **Floating-point standard**: sqrt(DBL_EPS) per soglie numeriche - **Statistica classica**: StdErr, correlazioni, Student-t ### Multi-Position Aggressivo - Ogni barra con segnale apre nuova posizione - 20% di capitale per trade (configurabile) - Nessun TP fisso: trailing stop adattivo da MFE/MAE - SL width da MAE dei trade vincenti ### Apprendimento Continuo - Agenti: CalibrateZ() + Learn() con bias/correlation tracking - NN: training supervisionato con campioni pesati per importanza - Stato: tutto salvato inline (incluso NN) per portabilità tester→live --- ## 15. Trade Entry / Exit Logic ### Come Entra a Mercato L'entry avviene in `ManagePositions()` in MultiAgentTest.mq5, **ogni barra** con segnale actionable: 1. **Nuova barra rilevata** in OnTick → chiama `orchestrator.Analyze(data)` per produrre `combinedZ` 2. **GetFinalSignal()** produce `FinalSignal { direction, zScore, ... }` 3. **Controllo soglia**: se `|zScore| > minZ` (dove `minZ = AdaptiveMinZ()`), si procede 4. **Calcolo SL**: `SL = price ± atr × slWidth` dove `slWidth = AdaptiveSLWidth()` 5. **Calcolo lotto**: `lot = AdaptiveBaseLot() × |zScore|` - `AdaptiveBaseLot() = balance × riskFraction / 100000` - Con riskFraction = 0.20 (20%): per $10k → lotto base 0.20 × z 6. **Chiamata MT5**: `trade.Buy(lot, sym, ask, sl, 0)` o `trade.Sell(lot, sym, bid, sl, 0)` - TP = 0: nessun take profit fisso, l'uscita è gestita da trailing stop o reversal 7. **Tracciamento**: `orchestrator.OnTradeOpen(ticket, price, atr)` salva la posizione in `openTrades[]` ### Frequenza di Entry (Multi-Position) - **Ogni barra** con segnale apre UNA NUOVA posizione, indipendentemente da quante sono già aperte - **Solo il margine libero** limita il numero di posizioni: se `marginReq ≥ freeMargin`, il trade è saltato - Nessun limite artificiale: l'array `openTrades[]` cresce dinamicamente (`EnsureTradeCapacity`) - Con `AdaptiveMinZ = Std/sqrt(N)` (~0.16 con 6 agenti), la soglia è molto bassa → molte entrate - Il sistema può gestire centinaia di posizioni contemporanee se il margine lo permette ### Come Esce a Mercato Ci sono **tre modi** per chiudere una posizione: **A) Reversal (chiusura attiva) — OPZIONALE** - Controllato da `Inp_UseReversalClose` (default: true) - Se **true**: in `ManagePositions()`, dopo aver calcolato il nuovo segnale: - `GetTradesToClose()` ritorna i ticket delle posizioni con direzione opposta al segnale corrente - BUY chiusi se `currentZ < -minZ`, SELL chiusi se `currentZ > minZ` - Chiamata: `OnTradeClose(tkt, closePrice)` + `trade.PositionClose(tkt)` - Se **false**: le posizioni NON vengono mai chiuse per reversal. Ogni barra apre UNA NUOVA posizione nella direzione del segnale, e le posizioni esistenti rimangono aperte. Questo permette: - **Long e short simultanei**: il sistema può tenere posizioni in entrambe le direzioni - **Massimizzazione del profitto**: non taglia le posizioni che potrebbero ancora essere redditizie - **Uscita solo via trailing stop o SL**: nessuna chiusura "forzata" dal segnale - Attenzione: il rischio aumenta perché le posizioni opposte si compensano parzialmente **B) Trailing Stop (chiusura automatica)** - In `TrailStops()`, chiamato ogni barra: 1. Calcola **trail trigger**: da `AdaptiveTrailTrigger()` = MFE medio o EVT fallback 2. Calcola **trail offset**: da `AdaptiveTrailOffset()` = MAE medio dei vincenti o EVT fallback 3. Se il profitto corrente > trail trigger (in ATR): - BUY: `newSL = entryPrice + (highestPrice - entryPrice) - offset` - SELL: `newSL = entryPrice - (entryPrice - lowestPrice) + offset` 4. Se il nuovo SL è più stretto del precedente, viene aggiornato via `PositionModify(tkt, newSL, curTP)` - Il trailing stop si attiva SOLO dopo che il prezzo ha superato il tipico MFE **C) SL/TP iniziale (broker-side)** - All'apertura, ogni posizione ha uno stop loss (SL = price ± atr × slWidth) - Se il mercato va contro la posizione, lo SL iniziale ferma la perdita - La chiusura da SL/TP è rilevata in `OnTrade()`: se un ticket tracciato non è più in `PositionsTotal()`, viene chiamato `OnTradeClose()` - Il trailing stop può spostare lo SL per proteggere i profitti, ma non lo allarga mai ### Numero di Ordini - **Entrate**: 1 posizione per barra con segnale (potenzialmente centinaia al giorno su M1) - **Uscite**: 1 chiusura per posizione (via reversal, trailing, o SL) - **Modifiche**: 1 modifica per barra per posizione (trailing SL via PositionModify) - **Totale ordini**: dipende dalla frequenza dei segnali × numero posizioni aperte - In backtest su H1 con 6 agenti: tipicamente 50-200 trade/mese, ma con entry aggressive può essere molto di più --- ## 16. Risk Management ### Dimensionamento Posizione Il rischio per trade è controllato da due livelli: **Livello 1: Frazione di Capitale (`Inp_RiskFraction`)** - Default: 0.20 (20% del capitale per trade) - `lotto = balance × riskFraction / 100000 × |z|` - Esempio: $10,000 × 0.20 / 100000 × |z=1.0| = 0.02 lotti (= 2,000 unità EURUSD) - Il `|z|` scala il lotto in base alla forza del segnale (|z|=2 → lotto doppio) **Livello 2: Stop Loss Iniziale** - `SL = prezzo ± atr × slWidth` - `slWidth = AdaptiveSLWidth()`: usa MAE dei trade vincenti (o EVT fallback) - Maggiore slWidth → stop più largo → maggiore rischio per trade - Il trailing stop protegge ulteriormente spostando lo SL in profitto **Livello 3: Margine** - Controllo esplicito: `if(marginReq ≥ freeMargin) return` - Se non c'è abbastanza margine per il lotto calcolato, il trade è saltato - Questo è l'UNICO limite reale al numero di posizioni ### Distribuzione del Rischio (Multi-Position) Con multi-position: - Ogni posizione ha rischio individuale = `balance × riskFraction × |z| / 100000` - Con 10 posizioni contemporanee: rischio totale = 10 × 0.20 × |z_medio| / 100000 × balance - Il rischio totale è proporzionale a: `Σ|z_i| × riskFraction × balance / 100000` - La diversificazione tra N posizioni riduce il rischio specifico di ogni entry ### Drawdown Control Il sistema non ha un hard stop sul drawdown (per scelta: l'utente vuole trading aggressivo). Tuttavia: - Il trailing stop limita le perdite di ogni singola posizione - La distribuzione MAE dei vincenti guida la larghezza dello SL - Il `rollingSharpe` negativo è segnalato ma non blocca il trading --- ## 17. Manual Override System Anche se il sistema è progettato per essere "zero magic constants" con tutti i valori derivati dai dati, puoi **sovrascrivere manualmente** qualsiasi parametro tramite gli **input dell'EA**: ### Cosa si può sovrascrivere | Input | Default | Descrizione | |-------|---------|-------------| | `Inp_MinZ` | 0.0 (auto) | Soglia minima z-score. Se >0, ignora `AdaptiveMinZ()` | | `Inp_WMin` | 0.0 (auto) | Peso minimo per agente. Se >0, ignora `1/(N×sqrt(N))` | | `Inp_SLRiskATR` | 0.0 (auto) | SL fisso in ATR. Se >0, ignora `AdaptiveSLWidth()` | | `Inp_TPRiskATR` | 0.0 (auto) | TP fisso in ATR. (TP=0 = trailing stop puro) | | `Inp_HurstPeriod` | 0 (auto) | Periodo Hurst fisso. Se >0, ignora calcolo adattivo | | `Inp_ADXPeriod` | 0 (auto) | Periodo ADX fisso. Se >0, ignora calcolo adattivo | | `Inp_Lot` | 0.01 | Lotto fisso. Sostituisce `AdaptiveBaseLot()` se >0 | | `Inp_BufferBars` | 0 (auto) | Numero barre buffer. Se 0: `max(300, HurstPeriod×10)` | | `Inp_RiskFraction` | 0.20 | Frazione di capitale per trade. Puoi abbassare (0.05=5%) o alzare (0.50=50%) | | `Inp_UseNeural` | false | True = neural orchestrator, False = softmax classico | | `Inp_TrainMode` | false | Colleziona campioni e allena NN in backtest | | `Inp_NNHidden` | 6 | Neuroni hidden layer della NN | | `Inp_UseReversalClose` | true | true=chiudi su segnale opposto, false=long+short coesistono | ### Come funziona l'override Nel codice, ogni input segue il pattern: ```mql // Se input > 0, usa input. Se = 0, usa valore adattivo double minZ = (Inp_MinZ > 0) ? Inp_MinZ : orchestrator.AdaptiveMinZ(); ``` Oppure per parametri non-zero: ```mql // NN: se passato >= 0, override if(l2 >= 0) m_l2 = l2; if(dropoutRate >= 0) m_dropoutRate = dropoutRate; ``` ### Esempi Pratici **Scenario conservativo**: `Inp_RiskFraction=0.05, Inp_MinZ=1.0` - Rischia 5% per trade, soglia alta → pochi trade selezionati **Scenario aggressivo**: `Inp_RiskFraction=0.50, Inp_MinZ=0` - Rischia 50% per trade, soglia adattiva bassa → trade frequenti e grandi **Scenario fisso**: `Inp_SLRiskATR=2.0, Inp_Lot=0.10` - SL sempre a 2 ATR, lotto fisso 0.10 — nessun adattamento ### Cosa NON si può sovrascrivere (rimane data-driven) - RunningStats alpha/min: derivati da N agenti - NN iperparametri: dropout, L2, β₁, β₂, ε — derivati dall'architettura - MAE/MFE distribuzioni: sempre empiriche - EVT fallback: solo quando non ci sono dati - Correlazioni e pesi: sempre empirici --- ## 18. Dati Salvati per Analisi Periodica Alla fine del backtest (`OnDeinit`), il sistema salva MOLTEPLICI file per analisi approfondita: ### File Salvati | File | Contenuto | Cartella | |------|-----------|----------| | `TR_Agent_Analysis_SYMBOL_TF.csv` | **TUTTI** i parametri derivati, soglie, periodi, stats | `Common` | | `TR_Agent_NN_v1.dat` | Modello NN con pesi inline | `Common` | | `NN_TrainingSamples_SYMBOL_TF.csv` | Campioni di training (8 feature + target) | `Common` | | `NN_LossHistory_SYMBOL_TF.csv` | Loss per epoca di training | `Common` | | `AgentLearning_SYMBOL_TF.csv` | Bias, correlazioni, errori per ogni agente | `Common` | ### Contenuto del CSV di Analisi (`SaveAnalysisCSV`) Il file `TR_Agent_Analysis_SYMBOL_TF.csv` contiene TUTTO: **Sezione 1: Trade Statistics** - TotalTrades, WinCount, WinRate, MaxDrawdown, RollingSharpe - ReturnMean, ReturnStd, ReturnCount - CombinedZMean, CombinedZStd, CombinedZCount **Sezione 2: MAE/MFE Distributions** - MAE_Mean, MAE_Std (massimo movimento avverso) - MFE_Mean, MFE_Std (massimo movimento favorevole) - MAE_Win_Mean, MAE_Win_Std (MAE dei soli vincenti) **Sezione 3: Derived Thresholds** - MinZ (soglia di entrata usata) - SLWidth (larghezza SL in ATR) - TrailTrigger (quando si attiva il trailing) - TrailOffset (quanto si arretra lo SL) - BaseLot (lotto base calcolato) - CorrMinSamples, WeightMin, WeightAlpha - EVT_MaxAbsZ **Sezione 4: Agent Details** - Per ogni agente: Name, Weight, Rho (correlazione), LastZ, Bias, BiasN, RhoLearn, RhoLearnN **Sezione 5: Neural Network** - NN_Epochs, NN_Loss, NN_Arch, NN_LR **Sezione 6: Input Parameters** (per poter replicare il backtest) - Tutti gli Inp_ parametri come sono stati usati ### Periodicità del Salvataggio - **Stato modello**: salvato ogni `saveInterval = N × 5` trade chiusi da SL/TP - **Analisi CSV**: salvata UNA volta in `OnDeinit` - **Agent Learning CSV**: salvato UNA volta in `OnDeinit` - **NN auto-save**: ogni 50 campioni durante il training (se TrainMode) - **NN Loss CSV**: salvato dopo ogni training in `OnDeinit` ### Come Usare i CSV per Analisi 1. **Dopo backtest**: apri `Common\TR_Agent_Analysis_SYMBOL_TF.csv` in Excel/Google Sheets 2. Controlla: Sharpe, Win Rate, Max Drawdown, MAE/MFE 3. Confronta soglie derivate tra backtest diversi per vedere l'evoluzione 4. Usa `NN_TrainingSamples_SYMBOL_TF.csv` per analizzare la distribuzione delle feature 5. Confronta `NN_LossHistory` per verificare che la loss scenda durante il training 6. Porta il `.dat` in live e ricarica lo stato esattamente com'era in backtest