/** * Financial calculation utilities */ export const financialUtils = { /** * Calculate the Sharpe ratio * @param returns Array of period returns * @param riskFreeRate The risk-free rate (e.g. 0.02 for 2%) */ calculateSharpeRatio(returns: number[], riskFreeRate: number = 0.02): number { if (returns.length < 2) { return 0; } // Calculate average return const avgReturn = returns.reduce((sum, val) => sum + val, 0) / returns.length; // Calculate standard deviation const squaredDiffs = returns.map(val => Math.pow(val - avgReturn, 2)); const avgSquaredDiff = squaredDiffs.reduce((sum, val) => sum + val, 0) / squaredDiffs.length; const stdDev = Math.sqrt(avgSquaredDiff); // Avoid division by zero if (stdDev === 0) return 0; // Calculate Sharpe ratio return (avgReturn - riskFreeRate) / stdDev; }, /** * Calculate the maximum drawdown * @param equityCurve Array of equity values over time */ calculateMaxDrawdown(equityCurve: number[]): number { if (equityCurve.length < 2) { return 0; } let maxDrawdown = 0; let peak = equityCurve[0]; for (let i = 1; i < equityCurve.length; i++) { if (equityCurve[i] > peak) { peak = equityCurve[i]; } else { const drawdown = (peak - equityCurve[i]) / peak; maxDrawdown = Math.max(maxDrawdown, drawdown); } } return maxDrawdown; }, /** * Calculate the Compound Annual Growth Rate (CAGR) * @param startValue Initial investment value * @param endValue Final investment value * @param years Number of years */ calculateCAGR(startValue: number, endValue: number, years: number): number { if (years <= 0 || startValue <= 0 || endValue <= 0) { return 0; } return Math.pow(endValue / startValue, 1 / years) - 1; } };