Hedge Fund Portfolio Stress Tester

Hedge Fund Portfolio Stress Tester

Simulate market shocks to assess your portfolio's resilience.

Portfolio Performance Under Stress

Detailed Scenario Analysis

Impact by Asset Class

${(result.totalImpact * 100).toFixed(2)}%

`; // Asset Impact Chart const impactCtx = document.getElementById('assetImpactChart').getContext('2d'); if (assetImpactChart) assetImpactChart.destroy(); assetImpactChart = new Chart(impactCtx, { type: 'bar', data: { labels: result.assetImpacts.map(a => a.class), datasets: [{ label: 'P&L Contribution (%)', data: result.assetImpacts.map(a => (a.impact * 100).toFixed(2)), backgroundColor: result.assetImpacts.map(a => a.impact < 0 ? '#fca5a5' : '#86efac'), }] }, options: { indexAxis: 'y', responsive: true, plugins: { legend: { display: false } }, scales: { x: { ticks: { callback: (value) => value + '%' } } } } }); } // --- EVENT HANDLING --- function handleConfigChange(e) { const { index, field, type } = e.target.dataset; const value = e.target.type === 'number' ? parseFloat(e.target.value) : e.target.value; appData[type][index][field] = value; updateDashboard(); } const portfolioBody = document.getElementById('portfolio-table-body'); portfolioBody.addEventListener('change', e => { e.target.dataset.type = 'portfolio'; handleConfigChange(e); }); portfolioBody.addEventListener('click', e => { if (e.target.classList.contains('remove-row-btn')) { appData.portfolio.splice(e.target.dataset.index, 1); runAllUpdates(); }}); document.getElementById('add-asset-row').addEventListener('click', () => { appData.portfolio.push({ class: 'US Equity', weight: 0, beta: 1, duration: 0 }); runAllUpdates(); }); document.getElementById('scenarios-form').addEventListener('input', e => { const { index, field } = e.target.dataset; const value = e.target.type === 'number' ? parseFloat(e.target.value) : e.target.value; appData.scenarios[index][field] = value; updateDashboard(); }); scenarioSelect.addEventListener('change', () => updateDetailedView(runStressTest())); // --- PDF GENERATION --- document.getElementById('download-pdf-btn').addEventListener('click', () => { const results = runStressTest(); const doc = new jsPDF(); let cursorY = 20; doc.setFontSize(22); doc.setFontStyle('bold'); doc.setTextColor('#0f766e'); doc.text('Portfolio Stress Test Report', 105, cursorY, { align: 'center' }); cursorY += 15; doc.setFontSize(16); doc.setTextColor('#111827'); doc.text('Overall Scenario Impact', 14, cursorY); cursorY += 8; doc.addImage(stressTestChart.toBase64Image('image/png', 1.0), 'PNG', 14, cursorY, 180, 90); cursorY += 100; doc.autoTable({ startY: cursorY, head: [['Scenario', 'P&L ($)', 'P&L (%)']], body: results.map(r => [r.name, `$${(r.totalImpact * BASE_PORTFOLIO_VALUE / 1000000).toFixed(2)}M`, `${(r.totalImpact * 100).toFixed(2)}%`]), theme: 'grid', headStyles: { fillColor: '#0d9488' } }); cursorY = doc.autoTable.previous.finalY + 15; doc.addPage(); cursorY = 20; doc.setFontSize(16); doc.text('Portfolio Composition', 14, cursorY); cursorY += 8; doc.autoTable({ startY: cursorY, head: [['Asset Class', 'Weight (%)', 'Beta', 'Duration']], body: appData.portfolio.map(a => [a.class, `${a.weight}%`, a.beta, a.duration]), theme: 'striped', headStyles: { fillColor: '#64748b' } }); doc.save('Portfolio-Stress-Test-Report.pdf'); }); // --- INITIALIZATION --- function runAllUpdates() { renderPortfolioTable(); renderScenariosForm(); updateDashboard(); } runAllUpdates(); setActiveTab('dashboard'); });
Scroll to Top