quantitivecalc
Version:
A TypeScript library providing advanced quantitative finance functions for risk analysis, performance metrics, and technical indicators. (Currently in development)
66 lines (65 loc) • 3.1 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.calculateBollingerBands = calculateBollingerBands;
const calculateMovingAverage_1 = require("./calculateMovingAverage");
/**
* Calculates Bollinger Bands for a given dataset.
*
* Bollinger Bands consist of three lines: the middle band (simple moving average),
* the upper band (SMA + N standard deviations), and the lower band (SMA - N standard deviations).
*
* @param data - Array of data objects to calculate Bollinger Bands for.
* @param sourceColumn - The key in each data object containing the source value (e.g., closing price).
* @param upperColumn - The key to store the calculated upper band value. Defaults to 'bb_upper'.
* @param middleColumn - The key to store the calculated middle band (SMA) value. Defaults to 'bb_middle'.
* @param lowerColumn - The key to store the calculated lower band value. Defaults to 'bb_lower'.
* @param windowSize - The number of periods to use for the moving average and standard deviation. Defaults to 20.
* @param numStdDev - The number of standard deviations to use for the upper and lower bands. Defaults to 2.
* @returns A new array of data objects with Bollinger Bands columns added.
*/
function calculateBollingerBands(data, sourceColumn, upperColumn = 'bb_upper', middleColumn = 'bb_middle', lowerColumn = 'bb_lower', windowSize = 20, numStdDev = 2) {
if (!data || data.length === 0) {
return [];
}
// Calculate the middle band (Simple Moving Average)
const withMA = (0, calculateMovingAverage_1.calculateMovingAverage)(data, sourceColumn, middleColumn, windowSize, 'simple');
return withMA.map((row, i) => {
if (i < windowSize - 1 || row[middleColumn] === null) {
return {
...row,
[upperColumn]: null,
[lowerColumn]: null,
};
}
// Calculate standard deviation for the window
let sumSquaredDeviations = 0;
const mean = row[middleColumn];
// Collect valid values for the window
const windowValues = [];
for (let j = i - windowSize + 1; j <= i; j++) {
const value = withMA[j][sourceColumn];
if (typeof value === 'number' && !isNaN(value)) {
windowValues.push(value);
}
}
if (windowValues.length === 0) {
return {
...row,
[upperColumn]: null,
[lowerColumn]: null,
};
}
// Calculate standard deviation using the collected values
for (const value of windowValues) {
sumSquaredDeviations += Math.pow(value - mean, 2);
}
// Use sample standard deviation (n-1) for consistency with typical Bollinger Bands calculation
const variance = sumSquaredDeviations / (windowValues.length - 1);
const stdDev = Math.sqrt(variance);
return {
...row,
[upperColumn]: mean + numStdDev * stdDev,
[lowerColumn]: mean - numStdDev * stdDev,
};
});
}