Teaching your AI agent a trading strategy

Part 3 of 5 in Trade with AI agent

Contents

⚠️ Everything here runs on a demo account. This is engineering content, not financial advice. Trading CFDs is high-risk. Most retail accounts lose money. A strategy the agent can recognise does not change that. Read the disclaimer before you do anything with real funds.

🚀 Just here to build? Skip straight to the build →

Part 3 of 5 in the Trade with AI agent series. (Part 1: MT5 access · Part 2: the news.)

The level it makes up

It is 08:14 in London. For the first fourteen minutes of trading today, the German index has been trapped within an extremely narrow 40-point trading range. Your agent has live pricing data from Part 1 and this morning’s headlines from Part 2, so you ask your agent: “is there a good trade setup?”

It describes the price in fluent prose, invents a support level a few points off, and hands you a confident read it cannot reproduce thirty seconds later. It is basically just giving you what it sees at a point in time. But a strategy is the opposite: we apply a rule the same way every time, with clear levels you can point at.

So for today’s article we want to give the agent a rule or trading strategy. In this post we encode a very basic strategy based on the open range breakout (ORB) as a small, testable skill that computes the levels instead of making best guesses. The agent’s job is not candle arithmetic — it simply collects the bars, runs the rule, cross-checks with the current news, and flags it if there is a good opportunity.

Why the open range breakout

Basically it can be any strategy, but we pick ORB since it’s simple and as mechanical as it can get: take the high and low of a fixed window at the start of a session, say the first fifteen minutes or, even better, the previous session, and use that as the baseline. A completed candle closing above the high is a long break; below the low, a short break. The stop sits at the other side of the range, and each target is a multiple of that risk (we will discuss risk management in the next article).

That makes it a good first strategy for an agent. It is time-anchored — the range is whatever printed, not a subjective pattern call. It has defined risk — entry-to-stop distance is known before any sizing decision. And it has few parameters, so the rule fits in one small program you can pin down with tests.

There is one issue: CFD indices and spot FX trade across long sessions, so “the open” is a choice. GER40 might use 08:00 Europe/London, US30 09:30 America/New_York, and those UTC offsets move with daylight saving. The config stores a timezone and open per symbol instead of pretending one fixed UTC hour works all year.

To clarify before we begin developing this: the ORB is a well-known intraday trading strategy, but like many such strategies, it does not represent an edge. Breakout trades lose just as frequently as they win. What we are creating here is only the portion of the strategy that an honest agent can control (i.e., executing the strategy rules, not inventing additional levels).

From bars to a signal

I have prepared the repo for those who just want to get it tested right away: mt5-agent-strategies. It contains an orb-strategy skill: completed OHLC bars in, one technical state per symbol out. It follows the open Agent Skills specification: a concise SKILL.md, a deterministic CLI, references, and tests. A shared core handles bars, sessions, and timezones, so you can extend it if you want to build your own strategy in a new folder — you can ask your coding agent to build a new strategy for you.

Hermes is the worked example. The same skill package can be installed for OpenClaw, Codex, or Claude Code; the repo handles each runtime’s different skill directory.

The evaluator uses five-minute bars by default: three completed M5 candles build a fifteen-minute opening range, wicks included, and the next completed candle closing beyond it is the first possible trigger. An in-progress candle never counts, which is why every evaluation carries an explicit as_of timestamp.

The states are the whole story:

  • none — today’s configured session has not opened.
  • building — the opening range has started but is not complete.
  • armed — the full range is locked and the evaluator is waiting for a close.
  • breakout_long / breakout_short — the first completed candle closed beyond the range, with entry, stop, risk, and targets attached.
  • invalidated — required bars are missing, an enabled filter rejected the range, or the entry window expired without a break.

The core logic, trimmed to fit on the page, looks like this:

python
def evaluate(bars, cfg, as_of):
    completed = completed_bars(bars, as_of, cfg.bar_minutes)
    rng = opening_range(completed, cfg.session, cfg.range_minutes)

    if not rng.complete:
        return state("building" if as_of < rng.end else "invalidated")
    if not atr_filter_passes(rng, cfg.filters):
        return state("invalidated", reason="range outside ATR bounds")

    for bar in entry_window(completed, rng.end, cfg.entry_window, as_of):
        if bar is MISSING:
            return state("invalidated", reason="entry bar missing")
        if bar.close > rng.high + cfg.buffer:
            return breakout("long", entry=bar.close, stop=rng.low, rng=rng)
        if bar.close < rng.low - cfg.buffer:
            return breakout("short", entry=bar.close, stop=rng.high, rng=rng)

    return state("invalidated" if window_closed(as_of, cfg) else "armed")

No model appears in that function, and that is the point. The model collects inputs and explains outputs; the program owns the price arithmetic.

The order of that loop matters. It walks the entry window bar by bar and stops at the first decision it can defend. A bar the broker never delivered makes the first break unknowable, so a gap before any break returns invalidated rather than reporting the next candle as “the” break. Once a break is confirmed, nothing later can unmake it — a gap five minutes afterwards must not retract a break the agent already reported. Fail closed on the way in; never revise on the way out.

The repo’s synthetic fixture produces this result, abridged — the real output also carries a reason, the resolved session_open, an ATR filters block, and the trigger_time of the confirming close:

json
{
  "symbol": "GER40",
  "state": "breakout_long",
  "range": {"high": 18250, "low": 18210, "size": 40},
  "signal": {
    "direction": "long",
    "entry": 18252.5,
    "stop": 18210,
    "risk_points": 42.5,
    "targets": {"1R": 18295, "2R": 18337.5}
  }
}

Those numbers are test data, not a backtest. Their job is to prove that the same bars produce the same levels.

Wiring it into your agent

As with Part 2, hand the agent the repo and let it set itself up. The repo ships an AGENTS.md with install and verification commands for Hermes, OpenClaw, Codex, and Claude Code. The packaging is shared; the install destination is runtime-specific.

🖼️ The payoff: you tell Hermes which symbols and session opens to watch. It writes the config, pulls completed bars through the read-only MT5 tools from Part 1, runs the evaluator, and reads back building, armed, or a confirmed break with levels. Advisory only: it reports a technical setup and never places a trade.

Hermes reports an ORB evaluation for the Asian session: XAUUSD and UKOIL each show a confirmed breakout long with the opening range, trigger time, entry, stop, risk in points, and 1R/2R targets, plus a live status read on each — advisory only, no trades placed

1. Have the agent install and verify it. Give it the repository URL and this prompt:

Clone https://github.com/vincentwongso/mt5-agent-strategies, read AGENTS.md, and install
the orb-strategy CLI and skill for Hermes. Run every offline verification step and
report the output. Do not fetch live bars or place any trade.

The agent installs the Python package, checks orb-evaluate --help, runs the offline tests, and copies the skill into Hermes’ skill directory. No broker connection needed.

2. Configure each session. Ask for the two cash-session anchors explicitly:

Configure a 15-minute ORB for GER40 at 08:00 Europe/London and US30 at 09:30
America/New_York. Use completed M5 candles, take only the first break within two
hours of the session open, and report 1R and 2R targets.

The agent copies config.example.yaml to config.yaml and writes:

yaml
defaults:
  range_minutes: 15
  entry_window_minutes: 120
  bar_minutes: 5
  buffer_points: 0
  targets_r: [1.0, 2.0]
  filters:
    atr_period: 5
    min_range_atr: null
    max_range_atr: null

symbols:
  GER40:
    timezone: Europe/London
    session_open: "08:00"
  US30:
    timezone: America/New_York
    session_open: "09:30"

The ATR bounds are deliberately off by default: the strategy note says to judge range size against D1 ATR but offers no universal threshold, and inventing one would make the example look more scientific than it is. Set them only after testing on the instrument and session you actually trade.

3. Ask whether a setup is forming. The agent uses the read-only get_rates tool from Part 1 for M5 bars, adds D1 bars if ATR is enabled, and passes the untouched timestamps and prices to the evaluator:

Check the open-range setup on my watchlist. For each symbol tell me its state and
reason. If it broke, report the direction, trigger time, entry, stop, risk in points,
and both targets. Do not size or place a trade.

The skill tells the agent how to assemble the bars into a small JSON input, and tells the evaluator exactly when “now” is, so the current unfinished candle cannot sneak in as a close.

Then put it on a schedule. The skill is not a daemon; your agent’s scheduler is. Evaluate periodically, alert only on state changes:

During each configured entry window, check my ORB watchlist every five minutes.
Stay quiet while a range is building or armed. Alert once when a symbol confirms
its first break, and include the levels. Never place the trade.

🔗 Chain it with Parts 1 and 2. Ask: “if GER40 confirms an open-range break, check the news watchlist for a high-impact release within fifteen minutes before you alert me.” The deterministic strategy output becomes one input to the agent’s judgement, not permission to trade.

What comes next

Your agent now computes levels instead of improvising them. Same bars, same as_of, same answer: hands from Part 1, eyes from Part 2, a repeatable rule from today.

Please use a demo to test them out first. From my testing, to be honest, the result is not that great yet, since the strategy is very basic, use it as a foundation that you can build on top to make it better.

And notice what the signal still does not say: how much. It carries risk in points, but nothing turns that into lots, caps total exposure, or stops ten attempts on a bad morning. The strategy proposes a technical setup but it doesn’t have clear principles of risk management yet. We will discuss that in the next article, Part 4.

Try it tonight

Pick one index and one session open. Build a fifteen-minute range from completed candles, and have your agent tell you when the first candle closes beyond it. Run it on demo for a week and keep every failed break in the sample.

Disclaimer

This is educational and experimental engineering content, not financial advice. Everything shown runs on a demo account. CFDs are complex, leveraged instruments and the large majority of retail accounts lose money. A strategy an agent can recognise does not change that. The open range breakout can fail, breakouts fake out, defined risk is not low risk, and a rule that behaves on recorded sessions can behave very differently live. Run it locally, understand how it works, keep it advisory, and never point it at real capital you cannot afford to lose.

Full disclosure: the author works at Fintrix Markets, a CFD broker, and the demo account used throughout this series is a Fintrix Markets demo account. Nothing here depends on it. The setup is broker-agnostic and works with any clean OHLC source; Part 1 uses a CFD broker that supports MetaTrader 5. This is an experimental side project, not a Fintrix Markets product.

What’s next in this series

  1. Give your agent access to MT5
  2. Feed it the news
  3. Teach it a strategy ← you are here. Turn a setup into something the agent can recognise and report.
  4. Add a risk model (coming soon) — hard rules, daily limits, and sizing it can’t override.
  5. Teach it to build an EA (coming soon) — graduate from assistant to native MT5 automation.