Modern Portfolio Theory (MPT) Optimizer

Asset Inputs (Expected Annual Values in %):

Asset Correlations (Between -1 and 1):

Add at least two assets to define correlations.

Optimization Type:

Optimal Portfolio Details:

Optimization Target:

Expected Return: 0.00%

Standard Deviation (Risk): 0.00%

Optimal Asset Weights:

Asset Name Weight (%)

Efficient Frontier:

Expected Return: ${data.optimalPortfolio.return.toFixed(2)}%

Standard Deviation (Risk): ${data.optimalPortfolio.stdDev.toFixed(2)}%

${riskFreeRateRow}

Optimal Asset Weights:

${data.optimalPortfolio.weights.map((w, index) => { const assetId = assetIds[index]; const assetName = assetData[assetId] ? assetData[assetId].name : `Asset ${assetId}`; return ` `; }).join('')}
Asset Name Weight (%)
${assetName} ${(w * 100).toFixed(2)}%

Efficient Frontier Chart:

${data.chartDataURL ? `` : '

Chart not available.

'}
`; const tempDiv = document.createElement('div'); tempDiv.innerHTML = pdfContentHtml; document.body.appendChild(tempDiv); // Temporarily add to DOM to ensure styles apply const options = { margin: 10, filename: 'MPT_Optimizer_Results.pdf', image: { type: 'jpeg', quality: 0.98 }, html2canvas: { scale: 2, logging: true, dpi: 192, letterRendering: true }, jsPDF: { unit: 'mm', format: 'a4', orientation: 'portrait' } }; html2pdf().set(options).from(tempDiv).save().finally(() => { document.body.removeChild(tempDiv); }); } // Event Listeners on DOMContentLoaded document.addEventListener('DOMContentLoaded', function() { const addAssetBtn = document.getElementById('addAssetBtn'); const optimizeBtn = document.getElementById('optimizeBtn'); const resetBtn = document.getElementById('resetBtn'); const downloadPdfBtn = document.getElementById('downloadPdfBtn'); const optimizeMVPRadio = document.getElementById('optimizeMVP'); const optimizeTangencyRadio = document.getElementById('optimizeTangency'); const riskFreeRateInputDiv = document.getElementById('riskFreeRateInput'); // Initial setup addAsset(); // Add first asset addAsset(); // Add second asset for initial correlations // Event listeners for buttons if (addAssetBtn) addAssetBtn.addEventListener('click', addAsset); if (optimizeBtn) optimizeBtn.addEventListener('click', optimizePortfolio); if (resetBtn) resetBtn.addEventListener('click', resetCalculator); if (downloadPdfBtn) downloadPdfBtn.addEventListener('click', downloadPdf); // Event listener for optimization type change function toggleRiskFreeRateInput() { if (optimizeTangencyRadio.checked) { riskFreeRateInputDiv.classList.add('show'); } else { riskFreeRateInputDiv.classList.remove('show'); } } if (optimizeMVPRadio) optimizeMVPRadio.addEventListener('change', toggleRiskFreeRateInput); if (optimizeTangencyRadio) optimizeTangencyRadio.addEventListener('change', toggleRiskFreeRateInput); // Call once on load to set initial visibility toggleRiskFreeRateInput(); });
Scroll to Top