Stock Warrants & Rights Issue Analyzer
Understand the potential impact of stock warrants and rights issues on your holdings.
** IMPORTANT - PLEASE READ **
- This calculator is for educational and illustrative purposes ONLY.
- Calculations for warrants (intrinsic value, break-even) and rights issues (TERP, value of right) are theoretical. Actual market prices can vary significantly.
- This tool **DOES NOT provide financial or investment advice.** Decisions regarding exercising warrants or participating in rights issues should be made after careful consideration of official company documents, your own financial situation, risk tolerance, and consultation with a qualified financial advisor.
- Tax implications of these corporate actions are not covered and vary by jurisdiction.
Stock Warrant Analysis
$
$
$
Rights Issue Analysis
$
1-for-
existing shares
$
Invalid input. Please check values.
'; this.elements.rightsResultsDiv.style.display = 'block'; this.rightsResultsData={}; return; } const numRightsReceived = Math.floor(currentShares / ratioX); // Assuming 1 right per X shares held const numNewSharesEntitled = numRightsReceived; // Assuming 1 right = 1 new share const costToSubscribe = numNewSharesEntitled * subscriptionPrice; // TERP = [(Market Price * X) + (Subscription Price * 1)] / (X + 1) const terp = ((marketPrice * ratioX) + (subscriptionPrice * 1)) / (ratioX + 1); // Value of one right = (Market Price - Subscription Price) / (X + 1) OR Market Price - TERP const valueOfOneRight = (marketPrice - subscriptionPrice) / (ratioX + 1); // Alternative TERP: marketPrice - valueOfOneRight; // Should be same let newTotalShares = currentShares; let totalInvestmentAfterRights = currentShares * marketPrice; // Initial holding value let newAvgCostPerShare = marketPrice; if (numNewSharesEntitled > 0) { // If rights are exercised newTotalShares = currentShares + numNewSharesEntitled; totalInvestmentAfterRights = (currentShares * marketPrice) + costToSubscribe; // This is total value right after, assuming market price doesn't change yet for old shares. // Better: Total cost basis = (Old shares * Old Avg Cost) + CostToSubscribe. We don't have old avg cost. // So, let's use value for "Total Holding Value After Exercising (at TERP)" totalInvestmentAfterRights = newTotalShares * terp; // Theoretical value after exercise at TERP newAvgCostPerShare = totalInvestmentAfterRights / newTotalShares; // If we consider TERP // More direct avg cost: ((Original Avg Cost * Original Shares) + (New Shares * Sub Price)) / Total New Shares // Since we don't have original avg cost, we can't calculate new *cost basis* avg easily. // We'll show new holding value at TERP and new shares. } this.rightsResultsData = { inputs: { currentShares, marketPrice, ratioX, subscriptionPrice }, outputs: { numRightsReceived, numNewSharesEntitled, costToSubscribe, terp, valueOfOneRight, newTotalSharesIfExercised: newTotalShares, totalValueAtTerpIfExercised: totalInvestmentAfterRights } }; this.elements.rightsResultsDiv.innerHTML = `Rights Issue Theoretical Impact
Number of Rights Received: ${this.formatNumber(numRightsReceived, 0)}
New Shares You Can Subscribe To: ${this.formatNumber(numNewSharesEntitled, 0)}
Total Cost to Subscribe (All Rights): ${this.formatCurrency(costToSubscribe)}
Theoretical Ex-Rights Price (TERP): ${this.formatCurrency(terp)} per share
Theoretical Value of One Right: ${this.formatCurrency(valueOfOneRight)}
${numNewSharesEntitled > 0 ? `
If You Exercise All Your Rights:
New Total Shares Held: ${this.formatNumber(newTotalShares, 0)}
Total Holding Value (at TERP): ${this.formatCurrency(totalInvestmentAfterRights)}
Implied Avg. Price per Share (at TERP): ${this.formatCurrency(terp)}
` : ''}
`;
this.elements.rightsResultsDiv.style.display = 'block';
},
generatePDF: async function() { // Simplified for brevity
if (!window.jspdf || !window.html2canvas) {
alert('PDF generation library is not loaded.'); return;
}
// Determine which tab's data to use
let dataToExport = null;
let title = "";
let inputs, outputs;
if (this.activeTab === 'warrantsTab' && this.warrantResultsData && this.warrantResultsData.inputs) {
dataToExport = this.warrantResultsData;
title = "Stock Warrant Analysis Report";
inputs = dataToExport.inputs; outputs = dataToExport.outputs;
} else if (this.activeTab === 'rightsIssueTab' && this.rightsResultsData && this.rightsResultsData.inputs) {
dataToExport = this.rightsResultsData;
title = "Rights Issue Analysis Report";
inputs = dataToExport.inputs; outputs = dataToExport.outputs;
} else {
alert('Please calculate the impact on the active tab first to generate a PDF.'); return;
}
await new Promise(resolve => setTimeout(resolve, 50));
const pdfExportContainer = document.createElement('div');
pdfExportContainer.classList.add('wr-pdf-export-content');
pdfExportContainer.style.width = '800px';
let pdfHtml = `${title}
`; pdfHtml += `Reminder: Educational/illustrative ONLY. Not financial advice. Market values can vary. Consult company documents & financial advisor.
`;
pdfHtml += `Inputs Provided
`;
if (this.activeTab === 'warrantsTab') {
pdfHtml += `
`;
pdfHtml += `Current Stock Price: ${this.formatCurrency(inputs.stockPrice,false)}
`;
pdfHtml += `Warrant Exercise Price: ${this.formatCurrency(inputs.exercisePrice,false)}
`;
pdfHtml += `Shares per Warrant: ${this.formatNumber(inputs.sharesPerWarrant,2)}
`;
pdfHtml += `Number of Warrants Held: ${this.formatNumber(inputs.numWarrants,0)}
`;
pdfHtml += `Cost per Warrant (if purchased): ${this.formatCurrency(inputs.costPerWarrant,false)}
`;
} else { // Rights Issue
pdfHtml += `Current Shares Held: ${this.formatNumber(inputs.currentShares,0)}
`;
pdfHtml += `Current Market Price (Cum-Rights): ${this.formatCurrency(inputs.marketPrice,false)}
`;
pdfHtml += `Rights Ratio (1-for-X): 1-for-${inputs.ratioX}
`;
pdfHtml += `Subscription Price per New Share: ${this.formatCurrency(inputs.subscriptionPrice,false)}
`;
}
pdfHtml += `Calculated Impact
`;
if (this.activeTab === 'warrantsTab') {
pdfHtml += `
`;
pdfExportContainer.innerHTML = pdfHtml;
document.body.appendChild(pdfExportContainer);
try {
const canvas = await html2canvas(pdfExportContainer, { scale: 1.5, useCORS: true, logging: false, windowWidth: pdfExportContainer.scrollWidth });
document.body.removeChild(pdfExportContainer);
const imgData = canvas.toDataURL('image/png');
const { jsPDF } = window.jspdf;
const pdf = new jsPDF({ orientation: 'p', unit: 'pt', format: 'a4' });
const pdfWidth = pdf.internal.pageSize.getWidth();
const pdfHeight = pdf.internal.pageSize.getHeight();
const imgProps = pdf.getImageProperties(imgData);
let imgFinalWidth = pdfWidth - 40;
let imgFinalHeight = (imgProps.height * imgFinalWidth) / imgProps.width;
if (imgFinalHeight > pdfHeight - 40) {
imgFinalHeight = pdfHeight - 40;
imgFinalWidth = (imgProps.width * imgFinalHeight) / imgProps.height;
}
let position = 20; let heightProcessed = 0; const pageMargin = 20; const pageHeightAvailable = pdfHeight - 2 * pageMargin;
while(heightProcessed < canvas.height) {
let pageSegmentHeightOnCanvas = Math.min(canvas.height - heightProcessed, (pageHeightAvailable / imgFinalHeight) * canvas.height );
if (pageSegmentHeightOnCanvas <=0) break;
const segmentCanvas = document.createElement('canvas');
segmentCanvas.width = canvas.width; segmentCanvas.height = pageSegmentHeightOnCanvas;
const sctx = segmentCanvas.getContext('2d');
sctx.drawImage(canvas, 0, heightProcessed, canvas.width, pageSegmentHeightOnCanvas, 0, 0, canvas.width, pageSegmentHeightOnCanvas);
const segmentImgData = segmentCanvas.toDataURL('image/png');
const segmentImgPropsPdf = pdf.getImageProperties(segmentImgData);
let segmentRenderWidth = pdfWidth - 2 * pageMargin;
let segmentRenderHeight = (segmentImgPropsPdf.height * segmentRenderWidth) / segmentImgPropsPdf.width;
if(segmentRenderHeight > pageHeightAvailable) {
segmentRenderHeight = pageHeightAvailable;
segmentRenderWidth = (segmentImgPropsPdf.width * segmentRenderHeight) / segmentImgPropsPdf.height;
}
if(heightProcessed > 0) pdf.addPage();
pdf.addImage(segmentImgData, 'PNG', pageMargin, pageMargin, segmentRenderWidth, segmentRenderHeight);
heightProcessed += pageSegmentHeightOnCanvas;
}
pdf.save((this.activeTab === 'warrantsTab' ? 'Warrant_Analysis.pdf' : 'Rights_Issue_Analysis.pdf'));
} catch (error) {
console.error("Error generating PDF:", error);
alert("An error occurred while generating PDF.");
if (document.body.contains(pdfExportContainer)) document.body.removeChild(pdfExportContainer);
}
}
};
document.addEventListener('DOMContentLoaded', function() {
wrApp.init();
});
Intrinsic Value per Warrant: ${this.formatCurrency(outputs.intrinsicValuePerWarrant,false)}
`;
if(inputs.numWarrants > 0) pdfHtml += `Total Intrinsic Value: ${this.formatCurrency(outputs.totalIntrinsicValue,false)}
`;
if(inputs.numWarrants > 0) pdfHtml += `Total Cost to Exercise: ${this.formatCurrency(outputs.costToExerciseAll,false)}
`;
if(inputs.numWarrants > 0) pdfHtml += `Est. Profit/Loss if Exercised & Sold: ${this.formatCurrency(outputs.profitLossIfExercised,false)}
`;
pdfHtml += `Break-even Stock Price: ${this.formatCurrency(outputs.breakEvenStockPrice,false)}
`;
} else { // Rights Issue
pdfHtml += `Number of Rights Received: ${this.formatNumber(outputs.numRightsReceived,0)}
`;
pdfHtml += `New Shares Entitled To: ${this.formatNumber(outputs.numNewSharesEntitled,0)}
`;
pdfHtml += `Total Cost to Subscribe: ${this.formatCurrency(outputs.costToSubscribe,false)}
`;
pdfHtml += `Theoretical Ex-Rights Price (TERP): ${this.formatCurrency(outputs.terp,false)} /share
`;
pdfHtml += `Theoretical Value of One Right: ${this.formatCurrency(outputs.valueOfOneRight,false)}
`;
if(outputs.numNewSharesEntitled > 0) {
pdfHtml += `If You Exercise All Rights:
`; pdfHtml += `New Total Shares Held: ${this.formatNumber(outputs.newTotalSharesIfExercised,0)}
`;
pdfHtml += `Total Holding Value (at TERP): ${this.formatCurrency(outputs.totalValueAtTerpIfExercised,false)}
`;
}
}
pdfHtml += `