UNPKG

quantitivecalc

Version:

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

81 lines (80 loc) 3.95 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.calculateCorrelationMatrix = calculateCorrelationMatrix; /** * Calculates the rolling correlation matrix for a set of assets over a specified window size. * * @param data - An array of asset return objects, where each object contains asset return values keyed by asset name. * @param assetColumns - An array of asset names (keys in each data object) to include in the correlation matrix. * @param windowSize - Optional. The number of periods to use for the rolling window. If not provided, uses the entire data length. * @returns An array of correlation matrices, each representing the correlations between assets for a window of data. * * @remarks * - If `windowSize` is not specified, the function computes the correlation matrix for the entire dataset. * - Each correlation matrix is a nested object where the outer keys are asset names, and the inner keys are asset names with correlation values. * - Correlation values are set to `1` for diagonal elements (self-correlation), and `0` if there is insufficient data. * - Handles missing or invalid data by skipping those entries in the calculation. */ function calculateCorrelationMatrix(data, assetColumns, windowSize) { if (!data || data.length === 0 || assetColumns.length === 0) { return []; } const results = []; const effectiveWindowSize = windowSize || data.length; for (let i = effectiveWindowSize - 1; i < data.length; i++) { const windowData = data.slice(i - effectiveWindowSize + 1, i + 1); const correlationMatrix = {}; // Initialize matrix assetColumns.forEach(asset1 => { correlationMatrix[asset1] = {}; assetColumns.forEach(asset2 => { correlationMatrix[asset1][asset2] = asset1 === asset2 ? 1 : 0; }); }); // Calculate correlations for (let j = 0; j < assetColumns.length; j++) { for (let k = j; k < assetColumns.length; k++) { const asset1 = assetColumns[j]; const asset2 = assetColumns[k]; if (asset1 === asset2) { correlationMatrix[asset1][asset2] = 1; continue; } // Extract valid data pairs const pairs = []; windowData.forEach(row => { const val1 = row[asset1]; const val2 = row[asset2]; if (typeof val1 === 'number' && typeof val2 === 'number' && !isNaN(val1) && !isNaN(val2)) { pairs.push([val1, val2]); } }); if (pairs.length < 2) { correlationMatrix[asset1][asset2] = 0; correlationMatrix[asset2][asset1] = 0; continue; } // Calculate means const mean1 = pairs.reduce((sum, pair) => sum + pair[0], 0) / pairs.length; const mean2 = pairs.reduce((sum, pair) => sum + pair[1], 0) / pairs.length; // Calculate correlation let numerator = 0; let sumSq1 = 0; let sumSq2 = 0; pairs.forEach(([val1, val2]) => { const diff1 = val1 - mean1; const diff2 = val2 - mean2; numerator += diff1 * diff2; sumSq1 += diff1 * diff1; sumSq2 += diff2 * diff2; }); const denominator = Math.sqrt(sumSq1 * sumSq2); const correlation = denominator === 0 ? 0 : numerator / denominator; correlationMatrix[asset1][asset2] = correlation; correlationMatrix[asset2][asset1] = correlation; } } results.push(correlationMatrix); } return results; }