Advanced8-12 min readTopic 13 of 20

    Risk Management for Algo Traders

    Rohit Singh

    Mr. Chartist · SEBI RA

    Module Progress
    0/20
    Module

    A discretionary trader's worst day is usually a bad market. An automated trader's worst day is usually a bad piece of software. When a human places orders, every order passes through a person who can notice that something looks wrong; when a program places them, nothing does — a loop that misreads a fill can send a thousand orders while you are still reading the first alert. Risk management for a systematic book therefore has three layers, not one: the market risk you signed up for, the execution risk you inherit from the venue, and the operational risk you built yourself. Only the first of those appears in a backtest.

    The three risk layers an automated strategy carries. A backtest models the first, hints at the second and is completely blind to the third.Three stacked bands. Market risk, with examples such as price moving against the position and a gap through the level, is marked as modelled by a backtest. Execution risk, covering slippage, partial fills and rejections, is marked as only approximated. Operational risk, covering stale quotes, duplicate orders after a retry and a lost connection, is marked as invisible to a backtest because a backtest never places an order.Three risks, one strategywhat the backtest sawMarket riskprice moves against youa gap through your levelthe regime the rule assumed endsMODELLEDthe risk you meant to takeExecution riskslippage on a wide spreada partial fill, stop sized for allan order rejected for marginAPPROXIMATEDonly if you modelled itOperational riskstale quote or a bad tickduplicate order after a retryconnection lost mid-positionINVISIBLEyou built this oneThe largest loss in an automated book is usually the bottom band, not the top one.
    The three risk layers an automated strategy carries. A backtest models the first, hints at the second and is completely blind to the third.

    What changes about risk when a machine places the orders?

    The strategy logic is not the part that changes. A breakout rule with a stop below the range is the same idea whether you type the order or your code sends it. What changes is everything around the idea.

    A human is a slow, unreliable, but genuinely useful circuit breaker. You cannot type two hundred orders in a minute. You would notice if the quantity field said 25,000 instead of 250. You would stop after the fourth loss of the morning even if no rule told you to. Automation removes all three of those accidental protections at once, and gives you nothing back unless you write the replacement yourself.

    That replacement is a set of limits that sit between the strategy and the broker, and refuse orders the strategy is perfectly happy to send. They are part of the strategy. A system without them is not a finished system that happens to lack safety features — it is an unfinished system.

    Note — This page is education, not advice. Nothing here is a recommendation to trade, to automate, or to use any particular limit value. Every number below is illustrative arithmetic on round figures.

    What are the three kinds of risk an automated strategy carries?

    Keeping these separate matters, because each one has a different owner, a different failure mode and a different control. Collapsing them into a single word — 'risk' — is how systems end up with a stop-loss and nothing else.

    Market risk
    The price moves against the position. This is the risk the strategy exists to take, it is the only one a backtest models properly, and it is controlled by the stop and — far more — by the position size. It is also the least interesting of the three, because it is the one you already understand.
    Execution risk
    The gap between the trade in your research and the trade you actually got. Slippage on a wide spread, a market order filled far from the last traded price, a partial fill that leaves you with a fraction of the intended position and a stop sized for the whole of it, an order rejected for margin at the exact moment you needed it. The strategy was right; the fill was not what the test assumed.
    Operational and technical risk
    Your infrastructure misbehaves. A stale quote, a bad tick, a duplicate order after a retry, a session token that expires mid-session, the connection dropping while you are holding a position, the clock on your machine drifting, a deployment that ships an untested change into live money. Nothing was wrong with the market or the venue. Something was wrong with you.

    Watch out — The third category is the one people leave out, and it is the one most likely to produce the single largest loss in an automated book's life. A market move is bounded by the stop you placed. A bug that keeps re-placing an order is bounded by nothing until something external stops it.

    Why is a stop-loss not enough on its own?

    A stop-loss protects one position against one kind of event: price moving through a level while your system is working correctly. It assumes the order reaches the exchange, that it is for the quantity you think you hold, and that your record of the position is accurate.

    Every operational failure breaks one of those assumptions. If your program thinks it is flat and the broker thinks you are long 400 shares, the stop was never placed against anything. If a retry created two entries instead of one, the stop covers half the exposure. If the connection dropped after the entry and before the exit order, there is no stop at all — only a position and a hope.

    This is why automated risk control is layered. The stop handles the price. Something else has to handle the software.

    What are pre-trade risk limits, and which ones are non-negotiable?

    A pre-trade limit is a check that runs on every order after the strategy has decided to send it and before it leaves your machine. It knows nothing about the setup. Its only job is to ask whether this order is even plausible.

    The useful mental model is an airlock. The strategy is free to be wrong about the market — that is allowed, and it is priced in. The airlock exists to catch the orders that are not wrong about the market but wrong about arithmetic.

    Every order passes the same gates before it reaches the broker. A gate that has never rejected anything is not proof the system is safe — it is untested code sitting in the critical path.A signal from the strategy enters a stack of six checks: instrument whitelist, maximum order size, orders-per-minute throttle, duplicate order guard, portfolio heat and daily loss cap. An order that fails any check is rejected and logged rather than sent. Only an order passing all six reaches the broker and the exchange. A kill switch sits beside the stack and can disable the whole path in one action.STRATEGY SIGNALfree to be wrong about price1Whitelistsymbol in the tested universe?2Max order sizequantity and value plausible?3Throttleorders per minute under cap?4Duplicate guardthis client id seen before?5Portfolio heattotal open risk still under cap?6Daily loss capday still inside the tripwire?REJECTED + LOGGEDwith the reason, so arejection is evidenceKILL SWITCHone action, disables the pathSENT TO BROKER, THEN THE EXCHANGEA gate that has neverrejected anything isuntested code in thecritical path.
    Every order passes the same gates before it reaches the broker. A gate that has never rejected anything is not proof the system is safe — it is untested code sitting in the critical path.

    Which pre-trade limits belong in every automated system?

    LimitWhat it catchesHow the value is usually set
    Max order quantityA sizing bug, a decimal in the wrong place, a divide by a stop distance that came through as zeroA multiple of the largest position the strategy is ever designed to hold — not a round number you liked
    Max order valueThe same bug on an expensive instrument, where a plausible quantity is an implausible rupee amountAnchored to account equity, so it scales when the account does
    Max orders per minuteA runaway loop, a retry storm, a signal that flickers on and off across one candle boundaryA small multiple of the busiest minute the strategy could legitimately have
    Max open positionsA universe scan that fires on forty names at once because a filter silently stopped workingThe number the capital and the margin can actually support at the same time
    Max total open riskIndividually reasonable positions that together are one large betCovered in Position Sizing & Portfolio Construction — this is portfolio heat
    Max daily lossA bad regime, a broken assumption, or a bug that is losing money quietly and correctly-lookingA drawdown you have decided in advance you will stop and investigate at
    Duplicate order guardThe same signal acted on twice, usually after a reconnect or a retryA client-side order id per signal, rejected if seen before
    Instrument whitelistAn order for a symbol the strategy was never tested on, usually after a data-file changeThe exact tradable universe from the rulebook, loaded fresh each session

    Where should these limits live?

    Not inside the strategy. A limit that lives in the same function as the signal gets edited when the signal gets edited, and the edit that breaks it is the same edit that needed it.

    Put the checks in a separate layer that every order passes through, with no access to the strategy's reasoning. It should be boring, small, heavily tested, and changed almost never. If you run more than one strategy, this layer is shared — the daily-loss limit for the account is an account-level number, not something each strategy tracks privately.

    Your broker also runs its own checks, and the exchange runs more. Those are a backstop, not your risk system: they exist to protect the broker and the market, and they are calibrated for that, not for your account's survival.

    Pro tip — Test the limits the way you would test the strategy. Send a deliberately oversized order in a paper environment and confirm it is rejected and logged. An untriggered safety check is a claim, not a control.

    What is a kill switch, and what should it actually do?

    A kill switch is one action that stops the system. It has to be usable in the worst thirty seconds of your trading life — by a person who is frightened, on a phone, possibly on a bad network. That constraint rules out anything requiring you to find a config file and redeploy.

    The design question people get wrong is what 'stop' means. There are three different answers and you need to have decided which one you want before you need it.

    1. 1

      Stop opening

      New entries are refused; existing positions and their exits keep running. This is the mildest form and the one most often correct when the concern is the strategy rather than the plumbing.

    2. 2

      Stop everything and cancel resting orders

      No new orders of any kind, and every open order is pulled. Positions remain. This is the right response when you suspect the software rather than the market, because it stops the machine from acting without deciding your positions for you.

    3. 3

      Flatten

      Cancel everything and exit every open position at market. The most drastic, and the most dangerous to automate: a flatten triggered by a data glitch will exit real positions into whatever liquidity exists at that second.

    4. 4

      Then, always: reconcile before restarting

      After any kill, the first action is not restarting. It is comparing what your system believes it holds against what the broker says you hold. Restarting a system whose state is wrong is how one incident becomes two.

    Watch out — A kill switch that has never been used is untested. Pull it deliberately in a paper environment, and at least once in a live session at a moment of your choosing, so that the first time it runs is not the first time it matters.

    What is reconciliation, and why is it a daily job?

    Reconciliation is the comparison between your system's record of the world and the broker's record of the world: positions, quantities, average prices, open orders, and cash or margin used. In a manual account you do this by glancing at the positions tab. In an automated account nobody glances at anything, so it has to be a scheduled step that produces a pass or a fail.

    The reason it matters is that your program does not trade the market. It trades its own internal model of your position. Once that model and reality disagree, every subsequent decision is computed from a fiction — including the exits.

    Four ways a local position record drifts from the broker's. Each one is silent: the strategy keeps running, and every order it sends afterwards is sized from the wrong number.Four rows compare what a trading program believes it holds with what the broker's books say. A partial fill leaves the program thinking three hundred when one hundred and eighty traded. A retry after a timeout doubles the position at the broker. A manual exit in the broker's app leaves the program still holding a position that is closed. A restart that lost in-memory state leaves the program flat while a position is still open. Each mismatch is silent, and every order sent afterwards is sized from the wrong number.What your code believes, versus what you holdYOUR RECORDTHE BROKERPartial fillLONG 300LONG 180SILENTRetry after timeoutLONG 250LONG 500SILENTManual exit in the appLONG 400FLATSILENTRestart, state in memoryFLATLONG 120SILENTA failed reconciliation halts the system. It never overwrites its own record and carries on.
    Four ways a local position record drifts from the broker's. Each one is silent: the strategy keeps running, and every order it sends afterwards is sized from the wrong number.

    How do positions and reality drift apart?

    • A partial fill. You sent 300, 180 filled, the rest was cancelled at close. Your code recorded the order, not the fill. Position is the running sum of fills — never the sum of orders sent.
    • A retry after a timeout. The first request actually reached the broker; the acknowledgement did not reach you. You retried, and now there are two orders and one of them is invisible to your records.
    • A manual intervention. You exited something from the broker's app during the session and the program never knew. Perfectly reasonable human behaviour, fatal to an automated position record.
    • A restart. The process died and came back with an empty position dictionary, because state was held in memory and nothing was persisted.
    • A corporate action. A split, bonus or demerger changes the quantity and the price on the broker's books overnight. Your record still holds the pre-action numbers.
    • A rejected exit you never checked. The order was sent, the broker refused it, and nothing in your code reads the rejection, so the position is still open and your system has already moved on.

    How should a reconciliation step behave when it fails?

    It should stop the system, not correct it. The tempting design is to have the program overwrite its own record with the broker's and carry on. Do not — that turns a loud fault into a silent one and destroys the evidence you need to find the cause.

    A failed reconciliation should refuse to start the next session, alert you through a channel you actually read, and preserve both versions of the record. The correct sequence is investigate, then fix by hand, then restart. It is slower, and slower is exactly the point.

    Run it at least at start-up and at end of day. If your strategy holds intraday positions, run it after every fill as well: comparing after each event is what makes the eventual discrepancy traceable to a single order rather than to a whole session.

    What Indian market realities change the risk picture?

    The mechanics of NSE and BSE trading add constraints that a generic algorithmic-trading text will not mention, and that a backtest built on close prices will not enforce.

    • Product types are not interchangeable. Intraday and delivery products differ in leverage, in margin treatment, and in what the broker does if you do nothing — an intraday position left open can be squared off by the broker's own system, at a time and price you did not choose. Your code must know which product it is using.
    • Auto square-off exists and it is not your exit. If a broker's cut-off is what closes your intraday position, the exit price is the market's, not your strategy's, and your records will show an exit you never sent.
    • Price bands and circuit limits can freeze an instrument for the session. An order at a price outside the band is rejected, so a strategy that expects to always be able to exit at its stop is assuming something the exchange does not guarantee.
    • Gaps happen on results, board meetings, block deals, rating changes and regulatory news. A stop is an order, not a floor. Position size — not the stop — is the only defence against a gap through the level.
    • Margin requirements, peak-margin treatment and exposure limits change over time and by segment. Do not hard-code them from a blog post, this one included. Read the current specification at the exchange and confirm the applied numbers with your broker.
    • Automated order placement through a broker's interface sits inside SEBI's evolving framework for algorithmic trading and broker API access. Requirements around approvals, tagging and static-versus-dynamic strategies do change — verify the current position with your broker before deploying anything automated.

    Note — Regulatory and margin specifics are stated here by shape only, deliberately. Anything numeric in this area has a shelf life. Treat the exchange circular and your broker's current documentation as the source of truth.

    How much should a systematic trader risk per trade?

    There is a widely used convention of risking a small fraction of equity — often quoted as somewhere between a half and two per cent — on any single idea. It is worth understanding why the convention exists rather than adopting the number.

    The reasoning is loss-streak arithmetic, and it is arithmetic, not a claim about outcomes. Any rule that produces a stream of trades will produce consecutive losses, and the smaller the fraction risked, the more consecutive losses the account can absorb before the remaining capital is too small for the strategy to work with. Recovery is the other half: the deeper the drawdown, the more disproportionate the gain needed to return to the starting figure, purely because you are computing the gain on a smaller base.

    Gain required to recover = 1 ÷ (1 − drawdown fraction) − 1
    • A 10% drawdown needs about an 11% gain on the remaining capital.
    • A 25% drawdown needs about a 33% gain.
    • A 50% drawdown needs a 100% gain — you must double what is left.
    • This is definitional arithmetic on a smaller base. It says nothing about whether any gain is achievable.

    Watch out — The specific fraction is your decision, not this page's. It depends on your capital, your instruments, how many strategies you run at once, how correlated they are, and how much of a drawdown you can sit through without changing the rules — which is the variable that actually breaks systems.

    How do you decide the daily loss limit?

    A max-daily-loss limit is not a prediction that you will lose that amount. It is a tripwire: the point at which you have decided, in advance and calmly, that the day is no longer normal and deserves a human looking at it.

    Set it in the same units the rest of your risk is set in. If a single idea risks one unit, a day that has lost several of those units in a way the strategy was never designed to produce is a signal about the system, not the market. Pick the number when nothing is happening, write it into the limit layer, and do not raise it during a session — a limit you can edit while losing is a suggestion.

    What happens when it trips is the part to think about. 'Stop opening' is usually right. Automatically flattening on a loss limit converts a bad day into a guaranteed realisation of that day at whatever price exists at the moment the tripwire fires.

    What should you log, and what should alert you?

    Logging and alerting are risk controls, because an automated system's failure mode is silence. It does not stop. It keeps producing plausible output while doing the wrong thing.

    The minimum record for every automated session

    • Every signal generated, including the ones the limit layer refused — with the reason for refusal.
    • Every order sent, with your own client-side id, and every response received, including rejections.
    • Every fill, with quantity and price, kept separately from the orders that produced them.
    • The data snapshot the decision was made from, so a bad tick can be reconstructed later rather than argued about.
    • The result of every reconciliation run, pass or fail, with both versions of the position record when it fails.
    • A heartbeat that proves the system is alive — and an alert when the heartbeat stops, which is the only way you learn that nothing is running.

    Pro tip — Alert on the absence of expected activity, not only on errors. A crashed process raises no error at all from the outside; it just goes quiet, and quiet is indistinguishable from a calm day unless something is watching for the heartbeat.

    What invalidates your risk framework?

    A risk system, like a strategy, has to say what would prove it insufficient. These are the signs it has stopped doing its job.

    • A single loss larger than the maximum your limits should have permitted. Not a bad trade — a broken control. Stop and find it before trading again.
    • A reconciliation failure you patched by overwriting your records rather than by finding the cause.
    • A limit you raised during a live session. The number you set when calm was the honest one.
    • A kill switch you have never pulled, or that depends on infrastructure that would also be down in the scenario requiring it.
    • Orders that reached the broker without passing the limit layer, usually because a new strategy was wired directly to the API 'just for testing'.
    • Any position in the account that your system cannot account for. Even one, even small — it means the model and reality have diverged and you do not yet know how.

    Key points

    Automation removes the human circuit breaker; the limits that replace it are part of the strategy.
    Three distinct risks: market, execution, and operational — only the first is modelled in a backtest.
    The largest loss in an automated book's life is usually a software fault, not a market move.
    A stop protects one position and assumes your position record is correct. Often it is not.
    Pre-trade limits belong in a shared layer no strategy can bypass or edit for itself.
    A kill switch has three meanings — stop opening, stop and cancel, or flatten. Decide before you need it.
    Reconcile local state against the broker at start-up, at end of day, and after every fill.
    A failed reconciliation should halt the system, not silently overwrite its own records.
    Product type, auto square-off, price bands and gaps are Indian-market constraints a backtest ignores.
    Alert on silence. A crashed process raises no error — it just stops, and looks like a quiet day.

    Pro tip — Once your limit layer exists, deliberately break your own system in a paper environment: send an order ten times the maximum size, fire the same signal twice, kill the process while a position is open, and let the reconciliation run afterwards. The list of things that did not behave as you expected is the actual state of your risk management — everything else is a description of it.

    Frequently asked questions

    What is the biggest risk in algorithmic trading?

    For most automated books it is operational rather than market risk. A losing trade is bounded by the position size and the stop you chose. A software fault — a retry loop, a stale price, a duplicate order, a position record that has drifted from the broker's — is bounded by nothing until an external limit stops it. This is why pre-trade limits, a kill switch and a reconciliation step are treated as parts of the strategy rather than as operational extras.

    What pre-trade risk checks should an algo trading system have?

    At minimum: a maximum order quantity and a maximum order value, a cap on orders per minute, a cap on simultaneous open positions, a cap on total open risk across the book, a maximum daily loss, a duplicate-order guard keyed on your own client-side order id, and a whitelist of the instruments the strategy is allowed to trade. They should live in a separate layer that every order passes through, not inside the strategy code itself.

    What is a kill switch in algo trading?

    A single action that stops the system, usable in seconds and without a redeployment. It has three possible meanings and you should decide which you want in advance: stop opening new positions while exits continue; stop all activity and cancel resting orders while positions remain; or flatten everything at market. Whichever you choose, the first step after a kill is reconciling your position record against the broker's, before anything restarts.

    Why do I need to reconcile positions if the broker API reports them?

    Because your program does not act on the broker's numbers, it acts on its own internal record — and the two drift. Partial fills, retries after a timeout, manual exits you made in the broker's app, a process restart that lost in-memory state, and corporate actions all change one side without the other. Once the records disagree, every later decision, including the exits, is computed from the wrong quantity.

    How much should I risk per trade in a systematic strategy?

    That is your decision, and it depends on your capital, your instruments, how many strategies run at once and how correlated they are. The commonly cited convention of risking a small fraction of equity per idea exists because of loss-streak and recovery arithmetic: consecutive losses are certain to occur in any rule-based stream, and the deeper a drawdown goes the more disproportionate the gain needed to return to the starting figure — a 50% drawdown requires doubling what remains.

    Does a backtest capture execution and operational risk?

    No. A backtest models market risk, approximates execution risk only to the extent you deliberately modelled costs, slippage and partial fills, and is completely blind to operational risk because it never places an order, never loses a connection and never disagrees with a broker about what you hold. A result that looks robust in research says nothing about how the system behaves the day a token expires mid-session.

    Is automated trading allowed for retail traders in India?

    Retail access to broker APIs and automated order placement exists and sits inside SEBI's framework for algorithmic trading, which has been revised more than once — including the treatment of broker-provided APIs, strategy approval and order tagging. The specifics change, so verify the current requirements with your broker and against the current SEBI and exchange circulars rather than relying on any article's summary, including this one.