Skip to content

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

Services and their permitted responsibilities
ServiceLanguageWhat it may do
MQL5 gatewayMQL5Carry prices and account state out of MetaTrader 5, and carry order commands back in. No decisions of any kind.
Trading coreC++Evaluate risk, manage open positions, and dispatch orders. The only component with execution authority.
AI agentPythonScreen symbols and produce trade proposals. Cannot approve, execute, modify or close anything.
Backend APIPythonServe the console and record history. Reads state; issues no trading commands.
ConsoleTypeScriptShow you what happened and take your approvals. Talks only to the backend API.

The path a trade actually takes

  1. Ticks and account state leave your MT5 terminal through the gateway and reach the trading core.
  2. 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.
  3. 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.
  4. The proposal is published onto the message bus. The agent's authority ends at this line.
  5. The C++ risk engine independently re-checks it against every hard limit. It does not trust the confidence score or the Python-side validation.
  6. 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.
  7. 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

If the AI agent crashes, the database is unreachable and the console is down, your open positions are still being managed on live ticks — emergency exit, break-even and the profit ratchet all continue to evaluate. What stops is the generation of new proposals, which is the correct thing to stop when the system is degraded.

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.