UNPKG

quantitivecalc

Version:

A TypeScript library providing advanced quantitative finance functions for risk analysis, performance metrics, and technical indicators. (Currently in development)

69 lines (68 loc) 2.84 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.calculateRSI = calculateRSI; /** * Calculates the Relative Strength Index (RSI) for a given dataset. * * The RSI is a momentum oscillator that measures the speed and change of price movements. * It is typically used in technical analysis to identify overbought or oversold conditions. * * @param data - An array of objects representing the dataset. Each object should contain the source column. * @param sourceColumn - The key in each data object that contains the numeric value to calculate RSI from. * @param resultColumn - The key to store the calculated RSI value in each result object. Defaults to `'rsi'`. * @param windowSize - The number of periods to use for the RSI calculation. Defaults to `14`. * @returns A new array of objects with the RSI value added under the specified result column. * * @remarks * - If there is insufficient data to calculate RSI for a given row (i.e., fewer than `windowSize` periods), the result will be `null` for that row. * - If the average loss is zero, the RSI will be set to `100` for that row. */ function calculateRSI(data, sourceColumn, resultColumn = 'rsi', windowSize = 14) { if (!data || data.length === 0) { return []; } const result = data.map(row => ({ ...row })); for (let i = 0; i < result.length; i++) { if (i < windowSize) { result[i][resultColumn] = null; continue; } let gains = 0; let losses = 0; let gainCount = 0; let lossCount = 0; // Calculate gains and losses over the window for (let j = i - windowSize + 1; j <= i; j++) { const currentValue = result[j][sourceColumn]; const previousValue = result[j - 1][sourceColumn]; if (typeof currentValue === 'number' && typeof previousValue === 'number' && !isNaN(currentValue) && !isNaN(previousValue)) { const change = currentValue - previousValue; if (change > 0) { gains += change; gainCount++; } else if (change < 0) { losses += Math.abs(change); lossCount++; } } } if (gainCount === 0 && lossCount === 0) { result[i][resultColumn] = null; continue; } const avgGain = gainCount > 0 ? gains / windowSize : 0; const avgLoss = lossCount > 0 ? losses / windowSize : 0; if (avgLoss === 0) { result[i][resultColumn] = 100; } else { const rs = avgGain / avgLoss; result[i][resultColumn] = 100 - 100 / (1 + rs); } } return result; }