Portfolio Stress Test

DIY Investor Portfolio Stress Test

1. Enter Your Current Portfolio

Asset Allocation (Enter percentages for each asset class):

2. Select Stress Scenarios

Simulates a sharp decline in tech stocks. (Stocks: -40%, Bonds: +5%, Real Estate: 0%, Cash: 0%)

Simulates a broad market downturn affecting many asset classes. (Stocks: -50%, Bonds: +10%, Real Estate: -20%, Cash: 0%)

Simulates a rapid, short-term market shock. (Stocks: -30%, Bonds: +2%, Real Estate: -5%, Cash: 0%)

Simulates a challenging stagflation-like environment. (Stocks: -35%, Bonds: -10%, Real Estate: -15%, Cash: -5%)

3. Stress Test Results

No results yet. Please input your portfolio and select scenarios, then click "Calculate Results".

Initial Portfolio Value: $${portfolio.totalValue.toLocaleString('en-US')}

${portfolio.assets.map(asset => ``).join('')} `; scenarios.forEach(scenario => { let portfolioValueAfterStress = 0; let assetImpactCells = ''; portfolio.assets.forEach(asset => { const initialAssetValue = portfolio.totalValue * (asset.percentage / 100); const assetImpactPercentage = scenario.impact[asset.name] !== undefined ? scenario.impact[asset.name] : 0; // Default to 0 if asset not specified in scenario const assetValueChange = initialAssetValue * (assetImpactPercentage / 100); const finalAssetValue = initialAssetValue + assetValueChange; portfolioValueAfterStress += finalAssetValue; assetImpactCells += ``; }); const totalLoss = portfolio.totalValue - portfolioValueAfterStress; const percentageLoss = (totalLoss / portfolio.totalValue) * 100; resultsHtml += ` ${assetImpactCells} `; }); resultsHtml += `
Scenario${asset.name} Impact (%)Portfolio Value After Stress Total Loss ($) Percentage Loss (%)
${assetImpactPercentage.toFixed(1)}%
${scenario.name}$${portfolioValueAfterStress.toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 })} $${totalLoss.toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 })} ${percentageLoss.toFixed(2)}%
`; resultsContent.innerHTML = resultsHtml; showTab(2); // Go to results tab }; // --- PDF Download Functionality --- /** * Generates a PDF of the results content. */ window.generatePDF = async function() { // Show loading spinner pdfButtonText.classList.add('hidden'); pdfSpinner.classList.remove('hidden'); pdfDownloadButton.disabled = true; try { // Initialize jsPDF const { jsPDF } = window.jspdf; const doc = new jsPDF('p', 'pt', 'letter'); // Portrait, points, Letter size // Get the content to be converted to PDF (resultsContent div) const content = resultsContent; // Calculate the optimal scale to fit content on PDF page const pdfWidth = doc.internal.pageSize.getWidth(); const pdfHeight = doc.internal.pageSize.getHeight(); // Use html2canvas to render the HTML content to a canvas const canvas = await html2canvas(content, { scale: 2, // Increase scale for better resolution useCORS: true, // Required if content includes images from other domains logging: false, // Disable logging for cleaner console }); const imgData = canvas.toDataURL('image/png'); const imgWidth = canvas.width; const imgHeight = canvas.height; // Calculate the aspect ratio to fit the image on the PDF page const ratio = Math.min(pdfWidth / imgWidth, pdfHeight / imgHeight); const finalWidth = imgWidth * ratio * 0.9; // 90% of page width to add some margin const finalHeight = imgHeight * ratio * 0.9; const xOffset = (pdfWidth - finalWidth) / 2; const yOffset = (pdfHeight - finalHeight) / 2; // Add title to PDF doc.setFontSize(22); doc.text("Portfolio Stress Test Results", pdfWidth / 2, 60, { align: "center" }); // Add a line below the title doc.setDrawColor(59, 130, 246); // Blue-500 doc.setLineWidth(1); doc.line(xOffset, 75, pdfWidth - xOffset, 75); // Add the image (rendered HTML) to the PDF doc.addImage(imgData, 'PNG', xOffset, yOffset + 20, finalWidth, finalHeight); // Adjust yOffset for title // Save the PDF doc.save('Portfolio_Stress_Test_Results.pdf'); } catch (error) { console.error("Error generating PDF:", error); alert("Failed to generate PDF. Please try again."); // Using alert as per spec } finally { // Hide spinner and re-enable button pdfButtonText.classList.remove('hidden'); pdfSpinner.classList.add('hidden'); pdfDownloadButton.disabled = false; } }; });
Scroll to Top