Asset Allocation Stress Test

Asset Allocation Stress Test

Simulate the impact of adverse market scenarios on your portfolio.

1. Portfolio Setup

Asset Allocation (%)

%
%
%
%
%
Total Allocation: 0%

2. Stress Scenario

Scenario assumptions will be shown here.

Stressed Total Portfolio Value: ${formatCurrency(totalStressedValue)}

Total Portfolio Change (USD): ${formatCurrency(portfolioChangeUSD, true)}

Total Portfolio Change (%): ${formatPercent(portfolioChangePercent, true)}

`; // Update or create chart if (stressTestChartInstance) { stressTestChartInstance.destroy(); } stressTestChartInstance = new Chart(chartCanvas, { type: 'bar', data: { labels: chartLabels.concat('Total Portfolio'), datasets: [ { label: 'Initial Value (USD)', data: initialValuesChart.concat(totalInitialValue), backgroundColor: 'rgba(52, 152, 219, 0.7)', // Blue borderColor: 'rgba(52, 152, 219, 1)', borderWidth: 1 }, { label: 'Stressed Value (USD)', data: stressedValuesChart.concat(totalStressedValue), backgroundColor: 'rgba(230, 126, 34, 0.7)', // Orange borderColor: 'rgba(230, 126, 34, 1)', borderWidth: 1 } ] }, options: { responsive: true, maintainAspectRatio: true, scales: { y: { beginAtZero: true, ticks: { callback: function(value) { return '$' + value; } } } }, plugins: { title: { display: true, text: 'Portfolio Value: Initial vs. Stressed' }, tooltip: { callbacks: { label: function(context) { return context.dataset.label + ': ' + formatCurrency(context.parsed.y); } } } } } }); resultsSectionEl.style.display = 'block'; document.querySelector('html, body').scrollTop = resultsSectionEl.offsetTop - 20; // Scroll to results // Prepare PDF content document.getElementById('pdfReportDate').textContent = `Report generated on: ${new Date().toLocaleDateString()}`; document.getElementById('pdfTotalValue').textContent = `Total Initial Portfolio Value: ${formatCurrency(totalInitialValue)}`; const pdfInitialAllocTableBody = document.querySelector('#pdfInitialAllocationTable tbody'); pdfInitialAllocTableBody.innerHTML = ''; assetClasses.forEach(acName => { const percent = allocations[acName]; const initialAssetValue = totalValue * (percent / 100); const row = pdfInitialAllocTableBody.insertRow(); row.insertCell().textContent = acName; row.insertCell().textContent = formatPercent(percent); row.insertCell().textContent = formatCurrency(initialAssetValue); }); document.getElementById('pdfScenarioName').textContent = selectedScenarioName; const pdfScenarioAssumpsTableBody = document.querySelector('#pdfScenarioAssumptionsTable tbody'); pdfScenarioAssumpsTableBody.innerHTML = ''; assetClasses.forEach(acName => { const row = pdfScenarioAssumpsTableBody.insertRow(); row.insertCell().textContent = acName; row.insertCell().textContent = formatPercent(scenarioImpacts[acName], true); }); document.getElementById('pdfStressedTotalValue').textContent = `Stressed Total Portfolio Value: ${formatCurrency(totalStressedValue)}`; document.getElementById('pdfTotalChangeUSD').textContent = `Total Portfolio Change (USD): ${formatCurrency(portfolioChangeUSD, true)}`; document.getElementById('pdfTotalChangePercent').textContent = `Total Portfolio Change (%): ${formatPercent(portfolioChangePercent, true)}`; const pdfStressedTableBody = document.querySelector('#pdfStressedBreakdownTable tbody'); pdfStressedTableBody.innerHTML = ''; assetClasses.forEach(acName => { const percent = allocations[acName] / 100; const initialAssetValue = totalValue * percent; const impactPercentVal = scenarioImpacts[acName] / 100; const assetChangeVal = initialAssetValue * impactPercentVal; const stressedAssetValue = initialAssetValue + assetChangeVal; const row = pdfStressedTableBody.insertRow(); row.insertCell().textContent = acName; row.insertCell().textContent = formatCurrency(initialAssetValue); row.insertCell().textContent = formatCurrency(stressedAssetValue); row.insertCell().textContent = formatCurrency(assetChangeVal, true); }); // For PDF chart image: const chartImageEl = document.getElementById('pdfChartImage'); const chartNoteEl = document.getElementById('pdfChartNote'); if (chartCanvas.toDataURL) { try { chartImageEl.src = chartCanvas.toDataURL('image/png'); chartImageEl.style.display = 'block'; chartNoteEl.style.display = 'none'; } catch (e) { console.error("Error converting chart to image for PDF:", e); chartImageEl.style.display = 'none'; chartNoteEl.textContent = "Chart could not be embedded in PDF."; chartNoteEl.style.display = 'block'; } } else { chartImageEl.style.display = 'none'; chartNoteEl.textContent = "Chart visualization is available in the web view."; chartNoteEl.style.display = 'block'; } }); resetBtn.addEventListener('click', function() { totalPortfolioValueEl.value = ''; allocInputs.Equities.value = '50'; allocInputs.Bonds.value = '30'; allocInputs.Gold.value = '10'; allocInputs.RealEstate.value = '5'; allocInputs.Cash.value = '5'; updateTotalAllocation(); stressScenarioEl.selectedIndex = 0; updateScenarioAssumptionsDisplay(); resultsSectionEl.style.display = 'none'; resultsSummaryEl.innerHTML = ''; resultsTableBodyEl.innerHTML = ''; errorMessagesEl.style.display = 'none'; if (stressTestChartInstance) { stressTestChartInstance.destroy(); stressTestChartInstance = null; } }); pdfDownloadBtn.addEventListener('click', function() { const elementToPrint = document.getElementById('pdfReportContent'); elementToPrint.style.display = 'block'; // Temporarily display for PDF generation const opt = { margin: [10, 8, 12, 8], // top, left, bottom, right in mm filename: 'asset_allocation_stress_test_report.pdf', image: { type: 'jpeg', quality: 0.98 }, html2canvas: { scale: 2, useCORS: true, logging: false, width: elementToPrint.scrollWidth, windowWidth: elementToPrint.scrollWidth }, jsPDF: { unit: 'mm', format: 'a4', orientation: 'portrait' } }; // Before generating PDF, ensure chart image source is set if possible const chartImageForPdfEl = elementToPrint.querySelector('#pdfChartImage'); if (stressTestChartInstance && chartCanvas.toDataURL) { try { chartImageForPdfEl.src = chartCanvas.toDataURL('image/png'); chartImageForPdfEl.style.display = 'block'; elementToPrint.querySelector('#pdfChartNote').style.display = 'none'; } catch (e) { chartImageForPdfEl.style.display = 'none'; elementToPrint.querySelector('#pdfChartNote').style.display = 'block'; elementToPrint.querySelector('#pdfChartNote').textContent = "Chart could not be embedded in PDF."; } } else { chartImageForPdfEl.style.display = 'none'; elementToPrint.querySelector('#pdfChartNote').style.display = 'block'; elementToPrint.querySelector('#pdfChartNote').textContent = "Chart visualization available in web view."; } html2pdf().from(elementToPrint).set(opt).save().then(() => { elementToPrint.style.display = 'none'; }).catch(err => { console.error("Error generating PDF:", err); elementToPrint.style.display = 'none'; }); }); // Initial setup populateScenarios(); updateTotalAllocation(); });
Scroll to Top