Alternative Risk Premia (ARP) Strategy Evaluator
Global Parameter
Define Individual ARP Strategies
ARP Portfolio Evaluation
Total Weight: 0%
Portfolio Evaluation Metrics:
Define strategies and allocate weights to see portfolio metrics.
Important Note on Portfolio Volatility & Sharpe Ratio: This tool calculates the weighted average expected return. True portfolio volatility and Sharpe Ratio depend heavily on the correlations between the individual ARP strategies. These correlations are not factored into this simplified evaluator. Therefore, the actual portfolio volatility could be significantly different from a simple average of individual volatilities, and a precise portfolio Sharpe Ratio is not provided. Diversification benefits arise when strategies are not perfectly correlated.
Define strategies and allocate weights, then click "Evaluate Portfolio".
'; document.getElementById('arpDownloadPdfButton').style.display = 'none'; } } tabs.forEach(tab => tab.addEventListener('click', () => switchTab(tab.dataset.tab))); document.getElementById('arpGoToEvaluateTab')?.addEventListener('click', () => { if (validateStrategyInputs()) switchTab('evaluateTab'); }); document.getElementById('arpGoToDefineTab')?.addEventListener('click', () => switchTab('defineTab')); // --- Global State --- let arpStrategies = []; // { id, name, expReturn, volatility, weight (added in tab 2) } let riskFreeRate = 0.02; // Default 2% // --- Tab 1: Define ARP Strategies --- const riskFreeRateInput = document.getElementById('riskFreeRate'); const numArpStrategiesInput = document.getElementById('numArpStrategies'); const generateArpInputsButton = document.getElementById('generateArpInputs'); const arpStrategyDefinitionArea = document.getElementById('arpStrategyDefinitionArea'); riskFreeRateInput?.addEventListener('change', () => { riskFreeRate = parseFloat(riskFreeRateInput.value) / 100 || 0; }); generateArpInputsButton?.addEventListener('click', () => { const count = parseInt(numArpStrategiesInput.value); arpStrategies = []; arpStrategyDefinitionArea.innerHTML = ''; if (count >= 2 && count <= 5) { for (let i = 0; i < count; i++) { const strategyId = `arp_${i}`; // Add to global state with default values arpStrategies.push({ id: strategyId, name: `Strategy ${i+1}`, expReturn: 5.0, // Default 5% volatility: 10.0, // Default 10% weight: 0 // Will be set in tab 2 }); const strategyRow = document.createElement('div'); strategyRow.className = 'arp-strategy-row'; strategyRow.innerHTML = `Please define ARP strategies on the first tab.
'; return; } let tableHTML = 'Assign Portfolio Weights:
| Strategy Name | Exp. Return (%) | Volatility (%) | Weight (%) |
|---|---|---|---|
| ${escapeHtml(s.name)} | ${s.expReturn.toFixed(1)} | ${s.volatility.toFixed(1)} |
Individual ARP Strategy Metrics:
| Strategy Name | Exp. Return (%) | Volatility (%) | Weight (%) | Sharpe Ratio* |
|---|---|---|---|---|
| ${escapeHtml(s.name)} | ${s.expReturn.toFixed(1)} | ${s.volatility.toFixed(1)} | ${s.weight.toFixed(1)} | ${sharpeRatio} |
Portfolio Summary:
Weighted Average Expected Portfolio Return: ${(weightedAvgReturn * 100).toFixed(2)}%
*Sharpe Ratio calculated using a risk-free rate of ${(riskFreeRate*100).toFixed(1)}%. Assumes individual strategy inputs are net of fees.
`; portfolioMetricsEl.innerHTML = evaluationHTML; downloadPdfButtonArp.style.display = 'block'; }); // --- PDF Download --- downloadPdfButtonArp?.addEventListener('click', function () { const { jsPDF } = window.jspdf; const pdfOutputArea = document.getElementById('arpPdfOutputArea'); if (!pdfOutputArea || arpStrategies.length === 0 || portfolioMetricsEl.innerHTML.includes("Define strategies")) { alert('Please define strategies, allocate weights, and evaluate before downloading PDF.'); return; } html2canvas(pdfOutputArea, { scale: 1.5, useCORS: true, backgroundColor: '#ffffff' }) // Slightly increased scale for PDF clarity .then(canvas => { const imgData = canvas.toDataURL('image/jpeg', 0.85); // JPEG for smaller size const pdf = new jsPDF({ orientation: 'portrait', unit: 'pt', format: 'a4' }); const pdfWidth = pdf.internal.pageSize.getWidth(); const pdfHeight = pdf.internal.pageSize.getHeight(); const margin = 30; const contentWidth = pdfWidth - 2 * margin; const canvasWidth = canvas.width; const canvasHeight = canvas.height; const ratio = canvasWidth / canvasHeight; let imgWidth = contentWidth; let imgHeight = imgWidth / ratio; if (imgHeight > pdfHeight - 2 * margin) { imgHeight = pdfHeight - 2 * margin; imgWidth = imgHeight * ratio; } pdf.addImage(imgData, 'JPEG', margin, margin, imgWidth, imgHeight, undefined, 'MEDIUM'); pdf.save('ARP_Strategy_Evaluation.pdf'); }) .catch(err => { console.error("Error generating PDF:", err); alert("Error generating PDF. See console for details."); }); }); // --- Utility --- function escapeHtml(unsafe) { if (typeof unsafe !== 'string') return unsafe === undefined || unsafe === null ? '' : String(unsafe); return unsafe.replace(/&/g, "&").replace(//g, ">").replace(/"/g, """).replace(/'/g, "'"); } // --- Initial Setup --- riskFreeRateInput.value = (riskFreeRate * 100).toFixed(1); // Set initial display value generateArpInputsButton.click(); // Auto-generate inputs for default number of strategies switchTab('defineTab'); // Start on the first tab });