UNPKG

@railpath/finance-toolkit

Version:

Production-ready finance library for portfolio construction, risk analytics, quantitative metrics, and ML-based regime detection

67 lines (66 loc) 2.58 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.calculateCovarianceMatrix = calculateCovarianceMatrix; const CovarianceMatrixOptionsSchema_1 = require("../schemas/CovarianceMatrixOptionsSchema"); const CovarianceMatrixResultSchema_1 = require("../schemas/CovarianceMatrixResultSchema"); /** * Calculate Covariance Matrix * * Cov(X,Y) = E[(X - μ_X)(Y - μ_Y)] * * Measures how two variables move together. * Diagonal = variances * Off-diagonal = covariances * * @param options - Array of return series and optional labels * @returns Covariance matrix with variances */ function calculateCovarianceMatrix(options) { const { returns, labels } = CovarianceMatrixOptionsSchema_1.CovarianceMatrixOptionsSchema.parse(options); const n = returns.length; // Validate all series have same length const seriesLength = returns[0].length; if (returns.some((series) => series.length !== seriesLength)) { throw new Error('All return series must have the same length'); } if (seriesLength < 2) { throw new Error('Each return series must have at least 2 data points'); } // Generate labels if not provided const finalLabels = labels && labels.length === n ? labels : Array.from({ length: n }, (_, i) => `Asset ${i + 1}`); // Calculate means const means = returns.map((series) => series.reduce((sum, r) => sum + r, 0) / seriesLength); // Calculate covariance matrix const matrix = Array.from({ length: n }, () => Array(n).fill(0)); for (let i = 0; i < n; i++) { for (let j = 0; j < n; j++) { let covariance = 0; for (let k = 0; k < seriesLength; k++) { covariance += (returns[i][k] - means[i]) * (returns[j][k] - means[j]); } covariance /= seriesLength - 1; // Sample covariance matrix[i][j] = covariance; } } // Extract variances (diagonal) const variances = matrix.map((row, i) => row[i]); // Calculate average covariance (off-diagonal only) const offDiagonal = []; for (let i = 0; i < n; i++) { for (let j = i + 1; j < n; j++) { offDiagonal.push(matrix[i][j]); } } const averageCovariance = offDiagonal.length > 0 ? offDiagonal.reduce((sum, c) => sum + c, 0) / offDiagonal.length : 0; return CovarianceMatrixResultSchema_1.CovarianceMatrixResultSchema.parse({ matrix, labels: finalLabels, variances, averageCovariance, }); }