Quantitative Macro Hedge Fund Portfolio Modeler
Macro Factor/Strategy Information
Define your macro factors or strategies and input their historical monthly returns (%).
Portfolio Allocation
Allocate weights (in percentage) to each factor/strategy to form your overall portfolio. Weights must sum to 100%.
Performance Results & Optimization
Review the performance metrics for individual factors/strategies and the aggregated portfolio. Run optimization to find the minimum variance portfolio.
Individual Factor/Strategy Performance
Aggregated Portfolio Performance
Cumulative Return: 0.00%
Annualized Return: 0.00%
Annualized Volatility (Std Dev): 0.00%
Sharpe Ratio: 0.00
Maximum Drawdown: 0.00%
Optimized Portfolio (Minimum Variance)
This allocation aims to minimize portfolio risk given your input data.
Optimal Weights:
Expected Annualized Return: 0.00%
Annualized Volatility (Risk): 0.00%
Sharpe Ratio: 0.00
${factorName}: ${(weight * 100).toFixed(2)}%
`; }); optimizedPortfolioReturnSpan.textContent = `${(optimalReturn * 100).toFixed(2)}%`; optimizedPortfolioRiskSpan.textContent = `${(minRisk * 100).toFixed(2)}%`; optimizedPortfolioSharpeSpan.textContent = `${optimalSharpe.toFixed(2)}`; optimizationResultsDiv.classList.remove('hidden'); optimizationCalculated = true; showTab(currentTab); // Re-evaluate PDF button visibility }); // --- Input Validation --- function validateFactorInputs() { let isValid = true; const months = parseInt(numMonthsInput.value); if (isNaN(months) || months < 2) { alertUser('Number of historical months must be an integer greater than or equal to 2.'); numMonthsInput.focus(); return false; } const rfRate = parseFloat(riskFreeRateInput.value); if (isNaN(rfRate)) { alertUser('Risk-free rate must be a number.'); riskFreeRateInput.focus(); return false; } if (factorData.length === 0) { alertUser('Please add at least one factor/strategy.'); return false; } for (const factor of factorData) { const nameInput = document.getElementById(`factor-name-${factor.id}`); if (!nameInput || !nameInput.value.trim()) { alertUser('Factor/Strategy Name cannot be empty.'); if (nameInput) nameInput.focus(); isValid = false; break; } for (let i = 0; i < numHistoricalMonths; i++) { const returnInput = document.getElementById(`factor-${factor.id}-return-${i}`); if (!returnInput || isNaN(parseFloat(returnInput.value)) || returnInput.value.trim() === '') { alertUser(`Monthly Return for ${factor.name}, Month ${i + 1} must be a number.`); if (returnInput) returnInput.focus(); isValid = false; break; } } if (!isValid) break; // Break outer loop if inner loop failed } return isValid; } // --- PDF Generation Function --- downloadPdfButton.addEventListener('click', async function() { const pdfTitle = 'Quantitative Macro Hedge Fund Performance Report'; let pdfHtmlContent = `${pdfTitle}
`; // General Parameters pdfHtmlContent += `Report Parameters
`; pdfHtmlContent += `Number of Historical Months: ${numHistoricalMonths}
`; pdfHtmlContent += `Annual Risk-Free Rate: ${(riskFreeRate * 100).toFixed(2)}%
`; // 1. Individual Factor/Strategy Performance if (factorData.length > 0) { pdfHtmlContent += `Individual Factor/Strategy Performance
`; factorData.forEach(factor => { const returnsDecimal = factor.returns.map(r => r / 100); const cumulativeReturn = returnsDecimal.reduce((acc, r) => acc * (1 + r), 1) - 1; const annualizedReturn = Math.pow(1 + cumulativeReturn, 12 / numHistoricalMonths) - 1; const monthlyStdDev = calculateStandardDeviation(returnsDecimal); const annualizedStdDev = monthlyStdDev * Math.sqrt(12); const annualizedRiskFreeRate = Math.pow(1 + riskFreeRate, 12 / numHistoricalMonths) - 1; const sharpeRatio = annualizedStdDev !== 0 ? (annualizedReturn - annualizedRiskFreeRate) / annualizedStdDev : 0; let maxDrawdown = 0; let peakValue = 1; let currentValue = 1; returnsDecimal.forEach(r => { currentValue *= (1 + r); if (currentValue > peakValue) { peakValue = currentValue; } const drawdown = (peakValue - currentValue) / peakValue; if (drawdown > maxDrawdown) { maxDrawdown = drawdown; } }); pdfHtmlContent += `${factor.name}
`; pdfHtmlContent += `Cumulative Return: ${(cumulativeReturn * 100).toFixed(2)}%
`; pdfHtmlContent += `Annualized Return: ${(annualizedReturn * 100).toFixed(2)}%
`; pdfHtmlContent += `Annualized Volatility: ${(annualizedStdDev * 100).toFixed(2)}%
`; pdfHtmlContent += `Sharpe Ratio: ${sharpeRatio.toFixed(2)}
`; pdfHtmlContent += `Maximum Drawdown: ${(maxDrawdown * 100).toFixed(2)}%
`; pdfHtmlContent += `Monthly Returns (%):
`; pdfHtmlContent += `| ${r.toFixed(2)} | `; }); pdfHtmlContent += `
Aggregated Portfolio Performance (Your Allocation)
`; pdfHtmlContent += `Cumulative Return: ${portfolioCumulativeReturnSpan.textContent}
`; pdfHtmlContent += `Annualized Return: ${portfolioAnnualizedReturnSpan.textContent}
`; pdfHtmlContent += `Annualized Volatility (Std Dev): ${portfolioAnnualizedStdDevSpan.textContent}
`; pdfHtmlContent += `Sharpe Ratio: ${portfolioSharpeRatioSpan.textContent}
`; pdfHtmlContent += `Maximum Drawdown: ${portfolioMaxDrawdownSpan.textContent}
`; pdfHtmlContent += `Portfolio Allocation Weights:
`; pdfHtmlContent += `| Factor/Strategy | Weight (%) |
|---|---|
| ${factor.name} | ${(allocationWeights[index] * 100).toFixed(2)} |
Optimized Portfolio (Minimum Variance)
`; pdfHtmlContent += `Expected Annualized Return: ${optimizedPortfolioReturnSpan.textContent}
`; pdfHtmlContent += `Annualized Volatility (Risk): ${optimizedPortfolioRiskSpan.textContent}
`; pdfHtmlContent += `Sharpe Ratio: ${optimizedPortfolioSharpeSpan.textContent}
`; pdfHtmlContent += `Optimal Weights:
`; pdfHtmlContent += `| Factor/Strategy | Weight (%) |
|---|---|
| ${name} | ${weight} |