- GateManager: 8 gates with learning-based threshold adjustment
- LearningBridge: Bidirectional data flow between Paper/Live, CSignalDecision records
- StrategySelector: Performance-based strategy scoring with recency weighting
- InsightsRebuild.mq5: One-click insights.json generation from features.csv
- Test suite: 8 test files for integration, gates, managers, system health
### 🔄 Implemented with Minor Gaps
2026-02-05 01:22:42 -05:00
- **Insights auto-reload**: LiveEA watches for `insights.reload` request and polls for `insights.ready` to auto-reload. PaperEA's `CheckInsightsReload()` exists but only deletes the file (rebuild logic commented out).
ShutdownP0P5Systems(); // Clean shutdown of all P0-P5 components
```
**Key Design Decisions**:
- Risk gates (G1, G4, G7, G8) are never skipped under CPU pressure
- Multi-symbol management remains chart-per-symbol with Redis coordination
- SQLite runs parallel to CSV for 30-day migration period
- All P0-P5 features have enable/disable input parameters for gradual rollout
## <20>🔧 Unified System Architecture (NEW)
2025-09-24 17:59:15 -04:00
The DualEA system features a **Unified Architecture** that eliminates redundancy by consolidating insights management and gating pipeline into three core components:
**Core Components:**
- **ConfigManager**: Centralized configuration for gates, insights, and system settings
- **EventBus**: Cross-component communication with priority-based event logging
- **SystemMonitor**: Real-time health monitoring and performance metrics
**Key Benefits:**
- Single source of truth for configuration and monitoring
- Event-driven architecture with unified logging
- Real-time performance tracking and health scoring
- Backward compatibility with legacy mode support
**Quick Start:**
```cpp
// Initialize unified system (enabled by default)
CGateManager* gateManager = new CGateManager(symbol, timeframe, learning, true);
// Access unified components for advanced configuration
- Position and risk: `LotSize`, `MagicNumber`, `StopLossPips`, `TakeProfitPips`, `MaxOpenPositions` (0=unlimited)
2026-02-05 01:22:42 -05:00
- Trailing defaults (used if a strategy doesn't set them): `TrailEnabled`, `TrailType=0(fixed)`, `TrailActivationPoints`, `TrailDistancePoints`, `TrailStepPoints`
- Mode toggles: `NoConstraintsMode` (bool, default **true**) — bypasses many constraints for maximum data collection; critical safety checks (circuit breaker, memory) remain enforced
- **Position Manager** (see `Include/PositionManager.mqh`) — available behind `UsePositionManager`. Defaults: PaperEA=`true`, LiveEA=`false`. Current integration initializes the manager and supports caps/correlation hooks; advanced exits/brackets will be integrated next.
### MQL5 Compatibility Notes
All code has been verified MQL5-compatible with the following syntax adjustments:
- Log reasons: `fallback_no_policy` (no slices loaded), `fallback_policy_miss` (slice not found). Both bypass exploration caps and use neutral scaling; demo-only unless `FallbackDemoOnly=false`.
- **Insights auto-reload controls**:
-`InsightsAutoReload`, `InsightsLiveFreshMinutes`, `InsightsReadyPollSec` (inputs present; wiring for automated reload is being expanded in LiveEA).
- **Position management**:
-`UsePositionManager` (default false) and `PMMaxOpenPositions` for portfolio caps; enables integration with `Include/PositionManager.mqh` where available.
#### Policy scaling keys
- LiveEA expects trailing scaling under the key `trail_scale`.
- PaperEA’s `PolicyEngine` and `docs/PolicySchema.md` use `trail_atr_mult` for ATR-based trailing. Exporters may emit both keys for compatibility until the schema is unified.
-`PaperEA` calls `CheckPolicyReload()` in both `OnTimer()` and `OnTick()`; when `policy.reload` exists, it reloads `policy.json` and logs `Policy gating: min_conf=..., slices=N`.
- On trade execution, if policy is loaded, the EA applies per-slice scaling before sending the order.
- Use the provided script to recompute `insights.json` from the current `features.csv`:
1) In MT5 Navigator → Scripts → run `InsightsRebuild`.
2) Check `Common\Files\DualEA\insights.json` and Journal for status.
## Troubleshooting
- “No CSVs in MQL5/Files”: Expected. Tester and Live now write to `Common\Files\DualEA` using `FILE_COMMON`.
- “Error 5004 opening file”: First‑run read attempts can fail if the file doesn’t exist; the constructor now creates the file and header without logging an error.
- “Inputs not showing in Tester”: Click Inputs → Reset; MT5 caches previous inputs.
---
## PaperEA
- Purpose: primary data-collection EA for backtests and demo/paper runs. Logs features, events, and trades to the shared Knowledge Base for ML and insights.
- Execution model:
- OnInit/OnTick drive the scan→gate→execute path; logs to KB on every decision and execution.
- Policy reload via `DualEA/policy.reload` checked in `CheckPolicyReload()`; telemetry flush after scans.
- Timer-based scanning per Phase 6 design may be enabled as parity with LiveEA (see Phase 6) where implemented.
- Gating and exploration caps:
2026-02-05 01:22:42 -05:00
-`NoConstraintsMode` (default **true**) bypasses many gates/caps for unrestricted exploration; critical safety checks (circuit breaker, memory guard, news filter) remain enforced.
- When policy is loaded and slice exists, `ApplyPolicyGating()` checks confidence (per-slice scaling currently minimal in PaperEA; LiveEA has full scaling).
-`LiveEA/LiveEA.mq5`: policy loaded from file on init; `ApplyPolicyScaling()` applies SL/TP/trailing (trailing via `trail_scale`), fallback gating (`fallback_no_policy`, `fallback_policy_miss`, demo‑only by default), heartbeat with fallback flags
- Add `kb_check.bat` for headless insights rebuild+validate and wire into CI (fail on stale/coverage).
- Add `scripts/RunInsightsValidation.ps1` and `ScheduleInsightsValidation.ps1` for scheduled validation.
- Optional CI trainer job: run `ML/run_train_and_export.bat` on schedule/data‑change; publish `policy.json` and touch `policy.reload`.
- Operator runbook: KB rebuild/validate flows and artifact paths under `Common\\Files\\DualEA`.
- Telemetry: concise summaries for insights rebuild/validation outcomes.
- Not Implemented:
- Phase 5, 9, 10, 11
### Phase 1: Data & Insights Foundation
- TODOs (hardening and ops):
- CI integration: add `kb_check.bat` and wire `Scripts/ValidateInsights.mq5` to CI to fail on stale `insights.json`, empty/missing slices, and unmet required coverage (symbols/TFs/strategies).
- Headless rebuild wrapper: provide a batch/PowerShell entry point to run `Scripts/InsightsRebuild.mq5` non‑interactively (for CI/scheduled tasks).
- Schema versioning: version `insights.json` and add compatibility checks in `Include/StrategySelector.mqh`; document version in `docs/KB-Schemas.md`.
- I/O hardening: ensure `FolderCreate("DualEA", FILE_COMMON)` is called by all writers; prefer robust readers (`FILE_TXT|FILE_ANSI`), skip malformed rows, and log/continue.
- Validator enhancements: expand `ValidateInsights` to assert non‑empty required metrics per slice and configurable thresholds; surface a concise report.
- Ops scheduling: optionally add `scripts/RunInsightsValidation.ps1` and `ScheduleInsightsValidation.ps1` to run validation on a cadence.
### Phase 2: ML/LSTM Pipeline
- TODOs (ops/hardening):
- CI trainer job: run `ML/run_train_and_export.bat` on schedule or data‑change; publish `policy.json` to Common Files and touch `policy.reload`.
- Provenance & signing: include model hash, train window, metrics in `policy.json`; sign/hash for integrity; keep last‑known‑good for rollback.
- Shadow eval & A/B: support dual policies in PaperEA (shadow mode) prior to promotion to LiveEA.
- Monitoring: log SHAP/feature importance drift signals; alert on material drift.
- Rollback guardrails: auto‑rollback to last‑known‑good on parse/plausibility failure during hot‑reload.
Note (sequencing): core ML training/export and PaperEA policy load are implemented. The structured 3×3 audit for Phase 2 will begin after Phase 3 — Cycle 3.
- Suggestions:
- Use walk‑forward splits; track ROC‑AUC, Brier, Expected‑R; calibrate probabilities and thresholds per slice.
- Export `policy.json` with provenance (model hash, train window, metrics); sign/hash for integrity.
- Run A/B policies and shadow evaluation in PaperEA before promotion to LiveEA.
- Log SHAP/feature importance to monitor drift and potential leakage.
### Phase 2a: PaperEA Execution & Telemetry
- TODOs (remaining):
- CI wiring: integrate `Scripts/ValidateInsights.mq5` into CI and add `kb_check.bat` to fail on stale `insights.json`, empty/missing slices, and missing required coverage.
- Headless operations: add `scripts/RunInsightsValidation.ps1` and `ScheduleInsightsValidation.ps1` for scheduled rebuild/validation.
- Ops docs: add a short operator runbook covering rebuild/validate flows and artifact locations in `Common\\Files\\DualEA`.
- Explore caps ops: provide a lightweight reset helper and a smoke test that verifies daily/weekly counters persist and increment as expected.
- Telemetry polish: emit concise summaries for insights rebuild/validation outcomes.
2. Correlation‑aware pruning within selector/gating to retain a diversified subset per symbol/timeframe.
- Emit `p5_corr` telemetry; cap per symbol/TF.
3. Multi‑timeframe confirmations in selector/gating with inputs (e.g., `EnableMTFConfirmations`, `MTFConfirmTF`, `MTFConfirmMinScore`) and telemetry (`p5_mtf`).
4. Parameter stability tracking in selector; compute stability score and gate via (`P5_StabilityGateEnable`, `P5_StabilityWindowDays`, `P5_StabilityMaxStdR`) with telemetry (`p5_stability`).
5. Policy integration for subset selection/weighting from ML policy (beyond neutral scaling); document and gate safely.
6. Feature/telemetry export parity after exec in both EAs (ATR, spread, TF, trailing params, strategy features).
7. Telemetry consistency across both EAs: standardize remaining `p5_*` event keys and shadow logging under `NoConstraintsMode` (PaperEA parity).
8. Test plan: backtests (walk‑forward), forward/demo runs, and monitoring to validate selector and gating behavior.
-`OnInit()`: configure `EventSetTimer(TimerScanSeconds)` when `TimerScanEnabled`.
-`OnTimer()`: run a `ScanStrategies()` routine that performs the same Refresh → CheckSignal → gating (selector + insights + policy + caps) path as `OnTick()`.
- Deduplicate within a minute per `symbol|timeframe|strategy` using a rolling `LastScanMinute` map to avoid duplicate triggers if ticks also arrive.
- Preserve existing behavior: always `CheckPolicyReload()` and `Telemetry.Flush()` on timer.
- Performance & reliability hardening
- Pre‑create and reuse indicator handles for all registered strategies/timeframes to avoid reallocation overhead per scan.
- Cache policy and insights in memory; throttle file I/O to timer ticks; batch telemetry writes.
- Optional: `EventSetMillisecondTimer(250–1000ms)` for ultra‑low‑latency scanning in LiveEA; gate by CPU budget.
- LiveEA enrichment path
- Consume trained ML outputs for per‑slice `min_conf`, expected‑R, and dynamic sizing; apply via `ApplyPolicyScaling()`.
- Maintain exploration caps and detailed `LogGating`/`LogGatingShadow` for full auditability.
- Test & validation plan
- Backtests: walk‑forward with OOS across 3–5y per symbol/TF, including realistic spread/slippage/commission; parameter stability and FDR controls.
This section documents the LiveEA wiring of `Include/PositionManager.mqh` for correlation‑aware sizing and dynamic risk caps. All features are behind `UsePositionManager` and new PM inputs.
-`PM_CorrMinMult` (double) — minimum fraction of base lots allowed after correlation dampening
-`PM_CorrMinLots` (double) — absolute minimum lots floor after dampening
### Behavior
- New entries: after policy scaling (`ApplyPolicyScaling`), LiveEA applies correlation‑adjusted sizing via `CPositionManager.CalculateCorrelationAdjustedVolume(symbol, base_lots)`.
- Floors: `PM_CorrMinMult * base_lots` and `PM_CorrMinLots` are enforced to avoid over‑dampening.
- Scale‑ins: when PositionManager proposes `vol_scaled`, LiveEA applies the same correlation dampening and floors before overriding `order.lots`.
- Dynamic risk caps: configured in `OnInit()` via `CPositionManager.SetDynamicRisk(...)`. Internally caps additional size growth (implementation advisory, subject to future expansion).
### Telemetry & Logs
- Events: `pm_corr_sizing`, `pm_corr_floor`, `pm_corr_scale_in`, `pm_corr_floor_scale_in` with correlation value and before/after lots.
- Init log: `[PM] Initialized (...)` includes adaptive, profile, volatility exit, and dynamic risk params.
2) Open a correlated position (e.g., EURUSD) and then trade a related pair (e.g., GBPUSD). Expect reduced lots and `pm_corr_sizing` event.
3) Trigger a scale‑in via PositionManager; expect `pm_corr_scale_in` and floor events if dampening is severe.
4) Toggle `PM_CorrMinMult` / `PM_CorrMinLots` to observe floors applying (logs show before/after + floor values).
## License
Copyright 2025, Windsurf Engineering.
If you truly need low-latency sync later, consider:
- Named pipes or local TCP with a lightweight Python service
- A minimal REST loopback server
Note: These add failure modes and deployment friction; file-based I/O is simpler and reliable for MT5. Prefer file-based until a concrete latency SLO requires otherwise.
One JSON per line with explicit links to files/modules and decisions.
```json
{"id":"rb_0001","claim":"Exploration bypass triggers with existing slice","rebuttal":"Bypass is no‑slice‑only; existing under‑threshold slices are gated","evidence_files":["Experts/Advisors/DualEA/PaperEA/PaperEA.mq5"],"decision_paths":["Gate->Insights->ExploreCaps"],"status":"resolved","timestamp":"2025-08-17T00:00:00Z"}
Record adversarial tests, input mutations, expected vs observed behavior, and severity.
```json
{"ts":"2025-08-17T00:00:00Z","module":"PolicyLoader","file":"Experts/Advisors/DualEA/Include/StrategySelector.mqh","symbol":"EURUSD","timeframe":60,"case":"corrupt_policy_json","mutation":"truncated file","expected":"fallback to last‑known‑good policy with log and no crash","observed":"fallback engaged; neutral scaling applied","outcome":"safe","severity":"low","artifacts":["Common/Files/DualEA/policy.json","Common/Files/DualEA/policy.backup.json"],"notes":"Validated timer reload path and guardrails"}
```
Fields:
-`ts`: timestamp
-`module`, `file`: component and path under repo
-`symbol`, `timeframe`: slice context when applicable
-`case`, `mutation`: short names for cataloging
-`expected`, `observed`: behaviors
-`outcome`: safe | unsafe | inconclusive
-`severity`: low | medium | high
-`artifacts`: related files (Common Files paths allowed)