ATMResearch
Join Overfit - free
←Back to 36 Ways to Buy the DipFree sample
  1. Products/
  2. 36 Ways to Buy the Dip/
  3. Free sample
Free sample · Entry 1 of 40

RSI(2) below 10: a full entry from 36 Ways to Buy the Dip

This is one of the book's 40 entry sections, exactly as it is printed. Every entry gets the same pages in the same order, so this is what the other 39 look like.

Trades
440
Profit factor
1.61
Win %
59.5%
Max drawdown
13.7%

SPY daily, February 1993 to August 2026, 4-bar hold. Verdict: Strong.

Read more
Book page: section 4.1 RSI, with where the entry came from, how it works, the median trade and the start of the pseudo-code.
Book page: the rest of the RSI(2) pseudo-code and Figure 4.1.1, the median trade on a candlestick chart.
Book page: RSI(2) results, the drawdown comparison and the threshold test table.
Book page: RSI(2) results at every holding period, the three worst days and the takeaway.

How every entry in the book is tested

  • Every entry is measured on SPY daily, February 2, 1993 to August 20, 2026. That's 8,445 bars and 33.5 years.

  • The signal is read at a bar's close, the fill is the next bar's open, and the exit is the open N bars after the entry bar, with the sell order placed at the close of the bar before.

  • One position at a time, overlapping signals skipped. Sizing is non-compounding, a fixed $35,000 buying whole shares. No commission and no slippage.

  • Verdicts come from the numbers by rule and never by feel: under 50 trades is Not rankable, a profit factor under 1.15 is No edge, 1.15 to 1.50 is Edge present, above 1.50 is Strong.

36 Ways to Buy the Dip · The 40 Entries

4.1 RSI

The two-period RSI below 10. This is the most recognised mean reversion entry there is, and on this data it earns the reputation: 440 trades, a profit factor of 1.61, and a verdict of Strong.

Where it came from

RSI is commonly attributed to J. Welles Wilder Jr., who published it as a 14-period momentum gauge. This book flags that credit as unconfirmed rather than citing it, because no checked copy of the original was at hand, and an origin claim without one is a rumour with a date on it. The origin isn't what matters here anyway. What matters is the shorter window. At 14 periods RSI is a slow momentum reading. At two periods a single down close swamps the average and the reading drops toward zero, which turns it into something close to a pure short-term oversold signal. It's a different tool wearing the same name.

How it works

Wilder's smoothing separates up closes from down closes and reports the ratio between them on a 0 to 100 scale. With a two-bar window, two down closes in a row will drive it under 10 almost no matter how large they were.

Here's one, and it's the median trade this entry produced, so it's neither its best day nor its worst.

On December 31, 1993 SPY closed at $46.60 and RSI(2) read 8.3073, under the threshold of 10. The signal was known at that close, so the fill was the next session's open: January 3, 1994 at $46.60. At $35,000 that's 751 shares. Four bars later, on January 7, the trade sold at the open, $46.84. It made $180, or +0.515%.

Note what the fill cost this time: nothing. SPY opened exactly where it had closed, so the overnight gap took $0.00. Don't count on that. The next page's median trade gave up more than a percent of the price overnight before it started. That's not a fault in the test, it's the honest order of events, and it's one reason a rule tested on closing prices makes itself look better than it is.

SETTINGS: Length = 2 bars, Threshold = 10

FOR EACH BAR:
    Change    = Close - Close[1]
    Gain      = Change if Change > 0 else 0
    Loss      = -Change if Change < 0 else 0
    // Wilder, 1/n
    AvgGain   = WilderAverage(Gain, Length)
    AvgLoss   = WilderAverage(Loss, Length)
    RSI       = 100 - 100 / (1 + AvgGain / AvgLoss)

    SIGNAL fires at this bar's close when RSI < Threshold
    ENTRY   is the next bar's open
Figure 4.1.1: a candlestick chart of SPY around the end of 1993, with RSI(2) collapsing under 10 into the December 31, 1993 close, the fill at the next open, and the four bars that followed.
Figure 4.1.1: The tinted bar is the day RSI(2) read 8.3073. The fill is the next open, at the same $46.60 the signal bar closed at, and the exit is the open four bars later. This is the median of the entry's 440 trades, so it's what a typical one looks like rather than a good one.

What the test shows

RSI(2) below 10 on SPY at the 4-bar hold
TradesAvg tradeAvg %Profit factorWin %Max DD %Best holdVerdict
440$1570.4501.6159.5%13.7%5 barsStrong

The entry produced 826 signals and 440 trades, so roughly half the time it fired, it fired while a position was already open. That's the character of a fast oscillator: it doesn't give one signal at a bottom, it gives a cluster.

The number worth pausing on is the drawdown. Four of the nine ranked entries in this block hold their worst loss under 15%, and this is one of them at 13.7%, behind CCI at 10.4% and Williams %R at 11.9% and just ahead of TSI at 14.0%. The other five run from Stochastic's 16.0% all the way to 45.0%. Most entries in this block buy their profit factor with a deeper hole. This one doesn't, and that combination is rarer than the popularity of RSI(2) would suggest.

Does the number they picked matter

How to read this table, here and wherever it appears. Each row is the same entry at a different trigger level, on SPY at the 4-bar hold, and "(shipped)" marks the level the first edition used. Look for a run of nearby rows with a similar profit factor around the shipped one: a setting inside such a run doesn't depend on luck, and one on a lone peak does. Total $ and Ret/DD show the same rows as total profit and as total profit divided by the worst fall. Edge is edge over drift.

RSI(2) at five trigger levels, SPY, 4-bar hold
TriggerTradesPFAvg tradeTotal $Ret/DDEdgeVerdict
5.02241.450.380%$29,5792.79+0.222%Edge present
7.53411.580.450%$53,7895.06+0.292%Strong
10.0 (shipped)4401.610.450%$69,0115.58+0.292%Strong
20.07331.560.380%$97,3018.51+0.222%Strong
30.09201.440.300%$97,9747.26+0.142%Edge present

This is what a well-chosen setting looks like. From 7.5 through 20 the profit factor stays between 1.56 and 1.61, and the shipped 10 sits at the top of that stretch. Tighten to 5 and you lose half the trades and the edge goes with them, down a band to Edge present. Loosen to 30 and it decays again, because a reading of 30 on a two-period RSI is an ordinary down day rather than an oversold one. Ten sits inside the flat stretch, which is the right place for a threshold to sit: the settings either side of it barely move the result.

The holding period is the more interesting axis.

RSI(2) below 10 at eight holding periods, SPY
HoldTradesPFAvg tradeTotal $Ret/DDEdge
0 bars8261.350.140%$38,9117.16+0.134%
1 bar5771.300.140%$28,8862.76+0.099%
2 bars5081.580.340%$60,0347.52+0.260%
3 bars4621.490.330%$52,7724.69+0.211%
4 bars4401.610.450%$69,0115.58+0.292%
5 bars4171.880.630%$91,2847.58+0.433%
10 bars3371.740.770%$90,7948.80+0.380%
20 bars2331.750.870%$70,9064.13+0.092%
Edge over drift, by holding period (SPY)
  • 0 bars+0.134%
  • 1 bar+0.099%
  • 2 bars+0.260%
  • 3 bars+0.211%
  • 4 bars+0.292%
  • 5 bars+0.433%
  • 10 bars+0.380%
  • 20 bars+0.092%

Five bars is the peak at +0.433% over drift, ten is close behind at +0.380%, and four, the book's comparison hold, trails both at +0.292%. Five to ten bars is a broad region, and a broad region is worth far more than a peak, because it means the result doesn't depend on getting the exit exactly right. The 20-bar row is the warning: the average trade is 0.870%, the biggest in the column, and the edge over drift has shrunk to +0.092%. Hold this entry for a month and the market pays you nearly all of the return.

Where it goes wrong

This table ranks every signal the entry gave, including signals the flat-only backtest skipped because a trade was already open, by the return from the fill to the close five bars later. The last column counts how many of the 40 signalled on that bar.

The three worst trades for RSI(2) below 10
Entry dateEntry price5-bar return from the fillLowest low in 20 barsEntries signalling that day
2011-08-01$130.84-14.20%-15.72%20 of 40
2020-03-13$263.09-13.03%-17.04%29 of 40
2008-11-13$86.13-12.40%-13.69%23 of 40

Read the last column before the others. On all three of the worst days this entry ever had, half the catalog fired alongside it. These aren't RSI's failures, they're the market's, and no oversold reading was going to help you on March 13, 2020.

That's the useful pattern and it holds across most of this chapter. A fast oscillator's worst trades are crashes, and crashes are exactly when everything looks oversold at once. Chapter 6 measures how much that clustering actually costs a portfolio.

One coding trap. If there's no down close in the window, average loss is zero and the division would fail. The guard returns 100, so no signal fires, which is correct: an unbroken run of up closes is not oversold. A port that returns zero there will fire on the strongest bars in the file.

Takeaway: RSI(2) below 10 earns its reputation on this data, and the reason is the shallow drawdown rather than the win rate. Its trigger sits inside a flat region, which is where a threshold should sit, and its edge peaks at five bars and holds up at ten.

The code for this entry

The code pack ships every entry in EasyLanguage for TradeStation and in a standalone Python pack. Here is entry 01 in both, verbatim from the shipped files.

EasyLanguage

Strategy Code v4.txt

// ----- Entry 01: RSI(2) -----
RSI_Val = RSI(Close, E01_RSI_Period);

// Entry 01: RSI(2)
If StrategyNumber = 1 then begin
	LongCondition = RSI_Val < E01_RSI_OS;
	ShortCondition = RSI_Val > E01_RSI_OB;
end;
Python

buythedip/primitives.py

def rsi(close, n):
    """Wilder's RSI, 0 to 100.

    Two guards, checked in this order: no average loss reads 100 (so an unbroken
    run of up closes is never oversold), and no average gain with some loss reads 0.
    """
    close = np.asarray(close, dtype=float)
    size = len(close)
    out = np.full(size, np.nan)
    if size <= n:
        return out
    change = np.diff(close, prepend=close[0])
    gain = np.where(change > 0, change, 0.0)
    loss = np.where(change < 0, -change, 0.0)
    avg_gain = gain[1:n + 1].mean()
    avg_loss = loss[1:n + 1].mean()

    def reading(g, l):
        if l == 0:
            return 100.0
        if g == 0:
            return 0.0
        return 100.0 - 100.0 / (1.0 + g / l)

    out[n] = reading(avg_gain, avg_loss)
    for i in range(n + 1, size):
        avg_gain = (avg_gain * (n - 1) + gain[i]) / n
        avg_loss = (avg_loss * (n - 1) + loss[i]) / n
        out[i] = reading(avg_gain, avg_loss)
    return out

39 more entries, every one on the same pages

Plus the three example strategies built from the entries that held up, the stability test across three periods, the same 40 on ES futures and seven more markets, and the EasyLanguage and Python code for all of it.

Oscillator10

  • RSIthis sample
  • Stochastic
  • CCI
  • Williams %R
  • CMO
  • Ultimate Oscillator
  • TSI
  • Aroon Oscillator
  • DPO
  • PPO

Price position6

  • Range Position
  • Consecutive Lower Closes
  • Donchian Position
  • Percent Below 20-Day High
  • Lowest Close in X Days
  • New Low + Above SMA200

Volatility6

  • Bollinger Breakdown
  • Keltner Breakdown
  • Percent Below SMA
  • ATR Distance from High
  • Large Range Down Day
  • Gap Down

Momentum6

  • Rate of Change
  • MACD Histogram Extreme
  • TRIX
  • Z-Score of RSI
  • Z-Score of Returns
  • Z-Score of IBS

Pattern4

  • Lower Low + Close > Open
  • Consecutive Rejection Bars
  • Stochastic RSI
  • Elder Ray Bear Power

Volume2

  • MFI
  • Force Index

Advanced2

  • DV2
  • RSI Streak

Bonus4

  • IBS
  • Connors RSI
  • Casey C%
  • Ultimate C%

Hypothetical results from historical backtests on SPY, not real trading, with no trading costs deducted, shown for education. Past results, real or hypothetical, are not a guarantee of future returns. Trading involves risk of loss. Nothing here is investment advice or a recommendation to buy or sell any security.

StatOasis is calm, evidence-based algorithmic-trading education, founded by Ali Casey. Ali builds systematic trading strategies and teaches the workflow behind them: research, build, test, combine, deploy. He writes the Overfit newsletter, published since 2024, and runs the Algo Trading Masterclass.

Socials

  • X ↗
  • YouTube ↗
  • Instagram ↗
  • LinkedIn ↗
  • GitHub ↗
  • Muck Rack ↗
  • LinkedIn SO ↗
  • GitHub SO ↗

Products

  • Overfit - the newsletter
  • Algo Trading Masterclass
  • StatOasis Community
  • 36 Ways to Buy the Dip
  • AlgoChef ↗

Reading & tools

  • Research
  • Methodology
  • Survive the Decade
  • Wall of Love

StatOasis

  • About Ali Casey
  • Contact
© 2026 StatOasis. Calm, evidence-based.
PrivacyTermsHypothetical resultsCalifornia