trading2026-08-10Β·6 minΒ·14/145

RSI(2) Mean Reversion Backtest on BTC/USDT: Catching Falling Knives for a Fee

The classic RSI(2) buy-the-dip strategy, backtested on real hourly BTC/USDT. Zero-cost result +56.32%, but 269 round trips and realistic taker plus slippage turn it into -70.39%. Pandas implementation, charts, and the knife problem.

RSI(2) Mean Reversion Backtest on BTC/USDT (2023, hourly, real fees)

Every dip buyer thinks they're brave right up until the knife turns out to be a falling anvil. I know, because I've caught several of each. RSI(2) mean reversion is the algorithmic version of that instinct β€” "buy when everyone is panicking" β€” codified into two numbers. It sounded responsible, even contrarian. Then I met its fee schedule. Strategy Lab #8.

What RSI(2) mean reversion is

RSI measures momentum on a 0–100 scale; at a period of 2 it's jumpy and extreme. The strategy is brutally simple:

  • Buy when RSI(2) drops below 10 β€” the market is oversold, short-term panic.
  • Sell when RSI(2) climbs above 90 β€” the bounce has run.

The whole bet is that short-term panic is wrong, and price snaps back. On stocks with daily bars this is a real, well-documented edge. On crypto at hourly frequency it's a different animal β€” one where "oversold" can stay oversold for hours while the market keeps sliding, and every failed bounce is another round-trip of fees.

Results

StrategyCategoryTotal returnCAGRMaxDDSharpeTrades
rsi_meanrevmeanrev+13.64%+13.68%-22.68%0.60269

RSI(2) mean reversion vs buy & hold (2023, hourly, BTC/USDT)

269 trades for a +13.64% net return. Notice the naive max drawdown in the table below (-16.62%) β€” the best of anything in the series so far. That's the honest strength of mean reversion: it sits in cash during the crash, because "buy the panic" is already in. But that strength gets eaten alive by the turnaround count.

The fee bill

ScenarioCost/legTotal returnMaxDDSharpeTrades
naive (zero cost)0.00%+56.32%-16.62%1.76269
taker fee 0.05%/leg0.05%+19.50%-20.11%0.79269
+ funding 0.01%/8h0.05%+13.64%-22.68%0.60269
+ slippage 10bp/leg0.15%-33.61%-45.11%-1.34269
+ slippage 25bp/leg0.30%-70.39%-72.79%-4.18269

RSI(2) cost scenarios (2023, hourly, BTC/USDT)

+56.32% β†’ -70.39%. Same 269 signals, five different cost stories. Mean reversion is uniquely fragile to slippage because it buys into the exact moments of worst liquidity β€” you're buying when everyone else is selling, so your fill is systematically on the wrong side of the spread. That's the falling-knife tax you can't see in a no-cost backtest.

Buy and hold comparison

StrategyTotal returnCAGRMaxDDSharpe
rsi_meanrev+13.64%+13.68%-22.68%0.60
buy & hold+154.94%+155.62%-21.74%2.42

What this does NOT prove

  • One symbol, one year, hourly. On daily bars, or on a mean-reverting asset like a rangebound index, this family of strategies behaves completely differently β€” the timeframe is the variable being tested, not mean reversion itself.
  • 10/90 thresholds are arbitrary. RSI(2) results are notoriously sensitive to them, and tuning to 2023's data is the definition of overfitting.
  • The robust finding: a strategy whose edge lives in quick bounces must survive the cost of catching them. Slippage on panic sells is not a detail β€” it's the strategy's operating cost.

Code

from backtest_base import fetch, backtest_signal, metrics
from strategy import rsi

df = fetch("BTCUSDT", "binance", "2023-01-01", "2023-12-31", "1h")
r = rsi(df["close"], period=2)
enter = (r < 10).to_numpy()
exit_ = (r > 90).to_numpy()
signal = stateful_position(enter, exit_)     # buy panic, sell the bounce

res = backtest_signal(df, signal, cost_per_leg=0.0005,
                      funding_per_bar=0.0001 / 8.0)
print(metrics(res, 8760))

Reproduce it

cd blog-drafts/scripts
python backtest_base.py --strategy rsi_meanrev --symbol BTCUSDT --interval 1h \
    --start 2023-01-01 --end 2023-12-31 --fee 0.0005 --funding 0.0000125

Data: Binance public API, hourly OHLCV, 8,735 bars. The tables above reproduce exactly from this command.

This is a backtest on historical data, not investment advice. Past performance does not predict future results.