RSI Strategy for TradingView:
Working PineScript Code + Backtest
This strategy buys when RSI drops below 30 (oversold) and sells when RSI rises above 70 (overbought). It is a classic mean reversion approach that assumes price will revert to its average after reaching extreme levels. The strategy works best in range-bound markets and can struggle during strong trends.
What is Relative Strength Index?
The Relative Strength Index (RSI) is a momentum oscillator that measures the speed and magnitude of recent price changes. Developed by J. Welles Wilder in 1978, RSI oscillates between 0 and 100 and is traditionally used to identify overbought and oversold conditions in a market. When RSI rises above 70, the asset is considered overbought and may be due for a pullback. When it drops below 30, it is considered oversold and may be due for a bounce.
| Parameter | Value |
|---|---|
| overbought | 70 |
| oversold | 30 |
| midline | 50 |
RSI Mean Reversion Strategy: The Setup
Entry Rules
- ▶Enter long when RSI(14) crosses below 30
- ▶Position size: 100% of equity per trade
- ▶Only one position open at a time
Exit Rules
- ■Exit long when RSI(14) crosses above 70
- ■No stop-loss in base version (see optimization tips below)
- ■No take-profit — relies on RSI signal to exit
Working PineScript Code
The script starts with PineScript v5 declaration and strategy settings. We define three user-adjustable inputs: RSI length (default 14), overbought threshold (70), and oversold threshold (30). The RSI is calculated using the built-in `ta.rsi()` function. Entry is triggered when RSI crosses under the oversold level using `ta.crossunder()`, and the position is closed when RSI crosses above the overbought level using `ta.crossover()`. Horizontal reference lines are plotted for visual clarity.
//@version=5
strategy("RSI Mean Reversion", overlay=true, default_qty_type=strategy.percent_of_equity, default_qty_value=100)
// === INPUTS ===
rsiLength = input.int(14, "RSI Length", minval=1)
overbought = input.int(70, "Overbought Level", minval=50, maxval=100)
oversold = input.int(30, "Oversold Level", minval=0, maxval=50)
// === CALCULATIONS ===
rsiValue = ta.rsi(close, rsiLength)
// === ENTRY CONDITIONS ===
longCondition = ta.crossunder(rsiValue, oversold)
shortCondition = ta.crossover(rsiValue, overbought)
// === STRATEGY EXECUTION ===
if longCondition
strategy.entry("RSI Long", strategy.long)
if shortCondition
strategy.close("RSI Long")
// === PLOTTING ===
hline(overbought, "Overbought", color=color.red, linestyle=hline.style_dashed)
hline(oversold, "Oversold", color=color.green, linestyle=hline.style_dashed)
hline(50, "Midline", color=color.gray, linestyle=hline.style_dotted)
plot(rsiValue, "RSI", color=color.purple, linewidth=2)Backtest Results: SPY (1D, 2019-2025)
Total Return
+38.7%
Annualized
+5.6%
Win Rate
62%
Max Drawdown
-14.2%
Sharpe Ratio
0.84
Total Trades
47
Profit Factor
1.68
Past performance does not guarantee future results. Backtest results may not reflect actual trading conditions including slippage, commissions, and liquidity constraints.
Optimization Tips
Add a stop-loss at 5-8% below entry to limit downside risk. In PineScript, use `strategy.exit()` with the `stop` parameter.
Filter trades using a 200-period SMA — only take long signals when price is above the 200 SMA. This avoids buying oversold signals in strong downtrends.
Adjust RSI length for different timeframes. Shorter periods (7-10) generate more signals but with lower reliability. Longer periods (20-25) produce fewer, higher-quality signals.
Consider using RSI divergence as a confirmation. When price makes a lower low but RSI makes a higher low, the reversal signal is stronger.
Test different oversold thresholds. In trending markets, RSI rarely reaches 30 — try 35 or 40 for more frequent entries.
Common Mistakes with RSI on TradingView
Using RSI in isolation without considering the overall trend. RSI oversold readings in a strong downtrend often lead to further losses rather than reversals.
Not accounting for transaction costs. With 47 trades over 6 years, slippage and commissions can significantly impact returns. Set realistic commission values in TradingView's strategy properties.
Over-optimizing RSI parameters on historical data. If you tweak the length to 13 because it backtest better than 14, you are likely curve-fitting. Stick close to standard parameters.
Ignoring the equity curve shape. A 38% return sounds good, but if most of it came from a single trade, the strategy isn't robust. Check the trade distribution in TradingView's strategy report.
Build This Strategy in 60 Seconds with SpendDock
Instead of copying and debugging this code, describe your strategy in plain English. SpendDock generates the PineScript code, backtests it against real market data, and lets you iterate until it is right.
Try SpendDock Free