The Architecture of an Automated Trading System
The six subsystems between a strategy definition and a filled order, what each is responsible for, and where the hard failure modes live.
What subsystems does an automated trading system need?
Six: market data ingestion, strategy evaluation, a risk gate, order management, position and reconciliation state, and monitoring. Each has a distinct failure mode, and collapsing any two of them into one component is where most systems become unmaintainable.
The temptation is to write a loop that reads prices, decides, and calls the broker. That works until the first partial fill, the first duplicate submission, or the first disagreement between your position record and the broker's, and then the absence of boundaries is what makes the bug unfindable.
The boundaries, expressed as responsibilities
MARKET DATA normalise feeds → ordered, gap-detected candle stream
owns: time. Nothing downstream invents a timestamp.
STRATEGY pure function (state, candle) → intent | null
owns: nothing. No I/O, no clock, no broker calls.
This purity is what makes backtest and live share code.
RISK GATE intent → approved order | rejection(reason)
owns: the veto. Position limits, exposure caps,
per-strategy capital, kill switch.
ORDER MANAGEMENT approved order → broker submission, with an
idempotency key. Owns retries and their safety.
POSITION STATE the system's belief about what is held,
plus reconciliation against broker truth.
Owns: detecting divergence, loudly.
MONITORING observes all five. Owns: waking a human.Why must strategy evaluation be a pure function?
Because it is the only way backtesting and live trading can run the same code. If the strategy reads the clock or calls the broker directly, the backtest is testing a different program from the one that trades.
Given the same state and the same candle, a pure evaluator returns the same intent whether it is being replayed over 2019 data or evaluated live. Every dependency on wall-clock time, network state or account balance moves outward into an explicit parameter.
This is the single highest-leverage design decision in the list. It is also the one most often compromised early and expensively unwound later.
What makes order management genuinely hard?
Network calls can fail after the broker has accepted the order but before you learn about it. Without an idempotency key, a retry creates a second position, and the system's own records will not show the duplicate.
The pattern is to generate a client order ID before the first attempt and reuse it on every retry, so the broker can recognise and reject the duplicate. Then reconcile: ask the broker what it actually holds and treat that as authoritative, rather than trusting a local ledger built from responses that may have been lost.
Failure modes worth designing for explicitly
| Failure | Naive behaviour | What it should do |
|---|---|---|
| Submission times out | Retry, creating a duplicate | Retry with the same idempotency key, then reconcile |
| Partial fill | Treat as filled or unfilled | Track filled quantity; the exit must match what is actually held |
| Data gap | Evaluate on stale candles | Detect the gap and suspend evaluation for that instrument |
| Broker auth expires | Fail silently on next order | Detect before the session, block new entries, keep exits available |
| Exit path unavailable | Keep entering | Refuse new entries. This is the one that must fail closed |
Why does the risk gate sit between strategy and execution?
So that limits cannot be bypassed by a strategy bug. If sizing and exposure checks live inside strategy code, a defect there can place an order no rule would have allowed. As a separate stage every order passes through, the gate holds regardless.
It also gives you one place to implement a kill switch. Flipping a single flag in the gate stops all new entries across every strategy, without touching strategy code or waiting for a deploy.
Where should cost modelling live?
In the core, applied at fill time, not in the reporting layer. A system that computes P&L from price differences and subtracts costs at the end will make sizing and exit decisions on numbers that do not exist.
For Indian equities this means brokerage, exchange transaction charges, STT, stamp duty, SEBI turnover fees and GST, several of which are charged differently on a buy than on a sell. Modelling them as a flat percentage is convenient and wrong in a way that makes frequent-trading strategies look much better than they are.
References
- Trading and Exchanges: Market Microstructure for PractitionersLarry Harris, Oxford University Press
- SEBI, legal framework and circularsSecurities and Exchange Board of India
- Idempotency keys for safe request retriesStripe API documentation
- architecture
- trading systems
- infrastructure
- engineering
Topics
Written by
The Stretus team writing on algorithmic trading, market structure and the systems that sit between a strategy and an exchange. Every claim about the platform links to the documentation that specifies it.
See these ideas running
The platform implements the workflow described here: strategies expressed as rules, backtested against historical data, paper traded, then executed through authorized broker APIs under platform-level risk controls.
Related reading
How a Backtesting Engine Works: Event Loop, Fills and Costs
Inside a backtest: the event loop, how fills are simulated, why lookahead bias appears, and what separates a useful engine from a plausible one.
What a Five-Year Order Audit Trail Has to Contain
The retention obligation, the fields an inspection actually asks for, and why "comprehensive logging" is not an answer to the question.
Static IP, API Keys and the Once-a-Week Rule
How authorised API access works under the framework, and why the once-per-calendar-week limit on changing an IP breaks naive failover designs.