UNPKG

@railpath/finance-toolkit

Version:

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

40 lines (39 loc) 1.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.calculateGarmanKlassVolatility = calculateGarmanKlassVolatility; /** * Garman-Klass volatility estimator * Uses OHLC data, most efficient unbiased estimator * * Garman, M. B., & Klass, M. J. (1980). "On the Estimation of Security Price Volatilities * from Historical Data" */ function calculateGarmanKlassVolatility(openPrices, highPrices, lowPrices, closePrices) { const n = openPrices.length; if (n === 0) { throw new Error('Price arrays cannot be empty'); } if (n !== highPrices.length || n !== lowPrices.length || n !== closePrices.length) { throw new Error('All price arrays must have equal length'); } let sum = 0; for (let i = 0; i < n; i++) { // Validate prices if (openPrices[i] <= 0 || highPrices[i] <= 0 || lowPrices[i] <= 0 || closePrices[i] <= 0) { throw new Error('All prices must be positive'); } if (highPrices[i] < lowPrices[i]) { throw new Error('High price must be greater than or equal to low price'); } const hlRatio = Math.log(highPrices[i] / lowPrices[i]); const coRatio = Math.log(closePrices[i] / openPrices[i]); // Garman-Klass formula: 0.5 * (ln(H/L))² - (2*ln(2)-1) * (ln(C/O))² sum += 0.5 * Math.pow(hlRatio, 2) - (2 * Math.log(2) - 1) * Math.pow(coRatio, 2); } const variance = sum / n; // Handle negative variance (can happen with the formula) if (variance < 0) { return 0; } return Math.sqrt(variance); }