quantitivecalc
Version:
A TypeScript library providing advanced quantitative finance functions for risk analysis, performance metrics, and technical indicators. (Currently in development)
65 lines (64 loc) • 3.29 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.calculateAlpha = calculateAlpha;
/**
* Calculates the rolling alpha for an asset relative to a benchmark using a specified window size.
* Alpha is computed as the intercept of the linear regression of asset excess returns against benchmark excess returns,
* annualized over the window.
*
* @param data - Array of data objects containing asset and benchmark returns.
* @param assetReturnsColumn - The key in each data object for the asset's returns.
* @param benchmarkReturnsColumn - The key in each data object for the benchmark's returns.
* @param resultColumn - The key to store the calculated alpha in each result object.
* @param windowSize - Number of periods to use for the rolling window (default: 252, typical for daily data over 1 year).
* @param riskFreeRate - Annual risk-free rate used to calculate excess returns (default: 0.02, or 2%).
* @returns A new array of data objects with the calculated alpha stored in the specified result column.
*/
function calculateAlpha(data, assetReturnsColumn, benchmarkReturnsColumn, resultColumn, windowSize = 252, // 1 year for daily data
riskFreeRate = 0.02) {
if (!data || data.length === 0) {
return [];
}
const result = data.map(row => ({ ...row }));
const dailyRiskFreeRate = riskFreeRate / 252;
for (let i = 0; i < result.length; i++) {
if (i < windowSize - 1) {
result[i][resultColumn] = null;
}
else {
const assetReturns = [];
const benchmarkReturns = [];
// Collect returns for the window
for (let j = i - windowSize + 1; j <= i; j++) {
const assetReturn = result[j][assetReturnsColumn];
const benchmarkReturn = result[j][benchmarkReturnsColumn];
if (typeof assetReturn === 'number' &&
!isNaN(assetReturn) &&
typeof benchmarkReturn === 'number' &&
!isNaN(benchmarkReturn)) {
assetReturns.push(assetReturn - dailyRiskFreeRate);
benchmarkReturns.push(benchmarkReturn - dailyRiskFreeRate);
}
}
if (assetReturns.length > 10) {
// Need sufficient data points
// Calculate beta (slope of regression)
const n = assetReturns.length;
const sumX = benchmarkReturns.reduce((a, b) => a + b, 0);
const sumY = assetReturns.reduce((a, b) => a + b, 0);
const sumXY = benchmarkReturns.reduce((sum, x, idx) => sum + x * assetReturns[idx], 0);
const sumXX = benchmarkReturns.reduce((sum, x) => sum + x * x, 0);
const beta = (n * sumXY - sumX * sumY) / (n * sumXX - sumX * sumX);
const avgAssetReturn = sumY / n;
const avgBenchmarkReturn = sumX / n;
// Alpha = Asset Return - Beta * Benchmark Return (annualized)
const alpha = (avgAssetReturn - beta * avgBenchmarkReturn) * 252;
result[i][resultColumn] = alpha;
}
else {
result[i][resultColumn] = null;
}
}
}
return result;
}