The future spot rate ($${expectedFutureSpotRate.toFixed(4)}) is higher than your option's strike price ($${optionStrike.toFixed(4)}). It's beneficial to exercise the option.
`;
} else {
// Let the option expire, buy at the better spot rate
transactionCost = hedgedAmount * expectedFutureSpotRate;
explanation = `
Strategy: Currency Option (Payable)
The future spot rate ($${expectedFutureSpotRate.toFixed(4)}) is lower than your option's strike price ($${optionStrike.toFixed(4)}). You let the option expire worthless and buy currency at the more favorable spot rate.
`;
}
} else { // Receivable - Selling foreign currency (Put Option logic)
if (expectedFutureSpotRate < optionStrike) {
// It's better to exercise the option to sell at the higher strike price
transactionCost = hedgedAmount * optionStrike;
explanation = `
Strategy: Currency Option (Receivable)
The future spot rate ($${expectedFutureSpotRate.toFixed(4)}) is lower than your option's strike price ($${optionStrike.toFixed(4)}). It's beneficial to exercise the option to sell at the higher strike price.
`;
} else {
// Let the option expire, sell at the better spot rate
transactionCost = hedgedAmount * expectedFutureSpotRate;
explanation = `
Strategy: Currency Option (Receivable)
The future spot rate ($${expectedFutureSpotRate.toFixed(4)}) is higher than your option's strike price ($${optionStrike.toFixed(4)}). You let the option expire worthless and sell currency at the more favorable spot rate.
`;
}
}
hedgedPortionCost = transactionCost + (exposureType === 'payable' ? premiumCost : -premiumCost);
explanation += `
- Cost of transaction for hedged portion: ${formatAsUSD(transactionCost)}.
- Cost of premium: ${formatCurrency(hedgedAmount, currency)} * $${optionPremium.toFixed(4)} = ${formatAsUSD(premiumCost)}. This is an upfront cost for payables and reduces revenue for receivables.
- Net cost of hedged portion: ${formatAsUSD(hedgedPortionCost)}.
- Cost of unhedged portion: ${formatCurrency(unhedgedAmount, currency)} * $${expectedFutureSpotRate.toFixed(4)} = ${formatAsUSD(unhedgedPortionCost)}.
`;
}
hedgedCostTotal = hedgedPortionCost + unhedgedPortionCost;
effectiveRate = hedgedCostTotal / exposureAmount;
// 3. Strategy P/L
let pnl = unhedgedCostTotal - hedgedCostTotal;
if(exposureType === 'receivable'){
// For receivables, a higher USD amount is better.
pnl = hedgedCostTotal - unhedgedCostTotal;
}
// Display results
const resultsSection = document.getElementById('results-section');
if (resultsSection) resultsSection.style.display = 'block';
const unhedgedCostEl = document.getElementById('unhedged-cost');
if (unhedgedCostEl) unhedgedCostEl.textContent = formatAsUSD(unhedgedCostTotal);
const hedgedCostEl = document.getElementById('hedged-cost');
if (hedgedCostEl) hedgedCostEl.textContent = formatAsUSD(hedgedCostTotal);
const effectiveRateEl = document.getElementById('effective-rate');
if (effectiveRateEl) effectiveRateEl.textContent = `$${effectiveRate.toFixed(4)}`;
const pnlEl = document.getElementById('strategy-pnl');
if (pnlEl) {
pnlEl.textContent = `${formatAsUSD(Math.abs(pnl))}`;
pnlEl.className = pnl >= 0 ? 'gain' : 'loss';
pnlEl.textContent += pnl >= 0 ? ' Gain' : ' Loss';
}
const explanationEl = document.getElementById('explanation-section');
if(explanationEl) explanationEl.innerHTML = explanation;
// Navigate to results tab
navigateToTab('results-tab');
}
function formatAsUSD(amount) {
return new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(amount);
}
function formatCurrency(amount, currencyCode) {
return new Intl.NumberFormat('en-US', { style: 'currency', currency: currencyCode, minimumFractionDigits: 2, maximumFractionDigits: 2 }).format(amount).replace(currencyCode, "").trim() + ` ${currencyCode}`;
}
function generatePdf() {
const { jsPDF } = window.jspdf;
const content = document.getElementById('pdf-content');
if (!content) {
console.error('PDF content area not found.');
return;
}
const pdfButton = document.getElementById('pdf-download-button');
if (pdfButton) pdfButton.style.display = 'none';
html2canvas(content, {
scale: 2,
backgroundColor: '#ffffff',
useCORS: true
}).then(canvas => {
if (pdfButton) pdfButton.style.display = 'block';
const imgData = canvas.toDataURL('image/png');
const pdf = new jsPDF({
orientation: 'p',
unit: 'mm',
format: 'a4'
});
const pdfWidth = pdf.internal.pageSize.getWidth();
const pdfHeight = pdf.internal.pageSize.getHeight();
const canvasWidth = canvas.width;
const canvasHeight = canvas.height;
const ratio = canvasWidth / canvasHeight;
let imgWidth = pdfWidth - 20;
let imgHeight = imgWidth / ratio;
if (imgHeight > pdfHeight - 20) {
imgHeight = pdfHeight - 20;
imgWidth = imgHeight * ratio;
}
const x = (pdfWidth - imgWidth) / 2;
const y = 10;
pdf.addImage(imgData, 'PNG', x, y, imgWidth, imgHeight);
pdf.save('Hedging_Simulation_Results.pdf');
}).catch(err => {
console.error('Error generating PDF:', err);
if (pdfButton) pdfButton.style.display = 'block';
});
}