
Algorithmic Trading 101: Strategies, Backtesting & Risk Management
A practitioner-oriented course covering the core building blocks of systematic trading: how to backtest without fooling yourself, the statistics behind mean-reversion and momentum strategies, and how to size positions and manage risk so a good strategy doesn't blow up your account.
Course Syllabus
5 / 10Chapter 5: Building a Mean-Reversion Strategy
Chapter 5: Building a Mean-Reversion Strategy
In Chapter 4, we built the statistical toolkit to answer one question: does this price series (or combination of series) actually mean-revert? We learned to use the ADF test, the Hurst exponent, half-life, and cointegration to separate genuine candidates from random walks dressed up as opportunities.
But statistics alone don't make you money. Knowing that a spread between two PSU banks is cointegrated with a half-life of 12 days doesn't tell you exactly when to buy, when to sell, or how much capital to risk. This chapter closes that gap β turning statistical evidence into a concrete, tradable, risk-bounded strategy.
Why this chapter matters: There's a wide gulf between 'this series is statistically mean-reverting' and 'this is a strategy I can actually run with real capital.' This chapter builds that bridge using three tools β Bollinger bands, scaling-in, and the Kalman filter β while keeping a constant eye on the overfitting trap from Chapter 1.
1. From Statistics to a Trading Rule
Let's start with the simplest possible way to trade a mean-reverting series, because understanding why it's too simple is instructive.
The Naive Linear Approach
Once you've confirmed (using Chapter 4's tools) that a series β say, the cointegrated spread between HDFC Bank and ICICI Bank β is genuinely mean-reverting, the most basic possible trading rule is: hold a position sized in direct proportion to how far the price has deviated from its moving average. The further the spread strays from its mean, the larger your position; as it reverts, you continuously scale your position back down toward zero.
This is elegant in theory β it's essentially 'parameterless' (no arbitrary entry/exit thresholds to tune), which makes it attractively resistant to the data-snooping bias we discussed in Chapter 1. And it does work, in the sense that it can produce a positive equity curve on a genuinely mean-reverting series.
But it has a critical flaw: it implies no cap on position size. If the spread deviates further than it ever has historically, this rule asks you to keep adding capital indefinitely, with no defined maximum exposure. No serious trader can run a strategy with unlimited, unbounded position sizing β you need a rule that tells you exactly when to be in the market, when to be out, and what the maximum capital at risk will ever be.
Note: The naive linear approach is a useful diagnostic β if it produces a positive equity curve on your candidate series, that's a good sign the underlying mean reversion is real and exploitable. But it's rarely a practical strategy on its own. This is exactly why we need Bollinger bands.
2. Bollinger Bands: The Practical Workhorse
The Core Rule
Bollinger bands convert the naive linear idea into a bounded, risk-manageable strategy by defining explicit entry and exit thresholds, measured in standard deviations (Z-scores) away from a moving average:
- Entry threshold (entryZscore): Enter a position only when the price (or spread) deviates by more than this many standard deviations from its moving average.
- Exit threshold (exitZscore): Exit the position once the price reverts back to within this many standard deviations of the mean.
At any given time, you hold either zero or one unit of position (long or short) β never an unbounded, continuously scaling amount. This makes both capital allocation and risk management dramatically simpler than the naive linear approach.
Classic Example: Consider a cointegrated spread between Britannia Industries and NestlΓ© India β two FMCG majors whose businesses share substantial economic overlap (packaged foods, similar input cost exposure, similar consumer demand drivers). Suppose your half-life calculation from Chapter 4 suggests a 15-trading-day look-back window. You set
entryZscore = 1: whenever the spread moves more than 1 standard deviation away from its 15-day moving average, you enter a position betting on reversion. You setexitZscore = 0: you exit once the spread reverts all the way back to its moving average. Every trade has a clearly defined entry trigger, exit trigger, and β critically β a bounded position size of exactly one unit.
Choosing entryZscore and exitZscore
The relationship between your two thresholds shapes your strategy's character:
- If exitZscore = 0, you exit precisely when the spread returns to its current moving average.
- If exitZscore is negative (specifically, the mirror image of your entry threshold), you're holding the position until it swings all the way through the mean and triggers an opposite signal β effectively flipping from long to short (or vice versa) without ever sitting flat.
- Shorter look-back periods combined with smaller entry/exit thresholds tend to produce more frequent round-trip trades and shorter holding periods β generally a higher trade count (which, recalling Chapter 2, gives you more statistical confidence in your backtest) but also higher transaction costs relative to profit per trade.
Warning: It's tempting to treat
entryZscoreandexitZscoreas free parameters to optimize via brute-force backtesting β trying every combination from 0.5 to 3.0 in small increments until you find the 'best' one. Resist this urge. As covered in Chapter 1, excessive parameter tuning on a single historical dataset is a textbook data-snooping trap. A far more disciplined approach is to anchor your look-back period to the half-life derived in Chapter 4, and choose round, sensible entry/exit thresholds (like 1 and 0, or 2 and 0) rather than hunting for a suspiciously 'optimal' decimal value.

3. Does Scaling-In Actually Work?
The Trader's Instinct
Many traders β even those using a Bollinger band framework β feel a strong pull toward scaling-in (also called averaging-in): as the price moves further from the mean, the case for reversion seems to strengthen, so why not add to the position incrementally rather than committing all your capital in a single entry?
This is, in essence, a partial return to the naive linear approach from Section 1 β just applied at discrete steps (say, adding a fixed increment every additional 0.5 standard deviations of further deviation) rather than continuously.
The Honest Answer: It's Complicated
- In pure backtests, scaling-in is often not clearly optimal. It reintroduces some of the same unbounded-exposure character as the naive linear rule, and a well-tuned single-entry Bollinger band strategy frequently backtests just as well, if not better, with far simpler position management.
- In live trading, many practitioners still find scaling-in genuinely useful β because real market volatility and the true probability of reversion do shift over time in ways a static historical backtest can't fully capture. A single fixed entry point assumes the 'best' entry Z-score is constant across all market regimes, which isn't strictly true.
Classic Example: During a period of unusually high volatility β say, around a Union Budget announcement or a surprise RBI repo rate decision β a cointegrated spread might swing to 2.5 standard deviations from its mean and keep going to 3.5 before reverting, simply because overall market volatility has temporarily expanded. A trader using scaling-in who added incrementally at 1, 2, and 3 standard deviations would have built a larger, better-positioned trade to capture the eventual reversion, compared to a trader who entered fully at the 1-standard-deviation mark and then had to sit through a much larger drawdown before the position finally worked.
Note: There is no single 'correct' answer here β this is a genuine, honest trade-off. The disciplined approach is to test scaling-in explicitly as its own variant (with the same rigor from Chapter 2: does it hold up under Monte Carlo and trade-randomization testing, not just raw backtested return?) rather than adding it reflexively because it 'feels' safer.
4. The Kalman Filter: Adapting to a Changing World
The Problem with Fixed Look-Back Windows
Every mean-reversion strategy so far has relied on a moving look-back window to calculate the hedge ratio, moving average, and standard deviation. But fixed windows have an awkward property: as time moves forward and the window slides, the oldest data point drops out and a new data point enters, which can cause abrupt, sometimes artificial jumps in your calculated hedge ratio or mean β especially if the look-back window is short.
Classic Example: Suppose you're calculating a rolling 20-day hedge ratio between a Gold ETF and Titan Company (recall this cointegrated pair from Chapter 4). If day 21 happens to be an unusually volatile session β say, a day with a large, sudden move in global gold prices β then as your 20-day window slides forward and eventually drops the corresponding old data point 20 days later, your hedge ratio can jump abruptly, even though nothing fundamental about the Titan-gold relationship actually changed. This is an artifact of the fixed-window mechanism, not a real shift in the underlying relationship.
The Kalman Filter Solution
The Kalman filter is an optimal, principled way to continuously update an estimate β such as a hedge ratio, or a spread's fair-value mean β based on each new incoming data point, without relying on an arbitrarily chosen fixed window or an arbitrarily chosen decay rate (as in a simple exponential moving average).
At a conceptual level, a Kalman filter setup requires you to define:
- An observable variable β something you can directly measure, like today's price of one instrument in the pair.
- A hidden variable β something you want to estimate but can't observe directly, like the 'true' current hedge ratio.
- A relationship connecting the two, plus an assumption about how much the hidden variable is expected to drift over time.
Given these ingredients, the Kalman filter produces a continuously updated, smoothly evolving estimate of the hidden variable (the hedge ratio) that automatically weights recent data more heavily than older data β but does so through a mathematically optimal weighting scheme, rather than an arbitrary rule like 'use the last 20 days' or 'decay by 5% each day.'
Classic Example: Applying a Kalman filter to the Gold ETFβTitan pair means the hedge ratio updates smoothly, day by day, as new price data arrives β gracefully adapting if Titan's gold-price sensitivity gradually shifts (say, due to a change in the company's product mix or hedging policy) without the abrupt, artificial jumps a fixed 20-day rolling window would produce.
Warning: The Kalman filter is a genuinely more sophisticated tool than a rolling window, and it comes with a real cost: added model complexity. As traders, we don't need to derive the underlying mathematics from scratch β reliable software libraries handle the computation β but we do need to be honest with ourselves about whether the added complexity is earning its keep. If a simple rolling-window approach and a Kalman filter approach produce very similar backtested results, the simpler rolling-window version is often the better choice in production, purely because it's easier to understand, debug, and explain when something goes wrong.

5. The Overfitting Trap: Keeping Your Model Honest
This chapter has introduced three tools of increasing sophistication β Bollinger bands, scaling-in, and the Kalman filter β and it's worth pausing to connect this directly back to Chapter 1's central warning about data-snooping bias.
More Parameters, More Danger
Each tool we've added comes with its own tunable parameters:
- Bollinger bands: look-back window, entryZscore, exitZscore.
- Scaling-in: number of scale-in steps, size of each increment.
- Kalman filter: assumptions about how quickly the hidden variable (hedge ratio) is expected to drift over time.
Golden Rule: Every additional parameter you introduce is another dial that can be β consciously or unconsciously β tuned to fit historical noise rather than a genuine, persistent market relationship. The more parameters your strategy has, the more historical data you need to have any confidence that its backtested performance reflects a real edge rather than overfitting.
A Practical Discipline for This Chapter's Tools
- Anchor your look-back window to the half-life calculated in Chapter 4, rather than testing dozens of arbitrary values.
- Start with the simplest version first. Build and backtest the basic Bollinger band strategy before adding scaling-in or a Kalman filter. Only add complexity if it produces a meaningfully and robustly better result β not just a marginally higher backtested return that could easily be noise (recall the statistical significance tools from Chapter 2).
- Re-validate added complexity with out-of-sample testing. If scaling-in or the Kalman filter improves your in-sample backtest but doesn't hold up on a genuinely untouched out-of-sample period, the added complexity was likely fitting noise, not signal.
- Ask 'why' at every step. Can you articulate, in plain economic terms, why a Kalman filter's adaptive hedge ratio should genuinely outperform a simple rolling window for this specific pair? If the honest answer is 'I'm not sure, but it backtested better,' treat that result with real suspicion.
Note: Chan's broader philosophy, echoed throughout this course, is that simple linear models resist overfitting better than complex ones β precisely because they have fewer parameters to accidentally fit to historical noise. The tools in this chapter should be seen as a toolbox to reach for when genuinely needed, not a checklist to apply indiscriminately to every strategy.
6. A Worked Example: Building the Full Strategy Step by Step
Let's tie the whole chapter together with a single illustrative walkthrough.
The Setup: You've identified, using Chapter 4's tools, that a weighted spread between HDFC Bank and ICICI Bank is cointegrated, with an ADF test confirming reversion at the 95% confidence level and a calculated half-life of 14 trading days.
- Choose your look-back window. Set it to 14 days, matching the half-life β avoiding an arbitrary round-number choice like 10 or 20 days.
- Build the basic Bollinger band rule. Set
entryZscore = 1andexitZscore = 0. Backtest this simple version first, being careful to avoid the pitfalls from Chapter 1 (no look-ahead bias, realistic slippage and brokerage costs, split/dividend-adjusted data). - Validate statistical significance. Apply Chapter 2's tools β hypothesis testing, Monte Carlo simulation, and trade-randomization β to confirm the backtested edge isn't just noise.
- Test scaling-in as a variant. Build a second version that adds to the position incrementally at 1, 2, and 3 standard deviations. Compare its out-of-sample performance honestly against the simple version β don't just eyeball the in-sample equity curve.
- Consider a Kalman filter only if the fixed 14-day window shows visible instability. If your hedge ratio is jumping around abruptly as the rolling window slides, and this instability is visibly hurting live-style walk-forward performance, that's a legitimate signal to invest in the added complexity of a Kalman filter. If the fixed window is stable and performing consistently, there may be little benefit to adding this complexity.
- Settle on the simplest version that passes all validation steps. If the basic Bollinger band strategy, scaling-in variant, and Kalman filter variant all perform similarly once properly out-of-sample tested, choose the simplest one β fewer moving parts means fewer places for bugs, transcription errors (Chapter 3), or future overfitting to creep in.
7. Key Takeaways
- The naive linear mean-reversion rule (position size proportional to Z-score) is a useful diagnostic for confirming genuine mean reversion, but is impractical on its own due to unbounded position sizing.
- Bollinger bands convert this into a practical, risk-bounded strategy using explicit entry and exit Z-score thresholds, holding a single defined position size at a time.
- Anchor your look-back window to the half-life from Chapter 4 rather than brute-force optimizing entry/exit thresholds, to avoid the data-snooping trap from Chapter 1.
- Scaling-in isn't clearly optimal in backtests but can genuinely help in live trading, since real market volatility and reversion probabilities shift over time β test it explicitly rather than assuming it's automatically better or worse.
- The Kalman filter offers a principled, adaptive alternative to fixed rolling windows for estimating hedge ratios and fair values, avoiding the abrupt jumps a rolling window can produce β but its added complexity should be justified by genuine, out-of-sample-validated improvement, not just a better in-sample backtest.
- Throughout this chapter's toolkit, the guiding discipline is the same one from Chapter 1: prefer the simplest model that does the job, since every additional parameter is another opportunity to overfit to historical noise rather than capture a real, persistent market relationship.
Coming up in Chapter 6: With mean-reversion strategy-building tools in hand, we turn to the second great family of trading strategies: momentum. We'll explore both time-series and cross-sectional momentum, and dig into what actually drives it β including roll returns, forced fund flows, and the slow diffusion of information through the market β building simple, rank-based long-short momentum strategies along the way.