Join today
Strategies / Mean reversion / Bollinger RSI TDI Reversal

Bollinger RSI TDI Reversal on the FTSE 100

A stretched market is flagged when price closes outside a Bollinger Band, RSI(9) is extreme and the TDI price line is outside its band. The trade opens later, when the TDI price line crosses its signal line back in the reversal direction. An ATR-based stop line then manages the exit.

Mean reversionLong & shortSwingFTSE 100Daily
n/aProfit factor
3,658Net profit EUR
38.49%Win rate
239Trades
-2,267Max drawdown
15.31Avg trade

Best run of 1. FTSE 100, Daily, spread 2, from run sweeps:2026-09-26-FTSE100-D-opt.tsv:4.

Entry rules, long

  1. Setup: close below the lower 20-period Bollinger Band, RSI(9) below 28 and the TDI price line below the lower TDI band
  2. Members only
  3. The ATR stop line is below the close

Entry rules, short

  1. Setup: close above the upper 20-period Bollinger Band, RSI(9) above 62 and the TDI price line above the upper TDI band
  2. Members only
  3. The ATR stop line is above the close

Exit rules

  1. Members only
  2. Close a long when price closes below the stop line
  3. Close a short when price closes above the stop line

Test conditions

PeriodUp to 2026-09-26
InstrumentFTSE 100, Daily
Spread2 points
Contracts1
Starting capital1,000,000
CostsSpread only. Commissions and overnight financing are not included.
BarsUp to 200,000 bars, fewer where the instrument has less history
Last tested2026-09-26

Parameters

positionSize
Contracts per trade
1
bandPeriod
Bollinger Bands length
20
rsiPeriod
RSI length for the extreme reading
9
overboughtLevel
RSI level that arms a short
62
oversoldLevel
RSI level that arms a long
28
stopAtrPeriod
ATR and average length for the stop line bands
14
stopAvgPeriod
Average of highs / lows that flips the stop line side
10
tdiRsiPeriod
RSI length inside the TDI
13
tdiBandPeriod
TDI band length
34
tdiBandWidth
TDI band width in standard deviations
1.6185
priceLinePeriod
TDI price line smoothing
2
signalLinePeriod
TDI trade signal line smoothing
7

Every run

Markets and timeframes tested

MarketTimeframePFTradesWin %NetMax DD
FTSE 100Best runDailyn/a 23938.493,658 EUR-2,267

Charts

Results by run

Net profit against max drawdown

Net profitMax drawdown
0-3K-1K3K5KFTSE 100 · Daily

The code

ProBuilder, rewritten to house standard

Every file in the library uses the same header, the same section order and the same variable names. The numbers above were produced by the original version before the rewrite, and the rewrite has not yet been compiled in ProRealTime.

// ============================================================
// Bollinger RSI TDI Reversal
// ProRealAlgos Strategy Library  |  prorealalgos.com
// Type: Mean reversion
// Direction: Long & short
// Timeframe tested: Daily
// ============================================================

// --- Settings ---
DEFPARAM CumulateOrders = false

// --- Parameters ---
positionSize = 1          // contracts per trade
bandPeriod = 20           // Bollinger Bands length
rsiPeriod = 9             // RSI length for the extreme reading
overboughtLevel = 62      // RSI level that arms a short
oversoldLevel = 28        // RSI level that arms a long
stopAtrPeriod = 14        // ATR and average length for the stop line bands
stopAvgPeriod = 10        // average of highs / lows that flips the stop line side
tdiRsiPeriod = 13         // RSI length inside the TDI
tdiBandPeriod = 34        // TDI band length
tdiBandWidth = 1.6185     // TDI band width in standard deviations
priceLinePeriod = 2       // TDI price line smoothing
signalLinePeriod = 7      // TDI trade signal line smoothing

// --- Indicators ---
upperBand = BollingerUp[bandPeriod](close)
lowerBand = BollingerDown[bandPeriod](close)
rsiValue = RSI[rsiPeriod](close)

// Stop line: an ATR band that only moves in the trade's favour
atrValue = AverageTrueRange[stopAtrPeriod](close)
stopBandHigh = Average[stopAtrPeriod](high + atrValue)
stopBandLow = Average[stopAtrPeriod](low - atrValue)
avgHigh = Average[stopAvgPeriod](high)
avgLow = Average[stopAvgPeriod](low)

IF close > avgHigh THEN
  stopSide = 1
ELSIF close < avgLow THEN
  stopSide = -1
ENDIF
IF stopSide = -1 AND stopBandHigh > stopBandHigh[1] THEN
  stopBandHigh = stopBandHigh[1]
ELSIF stopSide = 1 AND stopBandLow < stopBandLow[1] THEN
  stopBandLow = stopBandLow[1]
ENDIF
IF stopSide = 1 THEN
  stopLine = stopBandLow
ELSE
  stopLine = stopBandHigh
ENDIF

// Traders Dynamic Index
tdiRsi = RSI[tdiRsiPeriod](close)
tdiMid = Average[tdiBandPeriod](tdiRsi)
tdiOffset = tdiBandWidth * STD[tdiBandPeriod](tdiRsi)
tdiUpper = tdiMid + tdiOffset
tdiLower = tdiMid - tdiOffset
priceLine = Average[priceLinePeriod](tdiRsi)
signalLine = Average[signalLinePeriod](tdiRsi)

// Two-step setup flags, kept between bars
ONCE longSetup = 0
ONCE longTrigger = 0
ONCE shortSetup = 0
ONCE shortTrigger = 0

44 more lines: the entry and exit rules.

Read this first

Known weaknesses

  • Only one market and timeframe were tested: FTSE 100 daily.
  • The win rate is 38.49%, so the system relies on winners being larger than losers and can go through long losing streaks.
  • Profit factor was not recorded, because the result comes from optimization sweep data only.
  • The setup flag carries over between bars, so a trigger can fire well after the original stretch, when the market has moved on.

Indicators used

Bollinger BandsRSIATRSMATraders Dynamic Index

How to load it

  1. Copy the code with the copy button above the code block.
  2. In ProRealTime, open a chart of the instrument and timeframe you want to test, then open ProOrder > New trading system and choose "Create with programming".
  3. Paste the code, give the system a name and save it.
  4. Click "Backtest", set your own spread and position size, and run it before you consider trading it live.

Questions

About this strategy

Does this run as an automated system in ProOrder?

Yes. It is coded for ProRealTime automated trading with 1 contract per trade. The original session filter hours were not part of the tested code.

How did it do in the backtest?

On FTSE 100 daily it made EUR 3,658.00 over 239 trades, with a max drawdown of EUR 2,266.60. No other instruments were tested.

How much capital does 1 contract need?

The worst peak to trough drop in testing was EUR 2,266.60 at 1 contract. Margin depends on your broker and is not covered here.

Why daily bars?

The setup needs a close outside the band plus two extreme oscillator readings, which is rare. Daily bars keep those extremes meaningful and the trade count manageable, at 239 trades in the test.

Related

Strategies like this one

Bollinger Squeeze

Uses the same indicator.

14.30 PF · 86 trades

Bollinger Reversal

Best run on the same market, FTSE 100.

1.74 PF · 117 trades

Monday Dip Buy

Also a mean reversion strategy.

n/a PF · 146 trades

Curious how reversal systems like this are combined with others? Get on the ProRealAlgos waitlist.

The ProRealAlgos community gets the full rules, the complete code and the automated portfolio.

Past backtest results do not guarantee future results. This is not financial advice. Curated and maintained by ProRealAlgos. ProRealTime™ is a trademark of ProRealTime SAS. prorealalgos.comStatsDocs