quantitivecalc
Version:
A TypeScript library providing advanced quantitative finance functions for risk analysis, performance metrics, and technical indicators. (Currently in development)
58 lines (57 loc) • 3.19 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.calculateMACD = calculateMACD;
const calculateMovingAverage_1 = require("./calculateMovingAverage");
/**
* Calculates the MACD (Moving Average Convergence Divergence) indicator for a given dataset.
*
* The function computes the MACD line, signal line, and histogram values for each row in the input data.
* It uses exponential moving averages (EMAs) for the fast and slow periods, and the signal line is an EMA of the MACD line.
*
* @param data - Array of data objects containing price or value information.
* @param sourceColumn - The key in each data object to use as the source value for calculations (e.g., 'close').
* @param macdColumn - The key to store the calculated MACD line value. Defaults to 'macd'.
* @param signalColumn - The key to store the calculated signal line value. Defaults to 'macd_signal'.
* @param histogramColumn - The key to store the calculated MACD histogram value. Defaults to 'macd_histogram'.
* @param fastPeriod - The period for the fast EMA. Defaults to 12.
* @param slowPeriod - The period for the slow EMA. Defaults to 26.
* @param signalPeriod - The period for the signal line EMA. Defaults to 9.
* @returns A new array of data objects with MACD, signal, and histogram columns added.
*/
function calculateMACD(data, sourceColumn, macdColumn = 'macd', signalColumn = 'macd_signal', histogramColumn = 'macd_histogram', fastPeriod = 12, slowPeriod = 26, signalPeriod = 9) {
if (!data || data.length === 0) {
return [];
}
// Validate that fastPeriod < slowPeriod (standard MACD convention)
if (fastPeriod >= slowPeriod) {
throw new Error('Fast period must be less than slow period for MACD calculation');
}
// Calculate fast and slow EMAs
const withFastEMA = (0, calculateMovingAverage_1.calculateMovingAverage)(data, sourceColumn, '__fast_ema', fastPeriod, 'exponential');
const withBothEMAs = (0, calculateMovingAverage_1.calculateMovingAverage)(withFastEMA, sourceColumn, '__slow_ema', slowPeriod, 'exponential');
// Calculate MACD line (fast EMA - slow EMA)
const withMACD = withBothEMAs.map(row => {
const fastEMA = row.__fast_ema;
const slowEMA = row.__slow_ema;
const macdValue = fastEMA !== null && slowEMA !== null ? fastEMA - slowEMA : null;
return {
...row,
[macdColumn]: macdValue,
__temp_macd: macdValue,
};
});
// Calculate signal line (EMA of MACD line)
const withSignal = (0, calculateMovingAverage_1.calculateMovingAverage)(withMACD, '__temp_macd', signalColumn, signalPeriod, 'exponential');
// Calculate histogram (MACD - Signal) and clean up temporary columns
return withSignal.map(row => {
const macdValue = row[macdColumn];
const signalValue = row[signalColumn];
const histogramValue = macdValue !== null && signalValue !== null ? macdValue - signalValue : null;
// Create clean row without temporary columns
const { ...cleanRow } = row;
return {
...cleanRow,
[histogramColumn]: histogramValue,
};
});
}