Files
TR_Agent/MQL5/Experts/MultiAgentTest/DOCUMENTAZIONE_COMPLETA.md
T

836 lines
32 KiB
Markdown
Raw Normal View History

# 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 + α × (xmean)²) (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