FX
CURIO
Advanced9 min read

Building a Trading Bot Architecture

A trading bot is a distributed system with money on the line. Its architecture needs to be boring, testable, and hard to break.

It's tempting to write a trading bot as one big script: fetch price, check condition, place order, repeat. That works in a demo and fails in production, usually at the worst possible moment. A robust bot separates concerns into distinct layers so any single failure is contained rather than catastrophic.

The Layered Architecture

  1. 1.Data layer — ingests and validates market data, exposes a clean interface, isolated from strategy logic.
  2. 2.Signal layer — pure functions that turn validated data into a trade signal (buy/sell/hold + confidence).
  3. 3.Risk layer — sizes the position, checks exposure limits, and can veto any signal regardless of confidence.
  4. 4.Execution layer — translates an approved order into broker API calls, handles retries and idempotency.
  5. 5.Monitoring layer — logs everything, tracks live vs. expected performance, triggers alerts and kill switches.
The risk layer should never trust the signal layer

Even if your signal logic is bug-free today, a future code change or bad data tick could produce an absurd signal (e.g. size = 10,000 lots). The risk layer's job is to be a hard, independent ceiling — max position size, max daily loss, max order rate — that no upstream bug can bypass.

State Management

A bot must always know exactly what state it's in: flat, order pending, in position, closing. Model this explicitly as a state machine rather than scattering boolean flags across the codebase. Ambiguous state is how bots end up double-entering positions or leaving orphaned orders on the book after a crash.

enum BotState { FLAT, ORDER_PENDING, IN_POSITION, CLOSING }

function onFillEvent(state: BotState, fill: Fill): BotState {
  if (state === BotState.ORDER_PENDING && fill.side === 'entry') return BotState.IN_POSITION;
  if (state === BotState.CLOSING && fill.side === 'exit') return BotState.FLAT;
  return state; // unexpected fill -> log and alert, do not silently transition
}

Idempotency and Crash Recovery

Bots restart — from deploys, crashes, or cloud instance recycling. On startup, the bot must reconcile its assumed state against the broker's actual account state (open orders, positions) before doing anything else. Never assume the local state file is truth; the broker's API is the single source of truth.

Testing Strategy

  • ▸Unit test the signal and risk layers in complete isolation, with mocked data — no network calls.
  • ▸Integration test against a broker's sandbox/paper environment before any live deployment.
  • ▸Chaos test — deliberately kill the process mid-order and verify the reconciliation logic recovers cleanly.

The Bottom Line

The most sophisticated signal in the world is worthless bolted onto a fragile bot. Architecture discipline — clean layer separation, explicit state, idempotent execution — is what turns a weekend script into something you can actually trust with capital.

Apply in CURIO

Turn this into a real trade plan

CURIO runs this logic on a live chart: AI analysis with entry, stop, targets and a risk-checked position size.

  • 3 free AI analyses — no card required
  • Vision mode reads your own chart screenshots
  • Auto-scanner & prop-firm guard from Pro
Free

Weekly CURIO Trading Briefing

One email per week: new encyclopedia articles, a setup breakdown and the macro events that actually move price.

  • New articles & learning paths first
  • One setup broken down step by step
  • No spam, unsubscribe anytime

We only use your email for this. Unsubscribe with one click.

Related articles