An algorithmic trading bot is a pipeline with a kill switch, not a script that “buys the dip”. The pieces are always the same, whether you execute through a broker API, a MetaTrader EA, or a mix: data in, a decision, an order out, and a risk layer that can say no. If you skip the last one, you do not have a system. You have a market order generator.
This architecture guide is for product people hiring an agency. DayDecoder builds custom software, including trading-related systems, from Ahmedabad for clients in the US, UK, Europe and Australia. We will talk about boxes and failure modes, not a secret indicator.
Risk disclaimer. Algorithmic trading can lose money rapidly, including more than you intend if leverage, bugs or retries go wrong. Historical data, backtests and simulations are not live trading and do not predict future results. This article is educational architecture. It is not investment, trading or financial advice. DayDecoder does not promise profits or that any design will be profitable. Only use capital you can afford to lose, and consult a regulated adviser if you need advice.
Key takeaways
- Four planes: data, strategy, execution, risk. Risk can veto the other three.
- The system of record for positions is the venue (broker/exchange), reconciled by you, not a pandas DataFrame.
- Idempotent orders, sequenced commands, and a dead-man switch are architecture, not polish.
- Research (batch) and live (streaming) share ideas, not the same process or the same clock.
- If you cannot draw where an order can be duplicated, you are not ready to hire a coder to “just connect the API”.
The four planes
| Plane | Job | Typical failure |
|---|---|---|
| Data | Clocks, bars, trades, reference data, corporate actions if you have them | Silent gaps, timezone mix-ups, adjusted vs unadjusted prices |
| Strategy | Turn state into a desired position or order intent | Look-ahead, overlapping signals, hidden martingale |
| Execution | Turn intent into venue orders, handle partials and rejects | Double send, wrong symbol mapping, ignoring lot step |
| Risk | Gross limits, per-symbol limits, kill switch, who is allowed to trade | Limits only in a slide deck, not in the path of the order |
Put risk in-process in front of the order gateway, not as a dashboard someone might open. Dashboards do not catch a retry loop at 200 orders a second.
Data plane
You need a clock everyone agrees on (usually UTC internally, venue time at the edge). You need to know whether a bar is closed. You need a story for missing minutes: skip, mark, or halt. Crypto, FX CFDs and listed futures all lie differently about weekends.
Store raw ticks or trades if you can afford it; store bars you computed, with the recipe (session, timezone) in metadata. Do not recompute history with a different session filter than live. That bug looks like alpha in a notebook and like random in production.
Reference data: contract size, tick value, trading hours, expiry. For CFDs, the “symbol” is a broker product, not an exchange ISIN. Mapping US100 to the thing you backtested as NQ is a product decision with a loss attached if you get it wrong.
Strategy plane
A strategy module should be a pure-ish function: inputs are a state snapshot, output is a target (flatten, hold, buy N lots) plus a reason code. Side effects belong in execution. That split is how you backtest the same code path you run live, or at least a close cousin. See backtesting and risk management.
State includes: current position from the reconciler, not from “the last order we intended”. Intents lie after rejects.
Do not hide inventory doubling behind a parameter named aggression. If the strategy pyramids, the spec says so, with a cap.
Execution plane
One gateway per venue. The gateway understands: order types you actually have, rate limits, idempotency keys, and how to query open orders after a TCP blip. REST plus websocket is common; both can stall. Heartbeats and a “I don’t know my orders” mode that flattens or pauses are part of the design.
MetaTrader can be a venue. Then the EA is the gateway, not a second strategy. That pattern is in the Python bridge article.
Never let research notebooks hold API keys that can trade. Live keys on the live box, scoped if the broker allows, with IP allowlists where they exist.
Risk plane
Hard limits: max notional, max contracts, max orders per minute, max loss per session (from fills you have, not from a hope). A kill switch that a human and a watchdog can trip. A list of symbols allowed. A list of accounts allowed. Time windows.
Soft limits: alerts before you hit the wall. Soft without hard is decoration.
Risk must see gross across strategies if they share an account. Three “small” bots on one login are one bot with three authors.
Control plane and observability
Logs with correlation ids from intent to fill. Metrics: reject rate, lag from signal to ack, unexplained position. A UI that can pause. If the operator is in London and the VPS is in New York and the agency is in Ahmedabad, overlap hours and a documented night owner matter more than a Grafana theme. We work those overlaps on purpose; see offshore delivery.
Research vs live
Batch research can afford to replay a file. Live cannot rewind. Share libraries (lot rounding, session maps) but run two binaries. Promoting a notebook server to production is a rite of passage nobody needs twice.
When you add machine learning, RAG-style document bots are the wrong analogy. Price models overfit quietly. Keep them behind the same risk plane. Training choices are a different article: how to prepare your own AI model — and most trading teams still should not train a foundation model from scratch.
A reference topology
- Ingest workers write to a log (Kafka is optional; a durable queue is not). See Kafka with Laravel and Node if you already live in events.
- Feature store or simple tables for bars you trust.
- Strategy process, stateless enough to restart, reading positions from the reconciler.
- Risk process or library in front of the gateway.
- Gateway to the broker.
- Reconciler looping against the venue as source of truth.
- Operator UI and paging.
Start with fewer boxes on one VPS if you have one account and one strategy. Split when you have a reason (blast radius, team boundaries), not because a diagram looked senior.
Hiring an agency against this diagram
Ask them to mark which boxes they will own, which you will own, and where a duplicate order can be born. Ask for the disconnect behaviour in writing. If they only talk about “the strategy”, they are not building a bot. They are writing a signal.
DayDecoder has 10+ years and 103 customers on product software. Trading systems get the same treatment: tests, logs, and no theatrics. contact@daydecoder.com is the right address for a design review, not a profit pitch.
Idempotency, client order ids and the two-generals problem
You will not get a perfect “exactly once” from a network. You will get “at least once” plus a client order id you control. The gateway must store that id before send, see it on the venue, and refuse to mint a second marketable order for the same intent. If the venue does not support client ids, you build a conservative query-and-wait, and you accept that some strategies cannot be safely automated on that venue. That is an architecture outcome, not a cowardly one.
Intents should expire. A signal from thirty seconds ago on a fast product is archaeology. Expiry belongs in the command, checked again at send time, because a queue can delay you.
Clocks, calendars and sessions
Internal UTC, venue local at the edge, and a calendar of auctions, half days and maintenance. Crypto “always on” still has exchange maintenance. FX has rolls. Futures have expiries. A strategy that does not know the session is not a strategy; it is a random number generator with extra charts. Share the session library with the backtest, as in the risk article.
Multi-strategy books
Two strategies on one account need a position budget they cannot both spend. Either separate accounts (operationally heavier, cleaner) or a book-level risk process that sees intended plus open. Correlation is a risk input: two “independent” mean-reversions on the same dollar index are one bet. You do not need a PhD copula; you need a notional cap on a group. Put the group in config, not in folklore.
Shared research features (a volatility estimate) should be versioned. Quiet breakage of a feature service is a classic “all bots went stupid on Tuesday” incident.
Security of the live box
Least privilege OS user, no shared admin, secrets not in git, outbound firewall that can only reach the venue and your logging. RDP/SSH with MFA. No random browser on the live VPS. This is dull and more important than a new indicator. If an agency cannot talk about the box, they are delivering a zip of Python, not a system.
Need this architecture on a broker API or next to MetaTrader? Bring the venue, the asset class, and who holds the kill switch. Custom software development or contact.
Paper, research and the promotion gate
A strategy earns a live key when: the assumption list is written, the backtest engine shares sizing with live, limits are tested, the kill switch is drilled, and a human can explain a day of sim fills. Not when a notebook Sharpe looked pretty. Promotion is a checklist in git, signed in a ticket, not a Friday afternoon scp.
Demotion is also a feature. If reject rates spike or reconciler is stale, the bot pauses itself. Heroic “keep going” flags are how small shops meet their broker’s margin call. Architecture should make pause the default under uncertainty.
If you run MetaTrader and an API bot, they are two systems that may share a risk budget but must not share an undocumented order path. Draw both on the same whiteboard. If you cannot, you are not ready for either to be live at a size you care about. Write the diagram into the repo so it survives the whiteboard eraser.
Disaster recovery: a second VPS that is not running the strategy, with the ability to start paused, reconcile, then optionally resume. Snapshots of the live box are necessary and not sufficient; a snapshot in the middle of an order is a riddle. Prefer “start paused and human confirms”. Recovery that auto-trades from a stale snapshot is a second incident.
Handover checklist
You should receive diagrams of the four planes, the state machine, the kill-switch path, secret locations, venue client-id behaviour, and a signed promotion checklist. Include who is on call in each overlap window (US, UK, EU, AU, India). Include the account list the bot is allowed to see. If a box is missing from the diagram, that box will be invented in an incident. Invented boxes duplicate orders. Prefer a boring diagram you can hang next to the VPS password sheet you should not actually print. Put both in a password manager and a repo the operator can read at 2 a.m. without us.
FAQ
Can we start with a single Python script?
For a private research toy, yes. For anything with live keys, split risk and execution even if they are modules in one repo. Scripts grow retries. Retries duplicate orders.
Do we need microservices and Kafka on day one?
No. You need durable logs and a reconciler. Kafka helps when multiple consumers and replay matter. It is not a trading edge.
Where should the bot run?
Close enough to the venue to meet your latency budget, on infrastructure you can snapshot, with access control. See the VPS article for the MetaTrader case; the same ops ideas apply to API bots.
Will a better architecture make the strategy profitable?
No. Architecture reduces operational ways to lose money. It does not create edge. Anyone who sells you a diagram as an income plan is not an engineer.
Can DayDecoder run the bot for us 24/7?
We can build and help you operate. Custody of accounts and investment management are a different, regulated business. We stay on the software side.
Written by
Prakash Tank
Founder & Full-Stack Architect, DayDecoder
Prakash started as a certified Laravel developer and grew into a full-stack architect who owns a project end to end: requirements, architecture, development, deployment, and support. He designs event-driven systems with...
More about Prakash