A production trading bot is not a signal with a loop around it. It is a five-stage pipeline — data, signal, risk, execution, monitoring — and the stages rank in roughly reverse order of the attention they get in tutorials. Builders spend nearly all their time on the signal, which is also the stage least correlated with whether the system survives its first year live: signals fail gradually, the other stages fail all at once.
The short answer to "what do I actually need": a data store whose timestamps you trust, a signal simple enough to explain in two sentences, a risk layer that can veto anything, an execution layer that reconciles its own beliefs against the broker's, plus monitoring that pages you when the two disagree. Everything else — languages and frameworks included — is detail.
The Five Stages
Data
Everything downstream inherits this layer's flaws. The classic futures traps are contract rolls and session boundaries: a continuous back-adjusted series is fine for signals built on price differences but silently wrong for anything keyed to absolute levels, because the adjustment shifts history at every roll. Index futures trade nearly around the clock with a daily maintenance halt, so a "daily" bar is a convention — pick the session template that defines your day and encode it once.
Store raw exchange messages separately from derived series: if you only keep computed bars, every bar-builder bug fix rewrites history and old backtests stop being reproducible. Decide early between full depth of market and top-of-book — retrofitting depth into a quote-based design is a rewrite, not a patch.
Signal
A signal is a pure function: history in, position intent out. Keep it pure — no network calls, no hidden state — so it can be replayed exactly — the property every test below depends on. Inputs can be anything computable point-in-time: bar statistics, order flow imbalance, cumulative delta divergence, dealer positioning levels. The signal's job ends at intent — once it starts sizing positions or checking account state, risk logic is smeared across two layers and neither can be tested alone.
The losing side of this stage is complexity. Every added parameter is another dial an optimizer can turn toward noise; the overfitting section below is mostly a bill for decisions made here.
Risk
The risk layer sits between intent and orders and holds the only veto in the system. At minimum it enforces a hard position cap, a daily loss threshold that flattens and halts, a sanity bound on order prices, a rate limit on submissions, plus a human-reachable kill switch. These checks fire on bugs as often as on markets — a feed glitch that prints an absurd price, or a loop that re-submits a rejected order forever.
The cost of omission stays invisible for months: a missing gate costs nothing until the day it costs more than the account. That asymmetry is the argument for ranking this layer above the signal.
Execution
Backtests assume orders fill; live systems manage orders that exist in uncertain states — partially filled, rejected, cancelled in flight, or unknown during a disconnect. The core discipline is reconciliation: check the bot's internal position against the broker's reported position on a schedule, and halt trading on any mismatch instead of "correcting" automatically — correction applied to bad state is how a flat bot becomes a doubled one.
Market orders pay the spread with certainty; limit orders earn the spread when they fill — but they fill preferentially when price is trading through them, exactly when you least want the position. This adverse-selection cost never appears in a naive simulation.
Monitoring
Log every decision with its inputs: what the signal saw, what the risk layer allowed, what was sent, what came back. Heartbeats should page you when the process dies but also when it merely goes quiet — a hung process holding a position is worse than a dead one. My readiness test: if the machine caught fire mid-session, could I flatten from a phone in two minutes using only the broker's interface? Until yes, size stays at minimum.
Backtest Overfitting
An overfit backtest is a lookup table of past noise wearing a strategy's costume. Every parameter combination tested is a lottery ticket; test enough and you will hold a winner over any historical stretch, purchased with search rather than structure.
Defenses, in order of cost:
- Fewer parameters. Two are defensible; ten are a curve-fitting kit.
- Out-of-sample data that stays out. The first time you peek and adjust, it has become in-sample.
- Walk-forward testing. Optimize on one window, trade the next untouched, roll forward. Parameters that jump around between windows are themselves the verdict.
- Plateaus over peaks. If results collapse when a lookback moves from 20 to 22, the 20 was noise.
- Cost realism. A fully hypothetical example: a micro contract with a $1.25 tick, an 8-tick stop against an 8-tick target — $10 risked to make $10. Add hypothetical costs of $1.50 round-turn commission and one tick ($1.25) of slippage — $2.75 per trade — and breakeven moves from a 50% win rate to 63.75%, since 0.6375 × $10 − 0.3625 × $10 − $2.75 = $0. Tight-bracket systems die on this arithmetic live while looking brilliant in a frictionless simulation.
Look-Ahead Bias
Look-ahead bias is any use of information at simulation time T that did not exist at wall-clock time T. The common forms:
- Trading a bar's close inside that bar — the close does not exist until the bar ends.
- Indicators that recompute across their whole window as new data arrives, silently changing their own history ("repainting").
- Signals built from settlement or end-of-day values timestamped before they were actually published.
- Choosing which contracts to trade using knowledge of how they later behaved.
Paper Versus Live
Paper trading validates plumbing; its fills are polite fictions. The divergence has distinct sources:
- Queue position. A simulated limit order fills when price touches it. A real one sits behind resting size, so the touch often comes without a fill — except when the level trades through, filling you into a move against you.
- Stop slippage. Simulated stops execute at the stop price; real stops trigger into a moving book, where in fast conditions the gap between trigger and fill can exceed the stop distance itself.
- Feed differences. The simulated feed rarely matches the broker's tick-for-tick; a one-tick difference in entries is fatal to a system whose whole edge is two ticks.
- The intervention effect. With money attached, the human watching becomes part of the system — pausing after losses, overriding before news. Whatever was backtested, that hybrid is not it.
Infrastructure Minimums
Retail automation does not need a colocated rack. It needs a boring floor:
- A machine that stays up — a small cloud instance or a dedicated box on a UPS, never the laptop that sleeps.
- Process supervision that restarts the bot after a crash and re-enters through the reconciliation path rather than assuming flat.
- A disconnect policy written before the first live order: either working orders cancel at the broker side, or a documented decision to hold.
- Synced clocks. Unsynced ones corrupt logs first and backtests second.
- Logs shipped off the machine, so the crash that needs diagnosing cannot destroy its own evidence.
- Scoped credentials: the bot's API key gets the narrowest permissions the broker offers, with money movement excluded.
Risk Gates Before Signals
A signal's errors are survivable by design: it is wrong a large fraction of the time, one position at a time. Infrastructure and execution errors arrive instead as single events with tails — a re-send loop, a stale feed that keeps a stop from triggering, a reconnect that assumes flat while holding, an order router pointed at the wrong account. Signals decide what the system attempts; gates decide whether it survives long enough to attempt anything. Only one is existential: a mediocre signal behind hard gates outlives a brilliant signal without them.
A go-live sequence that respects that ranking:
- Replay the strategy event-driven over history with next-bar fills and full hypothetical costs.
- Paper trade long enough to exercise a disconnect, a reject, a partial fill, a daily-loss halt — trigger them deliberately if the market will not.
- Go live at one micro contract, not to test the signal but to measure real fill quality against the simulated assumptions.
- Compare live fills to simulated fills weekly — that difference is your true cost model; feed it back into the backtest and see whether the edge survives.