Demo-first MT5 Expert Advisor and Python news gateway. The EA never opens a position without an explicit approval click in MT5. Telegram is notification-only in v1.
gateway/: FastAPI gateway, economic-calendar/news adapters, scoring, single-use approval tokens, execution authorization and Telegram notifications.D:\Vault\Metatrader\audit.jsonl: append-only demo audit trail for generated signals and decisions (never commit secrets).mt5/Experts/XAUUSD_NewsTrader.mq5: MT5 EA with EMA/RSI/ATR confirmation, broker-aware sizing and approval panel.config/.env.example: configuration template. Copy to.envand keep secrets out of git.
py -m venv .venv
.\.venv\Scripts\Activate.ps1
pip install -e ".[dev]"
Copy-Item config\.env.example .env
uvicorn gateway.app:app --env-file .env --reload --port 8000
pytestRun the broker-free approval lifecycle smoke test with python .\scripts\smoke_gateway.py. It uses a temporary audit file and never contacts MT5 or a broker.
Set the MT5 terminal WebRequest allow-list to http://127.0.0.1:8000 and attach the EA to the broker's XAUUSD chart. The EA discovers the actual symbol, tick size/value, volume limits and stops level at runtime.
The gateway defaults to time-bucketed deterministic mock data so the UI and integration flow can be tested without API keys. JSON, RSS 2.0, and Atom feeds, Telegram, and the official YouTube Data API adapter are opt-in through environment variables. A failed optional feed is skipped and cannot create a signal by itself. YouTube uses title/description metadata only; no video scraping is performed. The EA defaults to RequireDemoAccount=true; keep it enabled through demo forward testing.
NEWS_FEED_URLS accepts comma-separated JSON, RSS 2.0, or Atom URLs. The template includes the Federal Reserve monetary-policy RSS feed; leave it empty for deterministic demo/mock operation. Before enabling another external feed, verify the provider's terms, reliability, and timestamps, then restart the gateway.
NEWS_MAX_AGE_SECONDS defaults to 3600; headlines older than this are ignored. This prevents an old RSS archive item from becoming a fresh trade signal.
HIGH_IMPACT_BLACKOUT_SECONDS defaults to 300; a high-impact headline must settle for five minutes before it can become an approval candidate. The mock provider publishes its deterministic demo event outside this window.
Every signal and approval decision is recorded in D:\Vault\Metatrader\audit.jsonl by default. Set AUDIT_LOG_PATH to move it elsewhere. Approval events include the approved plan or rejection reason; execution events include broker retcode and tickets. Approval tokens and credentials are not written to the audit log.
In demo mode the gateway also reloads previously published news_id values from this ledger, preventing the same feed item from being republished after a gateway restart.
providers -> normalized news -> scoring -> /v1/signal -> MT5 panel -> approve/reject -> single-use authorization -> MT5 order
The MT5 EA polls the gateway for a signal. Approval is local to the MT5 panel, token-bound, single-use, and expires after SignalTTLSeconds. After approval, the EA sends a broker-specific execution intent, the gateway authorizes it once, and the EA records the broker result. A true return from CTrade.Buy/Sell is not treated as execution success until the trade server retcode is accepted.
For a controlled environment, set GATEWAY_API_KEY in .env and the matching GatewayApiKey input in the EA. When the key is configured, execution endpoints and /v1/signal require the X-Gateway-Key header. The browser dashboard uses the read-only /v1/monitoring/signal endpoint and remains monitoring-only; approvals are performed in MT5.
To compile and deploy the EA on a machine with MetaEditor/MT5 installed, run powershell -ExecutionPolicy Bypass -File .\scripts\compile_mt5.ps1 -Deploy or pass -MetaEditorPath/-TerminalDataPath explicitly. After compilation, attach the EA to the broker's demo XAUUSD chart, keep RequireDemoAccount=true, add the gateway URL to MT5 WebRequest allow-list, and run forward testing before considering any real account.
To restart the gateway with .env loaded, run powershell -ExecutionPolicy Bypass -File .\scripts\start_gateway.ps1.
For unattended local operation, scripts\watch_runtime.ps1 checks the gateway and MT5 and restarts them when they are unavailable. It is installed in the current user's Windows Startup folder. To find a Telegram chat ID, send /start to the bot and run powershell -ExecutionPolicy Bypass -File .\scripts\find_telegram_chat_id.ps1; copy the result into the local .env as TELEGRAM_CHAT_ID.