Tested by BacktestingMax
RSI divergence strategy backtest
Does the RSI divergence strategy make money?
Mostly no: only 5 of our 24 backtests of RSI divergence made money. RSI is an indicator that scores how hard price has moved, from 0 to 100. In a bullish divergence, price makes a lower low (it falls below its last low), but RSI makes a higher low. A bearish divergence is the opposite: a higher high in price, with a lower high in RSI. We bought bullish divergences and sold short bearish ones (sold first, to profit from a fall) on 8 markets: 4 currency pairs, gold and 3 stock indices. Each market ran on 15-minute, 1-hour and 4-hour charts (24 backtests), from 2014 to 2025, after trading costs (the spread; overnight fees are not included). All 5 tests that made money were on 1-hour or 4-hour charts. Only the DAX (the German stock index), on its 1-hour and 4-hour charts, made money in both the older years (2014–2021) and the newer years (2022–2025). Waiting for confirmation did not help. For a buy, confirmation means waiting for a candle to close above the highest price between the two lows. With confirmation, only 1 of the 24 tests made money.
24 backtests 2014–2025 Trading costs included Tested 12 October 2026
Where it worked 24 backtests- Made money
- 5 of 24 tests, using the standard rules
- Made money in both periods
- 2 2014–2021 and again 2022–2025
- Best backtest
- +49% DAX, 1-hour chart: account growth 2014–2025
- Waiting for confirmation
- 0 tests made money in both periods, compared with 2 using the standard rules
Made money in both periods
- DAX, 1-hour
- DAX, 4-hour
Lost money on every market
- 15-minute charts
The results
Results on every market
Each box shows one backtest of the RSI divergence strategy using the standard rules, from 2014 to 2025, after trading costs: the % result, and a small chart of the account balance. The solid line is the account balance and the dashed line is the starting balance. Green results made money; red results lost money. Under each result: whether it made money in both 2014–2021 and 2022–2025, or passed all four of our checks (see "How a test passes" further down).
| Market | 15-minute | 1-hour | 4-hour |
|---|---|---|---|
| EUR/USD | −92% Lost money. Account down 90% by Dec 2023 | −41% Lost money | −27% Lost money |
| GBP/USD | −85% Lost money | +0.1% Made money overall, lost in one period | −20% Lost money |
| USD/JPY | −80% Lost money | +2% Made money overall, lost in one period | +2% Made money overall, lost in one period |
| AUD/USD | −94% Lost money. Account down 90% by Apr 2022 | −31% Lost money | −12% Lost money |
| Gold | −95% Lost money. Account down 90% by Jun 2021 | −34% Lost money | −26% Lost money |
| S&P 500 | −77% Lost money | −53% Lost money | −23% Lost money |
| Nasdaq 100 | −94% Lost money. Account down 90% by May 2024 | −69% Lost money | −13% Lost money |
| DAX | −81% Lost money | +49% Made money in both periods | +16% Made money in both periods |
All the numbers, test by test
| Market | Chart | Trades | Win rate | Profit factor | Result | Max drawdown | 2014–2021 | 2022–2025 | Monte Carlo drawdown | Trading costs |
|---|---|---|---|---|---|---|---|---|---|---|
| EUR/USD | 15-minute | 2,558 | 35.4% | 0.87 | −91.6% | −92.4% | −83.6% | −48.7% | −94.3% | $6,778 |
| EUR/USD | 1-hour | 760 | 34.6% | 0.90 | −40.6% | −52.6% | −40.2% | −0.5% | −59.4% | $2,254 |
| EUR/USD | 4-hour | 203 | 30% | 0.75 | −27.4% | −34.1% | −29.8% | +3.3% | −38.9% | $294 |
| GBP/USD | 15-minute | 2,621 | 36.9% | 0.89 | −84.6% | −85.0% | −76.9% | −33.2% | −90.7% | $8,876 |
| GBP/USD | 1-hour | 732 | 38.1% | 1.00 | +0.1% | −34.8% | −1.8% | +1.9% | −45.5% | $2,961 |
| GBP/USD | 4-hour | 215 | 32.1% | 0.84 | −20.3% | −24.3% | −17.1% | −3.8% | −34.7% | $387 |
| USD/JPY | 15-minute | 2,608 | 36.7% | 0.93 | −79.8% | −85.8% | −47.5% | −61.5% | −88.8% | $12,996 |
| USD/JPY | 1-hour | 850 | 36.9% | 1.00 | +1.6% | −32.5% | −15.4% | +20.1% | −47.3% | $2,666 |
| USD/JPY | 4-hour | 189 | 36% | 1.02 | +2.4% | −21.3% | −0.3% | +2.7% | −24.1% | $309 |
| AUD/USD | 15-minute | 2,721 | 35.5% | 0.85 | −94.3% | −94.9% | −88.7% | −50.0% | −96.0% | $8,328 |
| AUD/USD | 1-hour | 777 | 35.5% | 0.94 | −30.6% | −49.0% | −16.5% | −16.8% | −55.1% | $3,930 |
| AUD/USD | 4-hour | 200 | 34.5% | 0.91 | −11.7% | −24.6% | −6.0% | −6.0% | −30.7% | $462 |
| Gold | 15-minute | 2,171 | 34.6% | 0.82 | −95.2% | −95.4% | −91.6% | −42.9% | −96.2% | $9,540 |
| Gold | 1-hour | 685 | 36.1% | 0.89 | −33.6% | −56.0% | −46.6% | +24.5% | −53.2% | $2,492 |
| Gold | 4-hour | 193 | 31.6% | 0.76 | −25.5% | −26.4% | −12.0% | −15.4% | −36.0% | $403 |
| S&P 500 | 15-minute | 2,531 | 37.9% | 0.92 | −76.6% | −79.2% | −59.5% | −42.1% | −87.3% | $13,341 |
| S&P 500 | 1-hour | 731 | 34.1% | 0.88 | −52.8% | −64.9% | −18.9% | −41.8% | −65.8% | $3,071 |
| S&P 500 | 4-hour | 243 | 32.5% | 0.85 | −23.3% | −33.4% | −15.4% | −9.4% | −37.9% | $548 |
| Nasdaq 100 | 15-minute | 2,491 | 36.3% | 0.85 | −94.0% | −94.5% | −86.0% | −57.0% | −95.7% | $14,597 |
| Nasdaq 100 | 1-hour | 796 | 32.9% | 0.78 | −69.1% | −72.1% | −59.1% | −24.4% | −75.6% | $3,072 |
| Nasdaq 100 | 4-hour | 233 | 34.3% | 0.91 | −12.9% | −24.7% | −11.2% | −2.0% | −32.1% | $718 |
| DAX | 15-minute | 2,427 | 36.5% | 0.91 | −80.6% | −81.1% | −53.3% | −58.5% | −88.9% | $5,024 |
| DAX | 1-hour | 669 | 39.3% | 1.09 | +48.6% | −20.6% | +40.6% | +5.6% | −36.1% | $1,687 |
| DAX | 4-hour | 192 | 38% | 1.14 | +16.4% | −17.4% | +12.1% | +3.9% | −20.3% | $188 |
Profit factor is the money won divided by the money lost. Above 1 means the test made money. Max drawdown is the biggest fall from the highest balance. 2014–2021 and 2022–2025 show the result in each period on its own. Monte Carlo drawdown: we shuffled the trades into a random order 1,000 times; in 95% of those runs, the worst drawdown was this number or less. Result is the change in the account, with the risk of each trade set to 1% of the account at that time.
The account balance
The best test and the middle test
What we found
What the 24 backtests show
With the standard rules (the rules under 'The rules we tested', with nothing changed), 5 of the 24 tests made money, all on 1-hour and 4-hour charts. On the DAX, the account grew 48.6% on 1-hour charts and 16.4% on 4-hour charts, from 2014 to 2025. The other 3 were close to zero after 12 years: USD/JPY (+1.6% on 1-hour and +2.4% on 4-hour charts) and GBP/USD on 1-hour charts (+0.1%). Only the two DAX tests made money in both 2014–2021 and 2022–2025. On 15-minute charts, all 8 tests lost money: each account lost 77% to 95% of its starting balance.
Is divergence better than the simplest way to trade RSI? We compared it with the RSI 30/70 rules: buy when RSI comes back above 30, and sell short when it comes back below 70. Both ran on the same 16 tests: the 8 markets on 1-hour and 4-hour charts. R is the risk of one trade: the distance from the entry to the stop-loss. Each trade is sized so that, if the stop-loss is hit, it loses 1% of the account. Divergence trades won more often: 35.4% won, compared with 26.3% of the 30/70 trades. But the winning divergence trades were smaller: +1.74R on average, compared with +2.62R. So the average divergence trade lost slightly more: 0.043R (4.3% of the amount it risked), compared with 0.035R (see the table below).
Waiting for confirmation did not help. With confirmation, a buy waits for a candle to close above the highest price between the two lows of the divergence, and a sell waits for a close below the lowest price between the two highs. On 1-hour and 4-hour charts, more trades won with confirmation, but the winning trades were much smaller, and the average trade lost more (see the comparison below). This is because the later entry was about twice as far from the stop-loss, so the take-profit at 2R (twice the distance from the entry to the stop-loss) was about twice as far away too. The strategy also closes a buy early when RSI reaches 70, and a sell when RSI reaches 30. With confirmation, this RSI exit came first far more often than the take-profit, so most winning trades closed before they reached 2R.
Most RSI divergence trades go against the trend. Many traders judge the trend with the 200 EMA, a line that shows the average price of the last 200 candles. They only buy when price is above this line, and only sell when price is below it. On 1-hour and 4-hour charts, about 9 divergence trades in 10 did the opposite: they bought when price was below the 200 EMA, or sold short when price was above it. Only 862 of the 7,668 trades followed the 200 EMA rule: on average, about 4 or 5 a year per test. So a 200 EMA filter would leave very few trades. And those trades were not clearly better: their average result per trade was better than that of the other trades on 4-hour charts, on gold and on the stock indices, but worse on 1-hour charts and on the currency pairs.
RSI divergence compared with RSI 30/70
Divergence trades won more often than 30/70 trades, but the average trade lost slightly more
Both strategies ran on the same 16 tests: 8 markets on 1-hour and 4-hour charts, from 2014 to 2025, with the same trading costs and 1% risk per trade. The RSI 30/70 rules buy when RSI comes back above 30 and sell short when it comes back below 70; our RSI overbought/oversold page tests them. R is the risk of one trade: the distance from the entry to the stop-loss. Each trade is sized so that, if the stop-loss is hit, it loses 1% of the account.
| 1-hour and 4-hour charts | RSI 30/70 rules | RSI divergence |
|---|---|---|
| Trades | 17,194 | 7,668 |
| Win rate | 26.3% | 35.4% |
| Average winning trade | +2.62R | +1.74R |
| Average losing trade | −0.98R | −1.02R |
| Average trade, winners and losers together | −0.035R | −0.043R |
| Tests that made money | 4 of 16 | 5 of 16 |
| Made money in both 2014–2021 and 2022–2025 | EUR/USD 1-hour and DAX 4-hour | DAX 1-hour and DAX 4-hour |
On 15-minute charts, both strategies lost money on all 8 markets. The divergence accounts lost less, 77% to 95% compared with 96% to 99%, because divergence made fewer trades: 20,128 instead of 36,775. The average 15-minute trade was about the same: −0.079R with divergence and −0.076R with the 30/70 rules.
Wait for confirmation?
With confirmation, more trades won, but the average trade lost more
These numbers cover all the trades on 1-hour and 4-hour charts: 16 tests from 2014 to 2025. With confirmation, a buy waits for a candle to close above the highest price between the two lows of the divergence, and a sell waits for a close below the lowest price between the two highs. R is the risk of one trade: the distance from the entry to the stop-loss. Each trade is sized so that, if the stop-loss is hit, it loses 1% of the account.
- Win rate, standard rules
- 35.4% of 7,668 trades. The average winning trade made 1.74R.
- Win rate, waiting for confirmation
- 45.5% of 3,200 trades. The average winning trade made 0.98R.
- Average trade, standard rules
- −0.043R winners and losers together
- Average trade, waiting for confirmation
- −0.079R winners and losers together
ATR is how far price moves in an average candle. With confirmation, the trade opens after price has already moved away from the second low (or high), so the entry is further from the stop-loss: 3.5 ATR on average, compared with 1.8 ATR with the standard rules. The take-profit at 2R is about twice as far away too. So the RSI exit came first far more often than the take-profit: 38.8% of the trades closed when RSI reached 70 or 30, and only 7.2% at the take-profit.
How often
How many trades RSI divergence gave on each chart
Each bar shows the average number of trades per market per year with the standard rules, from 2014 to 2025, on the 8 markets. Only one trade is open at a time, so a divergence that formed while a trade was open is not counted.
- 15-minute20,128 trades. 0 of 8 tests made money. 210
- 1-hour6,000 trades. 3 of 8 tests made money. 63
- 4-hour1,668 trades. 2 of 8 tests made money. 17
- Daily247 trades. Too few to judge. 2.6
We need at least 100 trades to judge a test. On daily charts, each market had only 21 to 47 trades in 12 years, so daily charts are not in the results above. Over those 247 daily trades, 28% won, and the average trade lost 0.22R.
The strategy
What the RSI divergence strategy is
RSI (Relative Strength Index) is an indicator that scores how hard price has moved, from 0 to 100. It compares the size of the up moves with the size of the down moves over the last 14 candles. A divergence is when price and RSI point in different directions. In a bullish divergence, price makes a lower low, but RSI makes a higher low: price fell further, but RSI shows that the fall was weaker than before. Many traders read this as a sign that the fall is ending, so they buy. A bearish divergence is the opposite: price makes a higher high while RSI makes a lower high, and traders sell short. This page tests both of these, which traders call regular divergence. Hidden divergence is a different setup, and it is not tested here.
- RSI
- 14 candles, calculated the standard way (Wilder's formula)
- Swings
- A swing low is a low below the lows of the 3 candles on each side. A swing high is a high above the highs of the 3 candles on each side. The two swings of a divergence are 5 to 60 candles apart.
- RSI levels
- For a buy, RSI must be below 40 at the second swing low. For a sell, RSI must be above 60 at the second swing high.
- Stop-loss
- 0.25 ATR below the second swing low for a buy, or 0.25 ATR above the second swing high for a sell. ATR(14) is how far price moves in an average candle, over the last 14 candles.
- Take-profit
- 2R (2 times the distance from the entry to the stop-loss), or earlier when RSI reaches 70 for a buy or 30 for a sell
- Risk per trade
- 1% of the account
- Overnight (swap) fees
- Not included. Brokers charge or pay a fee for keeping a trade open overnight. On 4-hour charts, half of the trades stayed open longer than 30 hours, and 12% longer than a week, so results there could be higher or lower with a real broker.
The rules we tested
- Find the swing lows and swing highs. A swing low is a candle whose low is lower than the lows of the 3 candles before it and the 3 candles after it. A swing high is a candle whose high is higher than the highs of the 3 candles on each side. A swing is only known when the 3rd candle after it closes, so the test only uses it from then on.
- Buy on a bullish divergence. Each time a new swing low is known, compare it with the swing low just before it. We call the earlier one the first swing low, and the new one the second swing low. They must be 5 to 60 candles apart. The second swing low must be lower in price than the first. RSI at the second swing low must be higher than RSI at the first, and below 40. RSI is read on the two swing low candles themselves.
- Sell short on a bearish divergence. This is the opposite of the buy rule: the second swing high is higher in price than the first, the two swing highs are 5 to 60 candles apart, and RSI at the second swing high is lower than at the first, and above 60.
- The signal candle is the 3rd candle after the second swing, the one that makes the swing known. The trade opens at the next candle's open. Skip the signal if RSI is already 70 or higher for a buy, or 30 or lower for a sell.
- ATR is an indicator of how far price moves in an average candle, measured over the last 14 candles. Put the stop-loss 0.25 ATR below the second swing low for a buy, or 0.25 ATR above the second swing high for a sell. The stop-loss does not move. If price reaches it, the trade closes at the stop price, or at a worse price if price gaps past it (opens beyond it).
- Take profit at 2R. R is the distance from the signal candle's close to the stop-loss, so the take-profit is 2 times that distance from the close. Close the trade earlier if a candle closes with RSI at 70 or higher (for a buy) or at 30 or lower (for a sell). That RSI exit happens at the next candle's open.
- Only one trade is open at a time. A divergence that forms while a trade is open is ignored, even on the candle where the open trade hits its stop-loss or take-profit.
- Size every trade so that, if the stop-loss is hit, the trade loses 1% of the account.
The method
How we tested it
The test
- Markets
- EUR/USD, GBP/USD, USD/JPY, AUD/USD, Gold, S&P 500, Nasdaq 100 and DAX
- Charts
- 15-minute, 1-hour and 4-hour candles
- Dates
- January 2014 to December 2025
- Account
- $10,000, risking 1% of the account on each trade
- Trading costs
- Included. Every trade pays that market's normal trading cost: the spread, which is the gap between the buy price and the sell price.
How a test passes
We call a test passed only if it meets all four checks. A strategy can make money in one backtest and still fail one of these checks.
- At least 100 trades. With fewer trades, a good result could be luck.
- It made money from 2014 to 2021 and again from 2022 to 2025. This shows whether the strategy kept working in the newer years, not only in the older ones.
- A profit factor (the money won divided by the money lost) of at least 1.2 from 2022 to 2025, after trading costs.
- In 95% of 1,000 random shuffles of the trades, the account must not fall more than 30% from its highest point.
Improvements
Can the RSI divergence strategy be improved?
We tried three changes traders often make to RSI divergence, one at a time, on the same 24 tests as the standard rules. The first waits for price to confirm the divergence before entering. The second takes a buy only if RSI at the first swing low was below 30 (oversold), and a sell only if RSI at the first swing high was above 70 (overbought). The third removes the 2R take-profit and holds each trade until RSI reaches 70 (buys) or 30 (sells). If you pick the best change and then judge it on the years you used to pick it, it will almost always look good. So we picked the best one in 2014–2021 only, by the number of tests that made money, and then checked it in 2022–2025.
| Version | Made money 2014–2021years used to pick the best version | Made money 2022–2025years not used to pick it | Made money in both periods | Passed all four checks |
|---|---|---|---|---|
| Standard rules The rules under 'The rules we tested', with nothing changed. | 2 of 24middle test −24.4% | 7 of 24middle test −12.4% | 2 | 0 |
| Waiting for confirmationBest on 2014–2021 Don't enter as soon as the divergence is known. For a buy, wait up to 20 candles for a candle to close above the highest price from the first swing low to the second, then buy at the next candle's open. If a candle closes below the second swing low first, skip the trade. For a sell, do the opposite. If a new divergence forms while an older one is still waiting, the new one replaces it. The stop-loss stays at the same price, 0.25 ATR beyond the second swing. Because the trade opens later, the entry is further from the stop-loss. The 2R take-profit is measured from the close of the confirmation candle. | 5 of 24middle test −15.2% | 5 of 24middle test −5.2% | 0 | 0 |
| Only when RSI at the first swing was below 30 or above 70 Take a buy only if RSI at the first swing low was below 30, the level traders call oversold. Take a sell only if RSI at the first swing high was above 70, called overbought. The other rules stay the same. | 4 of 24middle test −23.3% | 9 of 24middle test −5.5% | 2 | 0 |
| No take-profit: hold until RSI reaches 70 or 30 Remove the 2R take-profit. A buy closes when RSI reaches 70, and a sell closes when RSI reaches 30. Both still close at the stop-loss if price reaches it first. | 0 of 24middle test −42.8% | 3 of 24middle test −24.4% | 0 | 0 |
No. The standard rules made money in both periods in 2 of 24 tests, and none of the three changes did better than that. In 2014–2021, the years we used to pick the best change, waiting for confirmation did best: 5 of 24 tests made money with it, compared with 2 with the standard rules. But 3 of those 5 were 4-hour tests with fewer than 100 trades from 2014 to 2025, too few to judge. In 2022–2025, the years we kept for the check, confirmation did worse: 5 of 24 tests made money, compared with 7 with the standard rules, and no test made money in both periods. So over the whole of 2014–2025, only 1 of its 24 tests made money, compared with 5 with the standard rules. With confirmation, the middle test lost less in 2022–2025 (−5.2%, compared with −12.4% with the standard rules), mostly because it made fewer than half as many trades. Taking a trade only when RSI at the first swing was below 30 or above 70 made money in the most tests in 2022–2025 (9 of 24), but in only 4 of 24 in 2014–2021, so it was not picked. With it, 2 tests made money in both periods, the same as with the standard rules. Holding each trade until RSI reached 70 or 30 did worst: no test made money from 2014 to 2025, and on 1-hour and 4-hour charts only 23.4% of its trades won.
Questions
Questions traders ask
Does RSI divergence work?
Mostly no. In our backtest from 2014 to 2025, with trading costs, RSI divergence made money in 5 of 24 tests (8 markets, each on 15-minute, 1-hour and 4-hour charts). All 5 were on 1-hour and 4-hour charts: the DAX and USD/JPY on both, and GBP/USD on 1-hour charts. Only the DAX made money in both 2014–2021 and 2022–2025, on both its 1-hour and 4-hour charts. On 1-hour and 4-hour charts, about 1 trade in 3 won (35.4%), and in most tests the winning trades did not pay for the losing trades and the trading costs.
What is the best timeframe for RSI divergence?
No timeframe made money on most markets in our test. 1-hour and 4-hour charts did better than 15-minute charts: on 1-hour charts, 3 of 8 tests made money, and on 4-hour charts, 2 of 8 did. On 15-minute charts, all 8 tests lost 77% to 95% of the account. The best test was the DAX on 1-hour charts: the account grew 48.6% from 2014 to 2025. Daily charts gave too few trades to judge: only 21 to 47 per market in 12 years.
Should you wait for confirmation after an RSI divergence?
Not in our test. In the confirmation version, a buy waited up to 20 candles for a candle to close above the highest price between the two lows of the divergence. A sell waited for a close below the lowest price between the two highs. The confirmation version made money in 1 of 24 tests from 2014 to 2025, compared with 5 when entering right away. Its trades won more often (45.5% on 1-hour and 4-hour charts, instead of 35.4%), but its average winning trade was much smaller: 0.98 times the amount risked, instead of 1.74 times. Confirmation did better than the standard rules in 2014–2021 (5 tests made money, compared with 2), but worse in 2022–2025 (5, compared with 7). No test made money in both periods with confirmation, so over the whole of 2014–2025 only 1 of its 24 tests made money.
What are the best RSI settings for divergence?
This test can't tell you which RSI period works best: we used the standard 14 candles. We did test the RSI level. Our standard rules need the second RSI low below 40 for a buy, or the second RSI high above 60 for a sell. We also tested taking only divergences whose first RSI low was below 30, the level traders call oversold (or whose first high was above 70, called overbought). That version made money in 4 of 24 tests from 2014 to 2025, compared with 5 with the standard rules. On 1-hour and 4-hour charts, the average trade lost about 4% of the amount it risked with both versions. So starting below 30 or above 70 did not make the strategy better. Be careful with settings chosen because they gave the best backtest: they fit the past data, so they often do worse in live trading.
Keep exploring
Related strategies we tested
RSI RSI overbought/oversold strategy backtest Made money in 4 of 24 tests, 2 of them in both periods. Best: DAX, 1-hour, +92%The strategy code we ran
This is the exact code from the BacktestingMax strategy engine. Paste it into the strategy editor in the app to run it on any market.
class RsiDivergence(Strategy):
"""Regular RSI divergence, as most traders learn it, plus three changes traders make.
Pivots. A pivot low is a candle whose low is below the lows of the 3 candles before it and
the 3 candles after it, so it is only known 3 candles later, when the 3rd candle after it
closes. A pivot high is the mirror image. RSI is Wilder's RSI over 14 candles, and the RSI
of a pivot is the RSI of the pivot candle itself.
Standard (all switches off):
Bullish divergence: a new pivot low is lower than the pivot low before it, but its RSI is
higher than that pivot's RSI, and below 40. The two pivots are 5 to 60 candles apart.
Buy when the candle that confirms the new pivot low closes (the order fills at the next
candle's open).
Bearish divergence: the mirror image with pivot highs (a higher high in price, a lower
high in RSI, RSI above 60): sell short.
The stop-loss goes 0.25 ATR(14) beyond the new pivot (below its low for a buy). Take
profit at 2 times the risk (2R), or close when RSI reaches 70 (buys) or 30 (sells),
whichever comes first; the RSI exit fills at the next candle's open. A signal is skipped
if RSI is already at that exit level. Size so the stop costs 1% of the account. One trade
at a time: a divergence that forms while a trade is open is ignored.
The changes, one at a time:
confirm = 1 don't enter at the divergence. Wait up to 20 candles for a candle to close
above the highest high from the first pivot low to the second (below the
lowest low from the first pivot high to the second, for a sell), then
enter. A close beyond the second pivot first cancels the setup, and a newer
divergence replaces it. Same stop; 2R is measured from that close.
oversold = 1 only divergences whose first RSI low was below 30 (oversold), or whose
first RSI high was above 70 (overbought)
no_target = 1 no 2R take-profit: hold until RSI reaches 70 (buys) or 30 (sells), or
until the stop-loss
"""
params = {"rsi_period": Param(type=int, default=14, min=2, max=100),
"pivot_bars": Param(type=int, default=3, min=1, max=10),
"min_gap": Param(type=int, default=5, min=1, max=100),
"max_gap": Param(type=int, default=60, min=2, max=200),
"buy_below": Param(type=float, default=40.0, min=1.0, max=50.0),
"sell_above": Param(type=float, default=60.0, min=50.0, max=99.0),
"exit_long": Param(type=float, default=70.0, min=50.0, max=99.0),
"exit_short": Param(type=float, default=30.0, min=1.0, max=50.0),
"stop_atr": Param(type=float, default=0.25, min=0.0, max=3.0),
"target_r": Param(type=float, default=2.0, min=0.5, max=10.0),
"confirm": Param(type=int, default=0, min=0, max=1),
"confirm_bars": Param(type=int, default=20, min=1, max=100),
"oversold": Param(type=int, default=0, min=0, max=1),
"no_target": Param(type=int, default=0, min=0, max=1)}
lookback = 100
def init(self, ctx):
n = ctx.params.pivot_bars
self.rsi = ctx.indicator("builtin:rsi", period=ctx.params.rsi_period)
self.atr = ctx.atr(period=14)
self.pl = ctx.pivot_low(source=ctx.low, left=n, right=n)
self.ph = ctx.pivot_high(source=ctx.high, left=n, right=n)
self.last_low = None # (bar index, price, RSI) of the latest pivot low
self.last_high = None # the same for pivot highs
self.setup = None # confirm version: (side, trigger, second pivot, stop, last bar)
def divergence(self, ctx, pivot_price, prev, side):
"""A new pivot (confirmed on this candle) against the pivot before it.
Returns (RSI of the first pivot, bar index of the first pivot) for a divergence, else None."""
p = ctx.params
n = p.pivot_bars
r_new = self.rsi.rsi[n]
if prev is None or r_new is None or prev[2] is None:
return None
gap = (ctx.bar_index - n) - prev[0]
if gap < p.min_gap or gap > p.max_gap:
return None
if side > 0:
ok = pivot_price < prev[1] and r_new > prev[2] and r_new < p.buy_below
ok = ok and (p.oversold == 0 or prev[2] < 30.0)
else:
ok = pivot_price > prev[1] and r_new < prev[2] and r_new > p.sell_above
ok = ok and (p.oversold == 0 or prev[2] > 70.0)
return (prev[2], prev[0]) if ok else None
def enter(self, ctx, side, stop, tag):
p = ctx.params
entry = ctx.close[0]
r0 = self.rsi.rsi[0]
hold = p.no_target == 1 # no fixed take-profit: the RSI exit or the stop ends the trade
if side > 0:
if not ctx.gate("stop_below_entry", stop < entry):
return
if not ctx.gate("rsi_below_exit", r0 < p.exit_long):
return
ctx.buy(size=ctx.size_by_risk_pct(0.01, stop=stop, entry=entry), sl=stop,
tp=None if hold else entry + p.target_r * (entry - stop), tag=tag)
else:
if not ctx.gate("stop_above_entry", stop > entry):
return
if not ctx.gate("rsi_above_exit", r0 > p.exit_short):
return
ctx.sell(size=ctx.size_by_risk_pct(0.01, stop=stop, entry=entry), sl=stop,
tp=None if hold else entry - p.target_r * (stop - entry), tag=tag)
def on_bar(self, ctx):
p = ctx.params
n = p.pivot_bars
i = ctx.bar_index
# Read the pivots on every candle, before any return, so no pivot is missed.
low_price, high_price = self.pl.value, self.ph.value
bull = bear = None
if low_price is not None:
bull = self.divergence(ctx, low_price, self.last_low, 1)
self.last_low = (i - n, low_price, self.rsi.rsi[n])
if high_price is not None:
bear = self.divergence(ctx, high_price, self.last_high, -1)
self.last_high = (i - n, high_price, self.rsi.rsi[n])
r0, a = self.rsi.rsi[0], self.atr.value
if r0 is None or a is None:
return
pos = ctx.position
if pos is not None:
self.setup = None
if pos.is_long and r0 >= p.exit_long:
ctx.close_position()
elif pos.is_short and r0 <= p.exit_short:
ctx.close_position()
return
c0 = ctx.close[0]
# A new divergence on this candle.
if ctx.gate("divergence", bull is not None or bear is not None):
side = 1 if bull is not None else -1
if bull is not None and bear is not None:
side = 0 # both on one candle: no clear signal
if side != 0:
first_bar = (bull if side > 0 else bear)[1]
span = range(n, i - first_bar + 1) # candles back, from the new pivot to the first
if side > 0:
pivot = low_price
stop = pivot - p.stop_atr * a
trigger = max(ctx.high[k] for k in span)
else:
pivot = high_price
stop = pivot + p.stop_atr * a
trigger = min(ctx.low[k] for k in span)
if p.confirm == 1:
self.setup = (side, trigger, pivot, stop, i + p.confirm_bars)
else:
self.setup = None
self.enter(ctx, side, stop, "bull_div" if side > 0 else "bear_div")
return
# Confirm version: wait for a close beyond the high (or low) between the two pivots.
if self.setup is not None:
side, trigger, pivot, stop, last_bar = self.setup
if i > last_bar or (side > 0 and c0 < pivot) or (side < 0 and c0 > pivot):
self.setup = None # no confirmation in time, or price went past the second pivot
elif ctx.gate("confirmation_close", (side > 0 and c0 > trigger) or (side < 0 and c0 < trigger)):
self.setup = None
self.enter(ctx, side, stop, "bull_div_confirmed" if side > 0 else "bear_div_confirmed")
Your turn
Test the RSI divergence strategy yourself
Change the settings, the market or the stop-loss and see the result in seconds. Ask the BacktestingMax AI: Backtest RSI divergence on the DAX 1-hour chart from 2014 to 2025: 3-candle swings, RSI below 40 for buys and above 60 for sells, stop-loss 0.25 ATR beyond the second swing, 2R take-profit, and an early exit at RSI 70 or 30
.
Free account. No credit card needed.
See every strategy we tested Browse strategies shared by tradersBacktest on historical data with trading costs, run by BacktestingMax. Past results do not guarantee future results, and nothing here is financial advice. Updated 12 October 2026.