Exciting Update: Version 1.0.0 is now available, introducing high-performance technical indicators and custom drawing tools. Read more
Version: 1.0.0

Relative Strength Index (RSI)

Integrate Relative Strength Index (RSI) oscillators rendering on a separate sub-pane.

Overview

The Relative Strength Index (RSI) is a momentum oscillator that measures the speed and change of price movements, outputting values between 0 and 100. It highlights overbought conditions above 70 and oversold conditions below 30.

Calculation Method

The RSI sums average gain and loss over 14 periods, calculating relative strength:

RSI = 100 - (100 / (1 + AvgGain / AvgLoss))

RSI Code Structure

Below is the full implementation code of the RSI indicator module from the library:

window.ChartingAPI.registerIndicator('rsi', {
  name: 'RSI',
  type: 'pane',
  levels: [30, 50, 70],
  params: { period: 14 },
  defaultColor: '#9C27B0',
  calculate: function(bars, params) {
    const period = params.period || 14;
    const rsi = new Array(bars.length).fill(null);
    if (bars.length < period + 1) return rsi;

    let avgGain = 0;
    let avgLoss = 0;
    for (let i = 1; i <= period; i++) {
      const diff = bars[i].close - bars[i - 1].close;
      if (diff > 0) avgGain += diff; else avgLoss -= diff;
    }
    avgGain /= period;
    avgLoss /= period;

    rsi[period] = avgLoss === 0 ? 100 : 100 - (100 / (1 + avgGain / avgLoss));

    for (let i = period + 1; i < bars.length; i++) {
      const diff = bars[i].close - bars[i - 1].close;
      const gain = diff > 0 ? diff : 0;
      const loss = diff < 0 ? -diff : 0;
      avgGain = (avgGain * (period - 1) + gain) / period;
      avgLoss = (avgLoss * (period - 1) + loss) / period;
      rsi[i] = avgLoss === 0 ? 100 : 100 - (100 / (1 + avgGain / avgLoss));
    }
    return rsi;
  },
  render: function(ctx, chart, values, bounds, color) {
    const { startIndex, endIndex, chartW, toY } = bounds;
    const themeColor = color || '#9C27B0';

    // 1. Draw shade between 30 and 70
    ctx.save();
    ctx.fillStyle = themeColor;
    ctx.globalAlpha = 0.04;
    const y70 = toY(70);
    const y30 = toY(30);
    ctx.fillRect(0, y70, chartW, y30 - y70);
    ctx.restore();

    // 2. Draw RSI line
    ctx.beginPath();
    ctx.strokeStyle = themeColor;
    ctx.lineWidth = 1.5;
    ctx.lineJoin = 'round';

    let started = false;
    for (let i = startIndex; i <= endIndex; i++) {
      if (i >= chart.bars.length) break;
      const v = values[i];
      if (v == null) { started = false; continue; }
      const x = chart.barToX(i);
      const y = toY(v);
      if (!started) {
        ctx.moveTo(x, y);
        started = true;
      } else {
        ctx.lineTo(x, y);
      }
    }
    ctx.stroke();
  }
});

Overbought & Oversold Shading

Shading provides a quick visual alert for extremes. In the rendering logic above, ctx.fillRect(0, y70, chartW, y30 - y70) colors the area between the 30 and 70 thresholds to make trend shifts highly visible.