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.