How to Implement RSI in Pine Script v5 for TradingView?

As experienced Pine Script developers and traders, we frequently rely on time-tested indicators to inform our decisions and build robust automated systems. The Relative Strength Index (RSI) is undoubtedly one of the most widely used momentum oscillators. In this article, we’ll delve into implementing RSI effectively in Pine Script v5, covering everything from the basics to more advanced applications.

Introduction to RSI and Pine Script v5

Understanding the Relative Strength Index (RSI)

The Relative Strength Index, developed by J. Welles Wilder Jr., is a momentum oscillator that measures the speed and change of price movements. It oscillates between 0 and 100. Traditionally, RSI is used to identify overbought (typically above 70) and oversold (typically below 30) conditions in an asset.

The calculation involves averaging upward and downward price changes over a specified period. This average gain and average loss are then used in a specific formula to derive the RSI value. A higher RSI indicates strong buying pressure, while a lower RSI indicates strong selling pressure.

Why use Pine Script v5 for RSI Implementation?

Pine Script v5 is the latest iteration of TradingView’s scripting language, offering significant improvements over previous versions. It provides a streamlined syntax, better performance, and access to powerful built-in functions and libraries.

Key advantages of v5 include:

  • Improved readability and structure.
  • Enhanced performance for complex calculations.
  • Standardized function libraries (ta.*, request.*, input.*).
  • Support for new features like object-oriented programming concepts (though less relevant for a basic indicator).

Using Pine Script v5 ensures your scripts are future-proof, efficient, and leverage the best tools TradingView provides for technical analysis and strategy automation.

Setting up TradingView and Pine Editor

Accessing the Pine Editor is straightforward within TradingView. Open any chart, locate the “Pine Editor” tab at the bottom, and click it. This opens the editor window where you can write, test, and save your Pine Script code. Ensure the version directive at the top of your script is set to @version=5.

Basic RSI Implementation in Pine Script v5

Implementing the core RSI indicator in Pine Script v5 is remarkably simple thanks to the built-in ta.rsi() function.

Declaring the Indicator and Overlay

Every Pine Script begins with a version declaration and a script annotation function. For a simple indicator like RSI, which typically plots in a separate pane below the price chart, we use indicator() with overlay=false.

//@version=5
indicator("Basic RSI", shorttitle="RSI", overlay=false)
  • "Basic RSI": The name of the indicator that will appear on the chart.
  • shorttitle="RSI": A shorter name, useful when multiple indicators are present.
  • overlay=false: Specifies that the indicator should plot in its own pane, not directly on the price chart.

Calculating the RSI using built-in ta.rsi()

The ta library in Pine Script v5 contains numerous technical analysis functions. The ta.rsi() function calculates the Relative Strength Index. It requires two main arguments:

  1. src: The source series (typically closing price, close).
  2. length: The lookback period for the calculation (commonly 14).

We should also allow users to customize these values using input controls.

//@version=5
indicator("Basic RSI", shorttitle="RSI", overlay=false)

// Inputs for customization
int rsiLength = input.int(14, title="RSI Length", minval=1)

// Calculate RSI
float rsiValue = ta.rsi(close, rsiLength)

Here, input.int() creates an integer input field in the indicator’s settings. close is the built-in variable representing the closing price of the current bar.

Plotting the RSI on the Chart

To visualize the calculated RSI value, we use the plot() function.

//@version=5
indicator("Basic RSI", shorttitle="RSI", overlay=false)

// Inputs for customization
int rsiLength = input.int(14, title="RSI Length", minval=1)

// Calculate RSI
float rsiValue = ta.rsi(close, rsiLength)

// Plot RSI line
plot(rsiValue, title="RSI", color=color.purple)

This line plots the rsiValue on the indicator pane with a purple color.

Adding Overbought and Oversold Levels

Standard overbought and oversold levels are 70 and 30. We can plot horizontal lines for these levels using the hline() function.

//@version=5
indicator("Basic RSI", shorttitle="RSI", overlay=false)

// Inputs for customization
int rsiLength = input.int(14, title="RSI Length", minval=1)
int overbought = input.int(70, title="Overbought Level", minval=50, maxval=100)
int oversold = input.int(30, title="Oversold Level", minval=0, maxval=50)

// Calculate RSI
float rsiValue = ta.rsi(close, rsiLength)

// Plot RSI line
plot(rsiValue, title="RSI", color=color.purple)

// Plot Overbought and Oversold levels
hline(overbought, title="Overbought", color=color.red, linestyle=hline.style_dashed)
hline(oversold, title="Oversold", color=color.green, linestyle=hline.style_dashed)

We’ve added inputs for the OB/OS levels as well, allowing users to adjust them. hline() draws a horizontal line at a specified value. linestyle controls the line appearance.

Customizing RSI in Pine Script v5

While the basic implementation is functional, customization enhances the indicator’s utility and flexibility.

Adjusting RSI Length and Source

We already added inputs for length. Let’s also add an input for the source series, allowing users to apply RSI to something other than close, such as open, high, low, or hlc3.

//@version=5
indicator("Custom RSI", shorttitle="RSI", overlay=false)

// Inputs for customization
string sourceInput = input.source(close, title="Source") // Use input.source
int rsiLength = input.int(14, title="RSI Length", minval=1)
int overbought = input.int(70, title="Overbought Level", minval=50, maxval=100)
int oversold = input.int(30, title="Oversold Level", minval=0, maxval=50)

// Calculate RSI
float rsiValue = ta.rsi(sourceInput, rsiLength) // Use the input source

// Plot RSI line
plot(rsiValue, title="RSI", color=color.purple)

// Plot Overbought and Oversold levels
hline(overbought, title="Overbought", color=color.red, linestyle=hline.style_dashed)
hline(oversold, title="Oversold", color=color.green, linestyle=hline.style_dashed)

input.source() is a convenient input type specifically for selecting a series.

Implementing Different Smoothing Methods (Explanation)

The standard RSI calculation uses a form of exponential moving average known as Wilder’s smoothing (RMA – Running Moving Average). The ta.rsi() function in Pine Script v5 uses RMA by default, which is standard.

While ta.rsi() doesn’t directly offer SMA or EMA for the core RSI calculation within the function call for the relative strength component, you could calculate average gains and losses manually using ta.sma or ta.ema and then apply the RSI formula. However, using ta.rsi is the recommended and most performant approach for the standard calculation.

Note: Some users might plot an EMA or SMA of the RSI line itself to smooth the resulting oscillator. This is a different technique for visual or signal smoothing, not changing the core RSI calculation method.

Adding Dynamic Overbought/Oversold Levels based on Volatility (Concept)

Instead of fixed 70/30 levels, one could potentially adjust these thresholds based on market volatility. During highly volatile periods, RSI might reach extreme levels (80+, 20-) more easily, while in low volatility, it might stay confined between 60 and 40.

A simple conceptual approach could involve calculating volatility (e.g., using Average True Range ta.atr) and adjusting the OB/OS levels based on its value or recent history. For instance, increasing the distance from 50 in high volatility.

Implementing this dynamically requires careful consideration of how volatility correlates with RSI extremes for the specific asset and timeframe. A simple example calculating ATR:

// Calculate ATR as a measure of volatility (can be used to inform dynamic levels)
int atrLength = input.int(14, title="ATR Length", minval=1)
float currentATR = ta.atr(atrLength);

// --- Logic to adjust overbought/oversold based on currentATR (pseudocode) ---
// adjustedOverbought = baseOverbought + volatility_factor * currentATR;
// adjustedOversold = baseOversold - volatility_factor * currentATR;
// --- End pseudocode ---

Note: Developing a robust dynamic level adjustment mechanism is a complex task often requiring extensive testing and validation. The code above only shows how to get a volatility measure.

Advanced RSI Techniques and Strategies

Beyond identifying simple OB/OS conditions, RSI can be used in more nuanced ways.

Identifying RSI Divergences (Regular and Hidden)

Divergence occurs when price makes a new high/low, but the oscillator (RSI) does not confirm it. Divergences are often considered potential signs of trend weakening or reversal.

  • Regular (Classic) Divergence:
    • Bearish: Price makes a higher high, but RSI makes a lower high. Suggests potential bearish reversal.
    • Bullish: Price makes a lower low, but RSI makes a higher low. Suggests potential bullish reversal.
  • Hidden Divergence:
    • Bullish: Price makes a higher low, but RSI makes a lower low. Suggests trend continuation.
    • Bearish: Price makes a lower high, but RSI makes a higher high. Suggests trend continuation.

Programmatically detecting divergences in Pine Script requires identifying price pivots and corresponding RSI pivots and comparing their values. This involves functions like ta.pivot_high and ta.pivot_low and careful logic to ensure valid comparisons across bars.

Using RSI for Trend Confirmation

Instead of just looking for OB/OS, traders often use RSI to confirm the strength or direction of a trend:

  • In an uptrend, RSI often stays above 50, dipping towards 50 during pullbacks. A break below 50 can signal trend weakening.
  • In a downtrend, RSI often stays below 50, bouncing towards 50 during rallies. A break above 50 can signal trend weakening.

Code logic for this would involve checking rsiValue > 50 or rsiValue < 50 in combination with other trend identification methods (like moving averages).

Combining RSI with Other Indicators

RSI’s effectiveness can often be enhanced by combining it with other indicators or concepts:

  • RSI and Moving Averages: Use MAs to identify the trend direction and RSI to time entries within that trend (e.g., buying dips in an uptrend when RSI pulls back to 50 or 40).
  • RSI and Support/Resistance: Look for OB/OS signals when price is at significant support or resistance levels.
  • RSI and Volume: Confirm RSI signals with volume analysis; divergences on low volume might be less significant.

Developing robust strategies often involves creating entry and exit conditions based on the confluence of signals from multiple indicators.

Best Practices and Troubleshooting

Writing efficient and reliable Pine Script code for RSI requires adherence to best practices.

Optimizing Code for Efficiency

  • Avoid Unnecessary Loops: Pine Script is designed for vectorized operations on series. Avoid for or while loops unless absolutely necessary for specific lookback logic not covered by built-ins.
  • Use Built-in Functions: Functions like ta.rsi are highly optimized. Always prefer built-in functions over manual calculation when a standard implementation exists.
  • Minimize Redundant Calculations: If a value is needed multiple times, calculate it once and store it in a variable.
// Example: Bad (calculating RSI twice)
// plot(ta.rsi(close, 14), color=color.blue)
// buySignal = ta.rsi(close, 14) < 30 // Redundant calculation

// Example: Good (calculating RSI once)
float myRsi = ta.rsi(close, 14)
plot(myRsi, color=color.blue)
buySignal = myRsi < 30 // Use the stored variable

Avoiding Common Errors in Pine Script RSI Implementation

  • Incorrect Version Directive: Ensure @version=5 is at the top.
  • Misunderstanding overlay=true/false: RSI usually needs its own pane (overlay=false).
  • Type Mismatches: Pay attention to variable types (int, float, bool, series). Pine Script is generally good about implicit casting, but explicit casting or understanding function signatures helps.
  • Repainting Issues: While basic ta.rsi itself does not repaint, be cautious when combining it with functions that look into the future (request.security without lookahead) or complex logic involving bars that may change upon historical recalculation. For standard indicator plotting, this is rarely an issue, but crucial for strategies.
  • Incorrect Input Types: Use input.int for lengths/levels, input.source for series, etc.

Utilize the console in the Pine Editor for debugging runtime errors and use plot() or label.new() to inspect values on specific bars during execution.

Backtesting RSI Strategies in TradingView

To evaluate the profitability of an RSI-based trading idea, convert your indicator script into a strategy script using @version=5 and strategy().

//@version=5
strategy("RSI Strategy", shorttitle="RSI Strat", overlay=true)

// Inputs
int rsiLength = input.int(14, title="RSI Length", minval=1)
int overbought = input.int(70, title="Overbought Level", minval=50, maxval=100)
int oversold = input.int(30, title="Oversold Level", minval=0, maxval=50)

// Calculate RSI
float rsiValue = ta.rsi(close, rsiLength)

// Define Entry and Exit Conditions
longCondition = ta.crossunder(rsiValue, oversold) // RSI crossing below oversold (common long signal)
shortCondition = ta.crossover(rsiValue, overbought) // RSI crossing above overbought (common short signal)

// Execute Trades
if longCondition
    strategy.entry("Long", strategy.long)

if shortCondition
    strategy.entry("Short", strategy.short)

// Optional: Exit on opposite signal or fixed duration
// if shortCondition
//     strategy.close("Long")
// if longCondition
//     strategy.close("Short")

Switch from the Pine Editor to the “Strategy Tester” tab to view performance metrics, equity curves, and lists of trades. Experiment with different input values and rules within the Strategy Tester’s settings. Remember that backtest results are historical and do not guarantee future performance.


Leave a Reply