Structured Products Investment Analyzer
Product Performance Analysis
Summary of Input Parameters:
Payoff Profile at Maturity:
Illustrative Payoff Chart (Final Value vs. Underlying Performance)
Key Performance Metrics:
Please ensure all general parameters (Investment Amount, Initial Level, Term) are valid positive numbers.
"; paramsSummaryEl.innerHTML = ""; payoffChartEl.innerHTML = ""; keyMetricsEl.innerHTML = ""; downloadPdfBtn.style.display = 'none'; return; } const params = { invAmt: formCache.investmentAmount(), initialS: formCache.underlyingInitialLevel(), term: formCache.termYears(), protection: formCache.principalProtectionLevel(), partRate: formCache.participationRate(), underlyingCapPart: formCache.capOnUnderlyingForParticipation(), // 0 if no cap overallReturnCap: formCache.overallReturnCap(), // 0 if no cap hasBarrier: formCache.hasBarrier(), barrierLvl: formCache.barrierLevel(), hasCoupons: formCache.hasFixedCoupons(), couponRate: formCache.annualFixedCouponRate(), }; // Display input summary let summaryHTML = '- ';
summaryHTML += `
- Investment Amount: $${params.invAmt.toLocaleString()} `; summaryHTML += `
- Underlying Initial Level: ${params.initialS} `; summaryHTML += `
- Term: ${params.term} Years `; summaryHTML += `
- Principal Protection: ${params.protection*100}% `; summaryHTML += `
- Upside Participation Rate: ${params.partRate*100}% `; if(params.underlyingCapPart > 0) summaryHTML += `
- Cap on Underlying for Participation: ${params.underlyingCapPart*100}% `; if(params.overallReturnCap > 0) summaryHTML += `
- Overall Cap on Product Return (from Underlying): ${params.overallReturnCap*100}% `; if(params.hasBarrier) summaryHTML += `
- Barrier Level: ${params.barrierLvl*100}% of Initial `; if(params.hasCoupons) summaryHTML += `
- Annual Fixed Coupon Rate: ${params.couponRate*100}% `; summaryHTML += '
| Underlying Perf. at Maturity | Underlying Final Level | Product Return (%) | Final Value ($) |
|---|---|---|---|
| ${(underlyingPerf * 100).toFixed(0)}% | ${finalS.toFixed(2)} | ${(totalProductReturnPercentage * 100).toFixed(2)}% | $${finalValueWithCoupons.toLocaleString(undefined, {minimumFractionDigits: 2, maximumFractionDigits: 2})} |
Maximum Potential Gain (in scenarios shown): ${(maxGain * 100).toFixed(2)}%
Maximum Potential Loss (in scenarios shown): ${(maxLoss * 100).toFixed(2)}%
Approximate Break-Even Underlying Performance: ${breakEvenUnderlying}
`; // Basic Chart (Final Value) payoffChartEl.innerHTML = ''; // Clear previous chart const valuesForChart = results.map(r => r.finalValue); const minVal = Math.min(...valuesForChart, 0); // include 0 in min for scale const maxVal = Math.max(...valuesForChart); const range = maxVal - minVal; results.forEach(r => { const bar = document.createElement('div'); bar.className = 'spia-chart-bar'; let barHeight = 0; if (range > 0) { barHeight = ((r.finalValue - minVal) / range) * 100; // Percentage of max height (200px defined in CSS) } else if (r.finalValue > 0) { // All values are same and positive barHeight = 50; // arbitrary height } bar.style.height = `${Math.max(5, barHeight)}%`; // Min height of 5% for visibility bar.title = `Underlying: ${(r.underlyingPerf*100).toFixed(0)}%, Final Val: $${r.finalValue.toLocaleString()}`; const label = document.createElement('span'); label.className = 'spia-chart-bar-label'; label.textContent = `${(r.underlyingPerf*100).toFixed(0)}%`; bar.appendChild(label); payoffChartEl.appendChild(bar); }); downloadPdfBtn.style.display = 'block'; } // PDF Download downloadPdfBtn?.addEventListener('click', function () { const { jsPDF } = window.jspdf; const pdfOutputArea = document.getElementById('spiaPdfOutputArea'); if (!pdfOutputArea) { alert('PDF output area not found.'); return; } if (payoffTableContainerEl.innerHTML.includes("Please ensure all general parameters")) { alert('Please input valid parameters and analyze before downloading PDF.'); return; } html2canvas(pdfOutputArea, { scale: 2, useCORS: true, backgroundColor: '#ffffff' }) .then(canvas => { const imgData = canvas.toDataURL('image/png'); 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) { // Check if it fits with margin imgHeight = pdfHeight - 2 * margin; imgWidth = imgHeight * ratio; } pdf.addImage(imgData, 'PNG', margin, margin, imgWidth, imgHeight); pdf.save('StructuredProduct_Analysis.pdf'); }) .catch(err => { console.error("Error generating PDF:", err); alert("Error generating PDF. See console for details."); }); }); // Initial setup document.getElementById('hasBarrier').dispatchEvent(new Event('change')); document.getElementById('hasFixedCoupons').dispatchEvent(new Event('change')); switchTab('paramsTab'); // Start on the first tab });