A strategy can be wrong, and a bot has to be built so that being wrong stays affordable. That is what guards are for: hard stops that do not ask the strategy's opinion.
Guards are the part to build first, before any strategy. Here are the six kinds every bot needs, why each one should be independent of the strategy, a checklist you can copy, and a way to test each guard by triggering it in paper mode. This is general practice, not a standard.
The reasoning: a guard must not depend on being right
A strategy's rules answer "should I trade?" A guard answers a different question: "should the bot be allowed to trade at all right now?"
If the guard asks the strategy, it fails in exactly the situations it exists for. A strategy stuck in a repeating error believes it is fine. A strategy fed stale prices believes the prices. So a guard should have three properties:
- It is independent. It counts and checks things the strategy cannot argue with: number of trades, number of errors, age of the last price.
- It is blunt. A cap on live trades does not care whether the signals were good. That is the point.
- It fails towards doing nothing. When the guard cannot check something, the answer is "don't", never "probably fine".
Most serious bot failures are quiet. They are not dramatic crashes but configuration and data errors, and none of them raises an alarm. A guard that does not need the bug to announce itself is the only kind that helps with that.
The six guards at a glance
| Guard | What it stops | Who or what triggers it |
|---|---|---|
| Manual kill switch | Everything, right now | A person |
| Automatic kill | Repeated errors, missing data | The bot's own counters |
| Daily cap on live trades | A strategy firing again and again | A count, checked before every live order |
| Loss limits (per trade, per day) | Losses that pile up | Losses measured in average losses |
| Hours and data-freshness checks | Trading blind or off-hours | Clock and age of last price |
| Paper-or-live routing | A trade going to the wrong place | A decision made once, per trade |
1. The manual kill switch
One control that stops new entries and, in most designs, closes what is open. Three things to insist on:
- It must be one action. If stopping the bot takes four screens, you will hesitate, and hesitation is what it is meant to remove.
- It must not need the strategy's cooperation. It sits above the strategies, not inside one.
- Every press should be recorded with a time. A record of when you intervened is useful later, when you review what happened and why.
A manual switch also has a limit: it needs a person who is looking. That is the reason for the next guard.
2. The automatic kill
An automatic kill acts without a person watching. The idea is simple: something the bot can count crosses a line, and the bot stops.
There are two families. One is money-based, such as a loss limit that halts trading. The other is plumbing-based: a small fixed number of consecutive errors, or a gap in incoming prices, and the bot stands down. If you have to pick one to build first, pick the plumbing kind, because a data problem that turns into a loop is far more common than a strategy that loses in a way no one expected, and a plumbing guard is the kind that stops a loop.
Whichever you choose, the trigger must be something the bot measures itself, not something it has to interpret.
3. The daily cap on live trades
The idea is that no matter what a strategy is doing, only a limited number of live trades can happen in one session. Pick a small fixed number and treat it as a blunt instrument, not a judgement about any strategy.
A cap is a way of deciding, in a calm moment, how much of a bad afternoon you are willing to allow. You cannot make that decision in the middle of one. Enforce it outside the strategies, check it before every live order, and reset it each day.
Keep the counters that guards depend on (trade count, error count) outside the code they limit, for example in a small file or database, so a restart or a strategy bug cannot reset them silently.
Track how often each guard fires. Without that, you cannot tell which guards are decisive and which are merely reassuring, and a guard can be worth having even if it rarely fires.
4. Loss limits: per trade and per day
Two limits, both written before the trade. One option is to express both in average losses rather than currency.
The reason to consider it is that position size tends to change over time, so any currency figure set in one period means something quite different later. "Stop after a small fixed number of typical losses" survives a change in size. A currency number does not. It is the same argument as for judging results in points and ratios: the unit should not move when your size does.
- Per trade: the stop-loss, decided in code before the entry.
- Per day: a limit on how many average losses the bot may take before it stops for the day.
Both are only as good as their enforcement. A stop that sits in a strategy's logic can fail with the strategy, for example through a configuration or data error. That is why the daily limit belongs outside the strategies.
5. Hours and data-freshness checks
A bot can be running and still be blind. A broker token can expire, a price feed can stall, and a stale price looks exactly like a real one. So before the open, and again before each entry, the bot should be able to answer two questions: is it inside trading hours, and is the last price recent?
The rule to follow is that "we could not check" is treated as a failure, not as a pass. If either check fails, the bot does not open a position.
6. Paper-or-live routing
This is the guard people underestimate. Every trade goes to either the paper record or the real broker, and something has to decide which. When that decision is wrong, nothing crashes: a trade you thought was paper is real.
A trade you believe is paper can end up real if the routing decision is wrong, or if it is checked at entry but not at exit. Nothing crashes, so the first sign can be a real order. Check routing at both entry and exit, and make any unclear case default to paper.
The general lessons:
- Fail closed. If the routing cannot work out where a trade belongs, it goes to paper, never live.
- Check both ends. Entry and exit each need the routing check, not just the entry.
- The operator's choice should be final. If you say paper, nothing should be able to overrule you silently.
- Restart after a fix. A change to a running bot generally does not take effect until the process restarts.
How to test each guard by triggering it in paper mode
A guard you have never seen fire is a guess. Before any guard has to work with real orders, trigger it on purpose in paper mode:
- Confirm you really are in paper mode. Check the routing first, with a harmless test order, so that nothing you do next can reach a broker.
- Write down the expected behaviour. For each guard: what should stop, what should stay running, what message should appear.
- Trigger it deliberately. Feed the bot a stale price, raise repeated errors, push the trade count past the cap, or press the kill switch.
- Check that it acted, and only as intended. New entries stop, existing paper positions are handled as designed, and unrelated parts keep running.
- Check the record. The event should leave a trace with a time, so you can tell afterwards that the guard fired rather than the strategy simply having nothing to do.
- Check the reset. Counters that should clear at the next session should clear, and those that should persist should persist.
- Try to get around it. Change a setting mid-session, restart the bot, or send an exit for a paper position. A guard that only works on the happy path is not finished.
- Repeat after every change. Any edit that touches guards or routing deserves the whole list again.
Treat a guard you have not triggered in paper mode as not yet built.
A checklist you can copy
| Guard | Question to answer before going live | Done |
|---|---|---|
| Manual kill switch | Can everything be stopped in one action, in under a few seconds? | [ ] |
| Kill switch record | Is every press recorded with a time? | [ ] |
| Automatic kill | What small fixed number of errors or data gaps makes the bot stand down? | [ ] |
| Daily live-trade cap | Is the cap enforced outside the strategies, and does it reset each day? | [ ] |
| Per-trade loss limit | Is the stop set in code before entry, for the direction actually taken? | [ ] |
| Per-day loss limit | Is it stated in average losses, and does it stop new entries? | [ ] |
| Hours check | Does the bot refuse to trade outside market hours? | [ ] |
| Data-freshness check | Does the bot refuse to trade on a stale price? | [ ] |
| Paper-or-live routing | Does an unclear case go to paper, at entry and at exit? | [ ] |
| Counters | Are the guard counters stored outside the code they limit? | [ ] |
| Testing | Has each guard been deliberately triggered in paper mode? | [ ] |
The algo trading in India guide makes a related point: write the risk layer before the strategy layer.
Practical takeaways
- Build the guards before the strategies. It is tempting to do it in the opposite order.
- Add the daily cap before going live.
- Test routing at exit as well as entry.
- Track how often each guard fires. Without it, any claim about a guard's value is a guess.
Guards will not make a strategy profitable. They only make a bad day survivable, and that is enough reason to build them first.
This post shares general engineering ideas for information only. It is not investment advice, and past results say nothing certain about the future. The author is not registered with SEBI as an investment adviser or research analyst.