Most retail trading systems start as one file that grows until nobody can change it safely. The strategy, the data handling, the order placement and the risk checks all end up tangled, and a change to one breaks another.
The fix is not a large framework. It is five separable pieces with clear boundaries, and knowing which one to build first.
The five layers
1. Data. Fetching historical candles, caching them locally, handling corporate actions, and supplying live prices during the session. Everything above it asks this layer for data and never talks to the broker directly.
2. Strategy. Takes data in, produces signals out. No orders, no broker, no logging of its own. Given the same data it must produce the same signal, every time.
3. Risk. Takes a signal and decides whether it becomes a position and at what size. Position sizing, per-position risk, correlation limits, daily loss limit. This layer can refuse a signal, and it must be able to.
4. Execution. Places, modifies and cancels orders, reads fills back, and knows what you actually hold. This is where broker-specific code lives, and it should be the only place.
5. Observation. Logging, state persistence and alerts. Every decision recorded with the inputs that produced it.
The point of the separation is not tidiness. It is that each layer can be tested alone, the strategy can be backtested without a broker, and swapping brokers touches one layer instead of everything.
The boundary that matters most
If you take one thing from this: the strategy layer must never call the broker.
It produces a signal — an instruction like buy this instrument at this reference price with this stop. Something else decides whether that becomes an order.
That single boundary gives you three things at once. The same strategy code runs in a backtest, in paper trading and live, with only the execution layer swapped — which means what you tested is what you deployed, rather than a reimplementation of it. The risk layer gets a place to stand, because it sits between signal and order and can refuse. And you can test the strategy without any network at all.
When a system is hard to test or hard to paper trade, this boundary is almost always the thing that is missing.
The risk layer is not optional plumbing
Most retail systems fold risk into the strategy, which makes it negotiable. Separating it makes it enforceable.
What belongs here: quantity from capital, risk percentage and stop distance; a cap on open positions; a cap on exposure per sector or theme; a daily loss limit that stops new entries; and a hard check that the account has the margin before an order is sent.
Written as its own component, every one of those becomes a condition the program checks rather than a rule you remember. The daily loss limit is the clearest example: as a line in the risk layer it stops the day. As an intention, it gets renegotiated at exactly the moment it matters.
Give it the authority to refuse a signal and log the refusal. A record of what it declined is genuinely useful later, because a system that refused twelve signals in a bad week did its job.
State, and the assumption that causes the most damage
A retail system will crash. The machine reboots, the connection drops, a library throws something unhandled. The question is what it believes when it comes back.
The rule: the broker is the source of truth for positions, always. Not a file you wrote, not a variable in memory. On startup, read positions and open orders from the broker and rebuild from those.
Then check two things that your own records cannot tell you. Does every position have a protective order at the exchange, since the crash may have happened between entry and stop placement? And is any resting order now stale, from a signal that is no longer valid?
What is worth persisting locally is the things the broker does not know: which strategy produced which position, what the intended stop was, and the daily loss counter. Keep those separate from position data rather than mixed with it.
What to build first
In order, and the order is the useful part of this article.
1. The data layer. Fetch, cache, sanity-check. Everything depends on it and it is testable immediately.
2. A backtest that subtracts costs. Before any live code. Most ideas die here, and that is the cheapest place for them to die.
3. The risk layer. Before execution, deliberately. Building it after the order code means retrofitting constraints onto something that already works without them, and that rarely happens.
4. Execution, in paper mode. The same code path with the order call swapped for one that records. Now what you are testing is what you will deploy.
5. Observation. Logging and alerts before going live, not after the first time you needed them.
6. Live, at minimum size.
The common failure is building an elegant framework before step two, which produces excellent infrastructure around an idea that never had an edge.
How much structure is too much
A caution, since this article is about structure.
You are one person running a handful of strategies. You do not need a plugin architecture, a message queue, a microservice per layer, or a configuration system that supports environments you will never have. Those are answers to problems teams have.
Five modules in one repository, communicating through plain function calls, with the boundaries above respected, is enough for almost every retail system. The separation is conceptual before it is architectural — what matters is that the strategy cannot place an order, not that the layers live in separate processes.
The right amount of structure is the amount that lets you test each piece alone and change one without breaking another. Beyond that you are building software rather than trading.
Every layer above eventually meets a broker account, which supplies the historical data, the live feed and the order endpoints.
The broker sits under every layer
It is also the source of truth for what you actually hold. Account free to open
The five layers, the paper-mode switch and the restart handling are built step by step in our Algorithmic Trading with Python course at Rs 24,900 — one payment, permanent access, free demo on WhatsApp first.
We sell no tips and no signal group, we manage nobody's money, and we promise no returns. Trading carries a real risk of loss.
Disclosure: the account-opening link on this page is under Atul Shrivastava's Zerodha Authorised Person registration (NSE AP Reg: AP2516003481; Zerodha Broking Ltd. SEBI Reg: INZ000031633) and earns a revenue share. TheFinBaba is not a SEBI-registered Investment Adviser — this content is educational, not investment advice.
Frequently Asked Questions
How should a retail algo trading system be structured?
Five separable layers - data, strategy, risk, execution and observation - with the strategy layer never calling the broker directly. That one boundary lets the same strategy code run in backtest, paper and live modes with only the execution layer swapped.
Why should the strategy not place orders directly?
Because then what you tested is not what you deployed, the risk layer has nowhere to sit, and the strategy cannot be tested without a network. Have it produce signals and let something else decide whether a signal becomes an order.
What belongs in the risk layer?
Position sizing from capital and stop distance, a cap on open positions, exposure limits per sector, a daily loss limit that stops new entries, and a margin check before sending. It must be able to refuse a signal, and it should log what it refused.
What should my program do after a crash?
Read positions and open orders from the broker rather than from its own records, then check that every position has a protective order at the exchange and that no resting order is stale. The broker is the source of truth for what you hold.
What should I build first?
The data layer, then a backtest that subtracts costs, then the risk layer, then execution in paper mode, then logging, then live at minimum size. Building infrastructure before the backtest produces excellent plumbing around an idea that never had an edge.
Do I need a proper framework for retail algo trading?
No. Five modules in one repository communicating through plain function calls is enough. Plugin architectures and message queues answer problems teams have. The separation is conceptual - what matters is that the strategy cannot place an order.
Related Reading
- Backtesting a trading strategy in Python
- Setting up paper trading in India
- Placing orders with Kite Connect in Python
- Risk management in trading
- Common algo trading mistakes
- Algorithmic Trading with Python - full syllabus
Disclaimer: TheFinBaba provides educational content only - this is not investment advice. Trading involves risk of loss.