RSI
Relative Strength Index
Measures the speed and magnitude of recent price changes, expressed as a value between 0 and 100.
What is it?
Developed by J. Welles Wilder Jr. in 1978, the RSI is a momentum oscillator that measures the ratio of average gains to average losses over a lookback period (default 14). The formula: RSI = 100 − (100 / (1 + RS)), where RS = average gain / average loss. The result oscillates between 0 and 100. Readings above 70 and below 30 are the levels most commonly cited in the literature, and they carry the traditional labels 'overbought' and 'oversold'. What those labels do not describe is what happens next: in strong trends the reading can stay at either end for weeks.
Common pitfalls
- The 70/30 levels are not universal. In a strong bull market, RSI rarely touches 30 — using it as a buy trigger means missing the entire move. Adjust levels to 80/40 in uptrends.
- RSI divergence can persist for many candles before price reacts. It is a warning, not a trigger — always wait for a price-action confirmation before entering.
- The default 14-period setting smooths out a lot of reading. Shorter periods (7–9) are more sensitive but noisier; longer periods (21–25) are smoother but lag more.
- RSI is calculated on closing prices only. Wicks and intraday volatility are invisible to it — a candle that wicked far below support and closed near the open will show a much higher RSI than the wick suggests.
- Crypto markets run 24/7 with no session close. The 14-period RSI on a daily chart covers 14 calendar days; on a 4H chart it covers only 56 hours. Be explicit about what timeframe you are reading.
Indicator Rider — RSI Thermometer
The RSI Thermometer fills blue at low readings, green in the middle range, and red at high readings — with the zone label showing the current value.
Free code template
Paste directly into TradingView Pine Editor → Add to chart.
/indicator("RSI — DAI Template", shorttitle="DAI RSI", overlay=false)
// ── Inputs ──────────────────────────────────────────────────────────────────
rsiLen = input.int(14, "RSI Length", minval=2)
obLevel = input.int(70, "Overbought Level", minval=50, maxval=100)
osLevel = input.int(30, "Oversold Level", minval=0, maxval=50)
src = input.source(close, "Source")
// ── Calculation ─────────────────────────────────────────────────────────────
rsiVal = ta.rsi(src, rsiLen)
// ── Colours ─────────────────────────────────────────────────────────────────
rsiColor = rsiVal >= obLevel ? #ef4444 :
rsiVal <= osLevel ? #3b82f6 : #22c55e
// ── Plot ────────────────────────────────────────────────────────────────────
plot(rsiVal, "RSI", color=rsiColor, linewidth=2)
hline(obLevel, "Overbought", color=color.new(#ef4444, 40), linestyle=hline.style_dashed)
hline(50, "Midline", color=color.new(#94a3b8, 60), linestyle=hline.style_dotted)
hline(osLevel, "Oversold", color=color.new(#3b82f6, 40), linestyle=hline.style_dashed)
bgcolor(rsiVal >= obLevel ? color.new(#ef4444, 92) : rsiVal <= osLevel ? color.new(#3b82f6, 92) : na)
// ── Divergence Detection (basic) ────────────────────────────────────────────
bullDiv = rsiVal[2] < osLevel and rsiVal[2] < rsiVal[4] and close[2] < close[4] and rsiVal > rsiVal[2]
bearDiv = rsiVal[2] > obLevel and rsiVal[2] > rsiVal[4] and close[2] > close[4] and rsiVal < rsiVal[2]
plotshape(bullDiv, "Bull Divergence", shape.labelup, location.bottom, #22c55e, text="DIV↑", size=size.small)
plotshape(bearDiv, "Bear Divergence", shape.labeldown, location.top, #ef4444, text="DIV↓", size=size.small)
alertcondition(ta.crossunder(rsiVal, obLevel), "RSI Leaving Overbought", "RSI dropped below " + str.tostring(obLevel))
alertcondition(ta.crossover(rsiVal, osLevel), "RSI Leaving Oversold", "RSI rose above " + str.tostring(osLevel))