RSI Indicator in Pine Script

The Relative Strength Index (RSI) is one of the most popular momentum oscillators. This guide covers everything from basic RSI to advanced implementations.


Basic RSI

Simple RSI

//@version=6
indicator("RSI Basic", overlay=false)
 
length = input.int(14, "RSI Length")
 
rsi = ta.rsi(close, length)
 
plot(rsi, title="RSI", color=color.blue, linewidth=2)
hline(70, color=color.red, linestyle=hline.style_dashed)
hline(30, color=color.green, linestyle=hline.style_dashed)
hline(50, color=color.gray)

RSI with Background

//@version=6
indicator("RSI with Background", overlay=false)
 
rsi = ta.rsi(close, 14)
 
plot(rsi, color=color.blue)
 
// Background colors
bgColor = rsi > 70 ? color.new(color.red, 90) : rsi < 30 ? color.new(color.green, 90) : na
bgcolor(bgColor)
 
hline(70)
hline(30)
hline(50, color=color.gray)

RSI with Custom Parameters

Adjustable RSI

//@version=6
indicator("Custom RSI", overlay=false)
 
// Input parameters
rsiLength = input.int(14, "RSI Length")
obLevel = input.float(70, "Overbought", minval=50, maxval=100)
osLevel = input.float(30, "Oversold", minval=0, maxval=50)
 
// Calculate RSI
rsi = ta.rsi(close, rsiLength)
 
// Plot
plot(rsi, color=color.purple, linewidth=2)
 
// Levels
hline(obLevel, color=color.red, linestyle=hline.style_dashed)
hline(osLevel, color=color.green, linestyle=hline.style_dashed)
hline(50, color=color.gray)
 
// Background zones
fill(plot1=plot(100), plot2=plot(obLevel), color=color.new(color.red, 90))
fill(plot1=plot(osLevel), plot2=plot(0), color=color.new(color.green, 90))

RSI Color Coding

Dynamic Colors Based on RSI Value

//@version=6
indicator("RSI Color Coded", overlay=false)
 
rsi = ta.rsi(close, 14)
 
// Color based on value
rsiColor = rsi > 70 ? color.red : rsi < 30 ? color.green : color.blue
 
plot(rsi, color=rsiColor, linewidth=2)
 
// Fill zones
fill(plot1=plot(rsi), plot2=plot(70), color=rsi > 70 ? color.new(color.red, 80) : color.new(color.gray, 90))
fill(plot1=plot(rsi), plot2=plot(30), color=rsi < 30 ? color.new(color.green, 80) : color.new(color.gray, 90))
 
hline(70)
hline(30)

RSI with Moving Average

RSI SMA Overlay

//@version=6
indicator("RSI with MA", overlay=false)
 
rsiLength = input.int(14, "RSI Length")
maLength = input.int(9, "MA Length")
 
rsi = ta.rsi(close, rsiLength)
rsiMA = ta.sma(rsi, maLength)
 
// Plot both
plot(rsi, color=color.blue, title="RSI")
plot(rsiMA, color=color.orange, title="RSI MA")
 
// Crosses
rsiCrossUp = ta.crossover(rsi, rsiMA)
rsiCrossDown = ta.crossunder(rsi, rsiMA)
 
plotshape(rsiCrossUp, location=location.bottom, style=shape.arrowup, color=color.lime)
plotshape(rsiCrossDown, location=location.top, style=shape.arrowdown, color=color.red)
 
hline(70)
hline(30)
hline(50)

RSI Overbought/Oversold Signals

Trading Signals

//@version=6
indicator("RSI Signals", overlay=true)
 
// Parameters
length = input.int(14, "RSI Length")
overbought = input.float(70, "Overbought")
oversold = input.float(30, "Oversold")
 
// Calculate
rsi = ta.rsi(close, length)
sma20 = ta.sma(close, 20)
 
// Signals
buySignal = ta.crossover(rsi, oversold)
sellSignal = ta.crossunder(rsi, overbought)
 
// Filter with trend
buyFilter = close > sma20
sellFilter = close < sma20
 
finalBuy = buySignal and buyFilter
finalSell = sellSignal and sellFilter
 
// Plot
plot(sma20, color=color.blue, title="SMA 20")
 
plotshape(finalBuy, location=location.belowbar, style=shape.labelup, color=color.green, text="RSI BUY")
plotshape(finalSell, location=location.abovebar, style=shape.labeldown, color=color.red, text="RSI SELL")
 
// Background
bgcolor(finalBuy ? color.new(color.green, 90) : finalSell ? color.new(color.red, 90) : na)

RSI Divergence

Bullish Divergence

//@version=6
indicator("RSI Divergence", overlay=false)
 
length = input.int(14, "RSI Length")
lookback = input.int(5, "Lookback")
 
rsi = ta.rsi(close, length)
 
// Find pivot lows on price
priceLow = ta.pivotlow(low, lookback, lookback)
 
// Find pivot lows on RSI
rsiLow = ta.pivotlow(rsi, lookback, lookback)
 
// Bullish divergence: price makes lower low, RSI makes higher low
bullishDiv = priceLow and rsiLow and low[lookback] < low[lookback * 2 + 1] and rsi[lookback] > rsi[lookback * 2 + 1]
 
plot(rsi)
plotshape(bullishDiv, location=location.bottom, style=shape.labelup, color=color.lime, text="BULLISH\nDIV")
 
hline(70)
hline(30)

Bearish Divergence

//@version=6
indicator("RSI Bearish Divergence", overlay=false)
 
length = input.int(14, "RSI Length")
lookback = input.int(5, "Lookback")
 
rsi = ta.rsi(close, length)
 
// Find pivot highs
priceHigh = ta.pivothigh(high, lookback, lookback)
rsiHigh = ta.pivothigh(rsi, lookback, lookback)
 
// Bearish divergence: price makes higher high, RSI makes lower high
bearishDiv = priceHigh and rsiHigh and high[lookback] > high[lookback * 2 + 1] and rsi[lookback] < rsi[lookback * 2 + 1]
 
plot(rsi)
plotshape(bearishDiv, location=location.top, style=shape.labeldown, color=color.red, text="BEARISH\nDIV")
 
hline(70)
hline(30)

Multi-Timeframe RSI

RSI on Higher Timeframe

//@version=6
indicator("Multi-Timeframe RSI", overlay=false)
 
length = input.int(14, "RSI Length")
tf = input.timeframe("D", "Timeframe")
 
// Current RSI
rsiCurrent = ta.rsi(close, length)
 
// Higher timeframe RSI
rsiHTF = request.security(syminfo.tickerid, tf, ta.rsi(close, length))
 
// Plot both
plot(rsiCurrent, color=color.blue, title="Current RSI")
plot(rsiHTF, color=color.orange, title="HTF RSI", linewidth=2)
 
hline(70)
hline(30)

RSI with Alerts

Alert-Ready RSI

//@version=6
indicator("RSI with Alerts", overlay=false, explicit_plot_zorder=true)
 
rsiLength = input.int(14, "RSI Length")
 
rsi = ta.rsi(close, rsiLength)
 
// Plot
plot(rsi, title="RSI", color=color.blue, linewidth=2)
hline(70, color=color.red)
hline(30, color=color.green)
hline(50, color=color.gray)
 
// Alert conditions
alertcondition(rsi < 30, title="Oversold", message="RSI Oversold - Potential Buy")
alertcondition(rsi > 70, title="Overbought", message="RSI Overbought - Potential Sell")
alertcondition(ta.crossover(rsi, 30), title="RSI Cross Up", message="RSI crossed above 30 - Buy Signal")
alertcondition(ta.crossunder(rsi, 70), title="RSI Cross Down", message="RSI crossed below 70 - Sell Signal")

Complete RSI Indicator

//@version=6
indicator("Complete RSI System", overlay=false)
 
// === INPUTS ===
rsiLength = input.int(14, "RSI Length")
maLength = input.int(9, "MA Length")
obLevel = input.float(70, "Overbought")
osLevel = input.float(30, "Oversold")
showDiv = input.bool(true, "Show Divergences")
showSignals = input.bool(true, "Show Signals")
 
// === CALCULATIONS ===
rsi = ta.rsi(close, rsiLength)
rsiMA = ta.sma(rsi, maLength)
 
// === PLOTTING ===
plot(rsi, title="RSI", color=color.blue, linewidth=2)
plot(rsiMA, title="RSI MA", color=color.orange)
 
// Levels
hline(obLevel, color=color.red)
hline(osLevel, color=color.green)
hline(50, color=color.gray)
 
// === SIGNALS ===
if showSignals
    // Buy: RSI crosses above oversold
    buySignal = ta.crossover(rsi, osLevel)
    // Sell: RSI crosses below overbought
    sellSignal = ta.crossunder(rsi, obLevel)
    // Signal line cross
    buyCross = ta.crossover(rsi, rsiMA)
    sellCross = ta.crossunder(rsi, rsiMA)
 
    plotshape(buySignal, location=location.bottom, style=shape.arrowup, color=color.lime, size=size.tiny)
    plotshape(sellSignal, location=location.top, style=shape.arrowdown, color=color.red, size=size.tiny)
    plotshape(buyCross, location=location.bottom, style=shape.cross, color=color.green, size=size.tiny)
    plotshape(sellCross, location=location.top, style=shape.cross, color=color.maroon, size=size.tiny)
 
// === DIVERGENCES ===
if showDiv
    lookback = 5
    priceLow = ta.pivotlow(low, lookback, lookback)
    rsiLow = ta.pivotlow(rsi, lookback, lookback)
 
    plotshape(priceLow and rsiLow, location=location.bottom, style=shape.labelup, color=color.lime, text="DIV")

RSI Strategies

RSI Only Strategy

//@version=6
strategy("RSI Strategy", overlay=false)
 
length = input.int(14, "RSI Length")
overbought = input.float(70, "Overbought")
oversold = input.float(30, "Oversold")
qty = input.float(10, "Quantity %")
 
rsi = ta.rsi(close, length)
 
// Long entry
if ta.crossover(rsi, oversold)
    strategy.entry("RSI Long", strategy.long, qty_percent=qty)
 
// Short entry
if ta.crossunder(rsi, overbought)
    strategy.entry("RSI Short", strategy.short, qty_percent=qty)
 
// Exit
if ta.crossunder(rsi, 50)
    strategy.close_all()
 
plot(rsi)
hline(overbought)
hline(oversold)

RSI + MA Strategy

//@version=6
strategy("RSI + MA Strategy", overlay=true)
 
rsiLength = input.int(14, "RSI")
smaLength = input.int(50, "SMA")
oversold = input.float(35, "Oversold")
overbought = input.float(65, "Overbought")
 
rsi = ta.rsi(close, rsiLength)
smaVal = ta.sma(close, smaLength)
 
// Filter: price above SMA
aboveSMA = close > smaVal
belowSMA = close < smaVal
 
// Entry signals
longCondition = ta.crossover(rsi, oversold) and aboveSMA
shortCondition = ta.crossunder(rsi, overbought) and belowSMA
 
if longCondition
    strategy.entry("Long", strategy.long)
 
if shortCondition
    strategy.entry("Short", strategy.short)
 
// Exit
if ta.crossunder(rsi, 50)
    strategy.close_all()
 
plot(smaVal)
plot(rsi, scale=scale.left)
hline(overbought)
hline(oversold)

RSI Reference

ConceptDescription
RSI > 70Overbought - potential sell
RSI < 30Oversold - potential buy
RSI = 50Neutral
RSI crosses upBullish momentum
RSI crosses downBearish momentum

Next Steps


RSI is a versatile indicator for identifying overbought/oversold conditions.