How the system works
System architecture
The services this system is built from, what each one is permitted to do, and why the component that thinks is not the component that trades.
Last reviewed: 25 August 2026
The one idea the whole design rests on
The component that decides what might be worth trading is not the component that decides whether it is allowed, and neither of them is the component that can send an order. Those are three separate programs, written in two different languages, communicating over a message bus.
This matters because a large language model is a probabilistic system. It can be wrong, it can be inconsistent, and it can be argued into things. So it is given the job it is genuinely good at — reading context and forming a view — and is structurally prevented from doing the job it should never hold, which is moving money.
The services
| Service | Language | What it may do |
|---|---|---|
| MQL5 gateway | MQL5 | Carry prices and account state out of MetaTrader 5, and carry order commands back in. No decisions of any kind. |
| Trading core | C++ | Evaluate risk, manage open positions, and dispatch orders. The only component with execution authority. |
| AI agent | Python | Screen symbols and produce trade proposals. Cannot approve, execute, modify or close anything. |
| Backend API | Python | Serve the console and record history. Reads state; issues no trading commands. |
| Console | TypeScript | Show you what happened and take your approvals. Talks only to the backend API. |
The path a trade actually takes
- Ticks and account state leave your MT5 terminal through the gateway and reach the trading core.
- A screener narrows your watchlist to instruments that currently look tradeable on measures like trend strength and noise. The model is never asked about everything at once.
- The AI agent reads candles, volatility and the economic calendar for what survived, and emits a structured proposal with a confidence score. A proposal below the confidence threshold is discarded before it goes anywhere.
- The proposal is published onto the message bus. The agent's authority ends at this line.
- The C++ risk engine independently re-checks it against every hard limit. It does not trust the confidence score or the Python-side validation.
- Approved proposals go to the execution engine, which is the only component that can emit an order command. Oversized ones wait for a human instead.
- Position management takes over for the life of the trade, running on ticks alone.
Why C++ for the part that matters
The risk rules are compiled code reading a versioned policy file. They are not instructions in a prompt, which means there is no wording for a model to reinterpret and no context in which it can be persuaded that this trade is the exception. The same inputs produce the same decision every time, and that decision can be reproduced later from the recorded inputs.
What keeps working when things break
The dependency direction is deliberate: the trading core depends on nothing above it. Position management and the risk engine run independently of the Python agent, the backend and the console.
The failure case this is designed around
Failing closed is the default throughout. Stale prices, missing data and unreachable dependencies produce rejections, not attempts.
Where to go next
Proposals and approval follows a single proposal through this pipeline in detail. Risk policy reference lists every limit it has to pass, with the shipped defaults.