Skip to content

Architecture

How an AI trading agent works when it is not allowed to trade

Six layers, each with a narrower authority than the one before it. The interesting part is not what each layer does — it is what each layer is structurally unable to do.

The layers, from your broker inward

Read the right-hand column first. Authority is the whole design.

01

MetaTrader 5 terminal

Your account, your broker

Helios connects to a MetaTrader 5 terminal running your own broker account. Your credentials stay with your broker and your terminal — Helios never asks for them and never holds them.

Holds the account. Executes what the broker accepts.

02

MQL5 gateway

Thin adapter, no logic

An Expert Advisor inside the terminal streams ticks and account state out over ZeroMQ, and receives order commands on a separate socket. It contains no strategy and makes no decisions of its own — deliberately, so that the terminal-side component stays small enough to audit by reading it.

Relays. Decides nothing.

03

C++ trading core

The only component with execution authority

Three deterministic services: a risk engine that evaluates every proposal against hard limits, position management that runs open trades, and an execution engine that is the single place an order can be dispatched from. Written in C++ with no network dependency on the AI layer.

Decides and executes. Everything else asks it to.

04

Event bus

The boundary

The AI layer publishes proposals onto NATS on a subject scoped to your account. That is the only channel between the agent and the trading core, and it carries proposals in one direction. There is no reverse channel that lets the agent command anything.

Carries requests. Grants nothing.

05

Python AI agent

Proposer only

Screens a watchlist with deterministic scoring, then asks an LLM for a decision on the symbols that pass. The model returns a structured proposal — direction, size, stop, target, and a required confidence score — validated against a schema before it is published. A malformed or low-confidence answer becomes NO_ACTION.

Suggests. Cannot execute, resize, or close anything.

06

Web console

A window, not a control room

The dashboard you are signing into reads state and sends high-level commands — approve this proposal, pause trading, change a risk setting. It holds no trading logic and no secrets, and the trading core keeps running normally if the dashboard is closed or offline.

Displays and requests. Never touches the trading path.

The decision

Three things the risk engine can say

Every proposal ends in exactly one of these, and every one of them is recorded.

APPROVED

The proposal passed every hard limit. The execution engine dispatches it to the terminal and position management takes over from the fill.

REJECTED

At least one limit failed. Nothing is sent. The rejection is written to the audit trail with the specific rule that blocked it, so you can see exactly why.

REQUIRES_HUMAN_APPROVAL

The proposal is within the hard limits but past your review threshold. It waits in the console for you. Nothing executes while it waits, and nothing executes if you never answer.

After the fill

Position management does not consult the AI

Once a trade is open, the model's job is over. What happens next is deterministic rule evaluation on every tick, in priority order.

  1. 01

    Emergency exit

    A per-position kill switch on unrealized loss. Evaluated first, before anything else, and cannot be overridden by a later rule.

  2. 02

    Profit lock

    Closes the position once profit falls a configured percentage below its own peak, so a winning trade does not round-trip back to nothing.

  3. 03

    Break-even

    Moves the stop to entry once the trade is far enough ahead. Fires once per position.

  4. 04

    Trailing stop

    Follows price in your favour and only ever tightens — it can never be widened by a later evaluation.

  5. 05

    Partial close

    Takes part of the position off at a configured level, leaving the remainder running under the same rules.

This is the part that matters when something breaks. If the Python agent crashes, the LLM provider goes down, the database becomes unreachable, or you close the dashboard, these rules keep running. The trading core does not depend on any of them to protect a position that is already open.

Next: the specific limits

Every gate a proposal has to pass, and what each one is protecting you from.