Private Market Liquidity Assessment Tool

Private Market Liquidity Assessment Tool

Input Investment Details

Assess Liquidity Factors

Liquidity Assessment Results

Please input details on previous tabs to see results.

${message}

`; document.body.appendChild(overlay); overlay.querySelector('.modal-ok-btn').onclick = () => overlay.remove(); } /** * Custom confirmation box function. * @param {string} message - The message to display. * @param {Function} onConfirm - Callback function if confirmed. */ function showCustomConfirmBox(message, onConfirm) { const overlay = document.createElement('div'); overlay.classList.add('custom-modal-overlay'); overlay.innerHTML = `

${message}

`; document.body.appendChild(overlay); overlay.querySelector('.modal-yes-btn').onclick = () => { onConfirm(); overlay.remove(); }; overlay.querySelector('.modal-no-btn').onclick = () => { overlay.remove(); }; } // --- Tab Navigation Logic --- /** * Shows the specified tab and hides others. Updates active tab buttons. * @param {number} tabIndex - The index of the tab to show. */ function showTab(tabIndex) { if (tabIndex < 0 || tabIndex >= tabContents.length) { console.error("Invalid tab index:", tabIndex); return; } tabContents.forEach(content => content.classList.remove('active')); tabButtons.forEach(button => button.classList.remove('active')); tabContents[tabIndex].classList.add('active'); tabButtons[tabIndex].classList.add('active'); currentTab = tabIndex; prevTabBtn.disabled = (currentTab === 0); nextTabBtn.disabled = (currentTab === tabContents.length - 1); // Re-render results if on the assessment tab if (currentTab === 2) { renderAssessmentResults(); } } /** * Navigates to the next or previous tab. * @param {number} direction - -1 for previous, 1 for next. */ window.navigateTab = function(direction) { const newTab = currentTab + direction; showTab(newTab); } // Add event listeners for tab buttons tabButtons.forEach((button, index) => { button.addEventListener('click', function() { showTab(index); }); }); // --- Investment Details Processing --- /** * Captures investment details and moves to the next tab. */ window.processInvestmentDetails = function() { const investmentName = document.getElementById('investmentName').value.trim(); const assetClass = document.getElementById('assetClass').value; const investmentAmount = parseFloat(document.getElementById('investmentAmount').value); const investmentDateStr = document.getElementById('investmentDate').value; const expectedHoldingPeriod = parseInt(document.getElementById('expectedHoldingPeriod').value); const targetIRR = parseFloat(document.getElementById('targetIRR').value); const notes = document.getElementById('notes').value.trim(); // Basic validation if (!investmentName) { showCustomMessageBox('Please enter an Investment Name.'); return; } if (isNaN(investmentAmount) || investmentAmount <= 0) { showCustomMessageBox('Please enter a valid Investment Amount.'); return; } if (!investmentDateStr) { showCustomMessageBox('Please enter an Investment Date.'); return; } if (isNaN(expectedHoldingPeriod) || expectedHoldingPeriod <= 0) { showCustomMessageBox('Please enter a valid Expected Holding Period in years.'); return; } if (isNaN(targetIRR) || targetIRR < 0) { showCustomMessageBox('Please enter a valid Target IRR (0% or more).'); return; } liquidityAssessmentData.investment = { name: investmentName, assetClass: assetClass, amount: investmentAmount, date: new Date(investmentDateStr + 'T00:00:00'), holdingPeriod: expectedHoldingPeriod, targetIRR: targetIRR, notes: notes }; showTab(1); // Move to Liquidity Factors tab } // --- Liquidity Factors Assessment --- /** * Captures liquidity factors and moves to the assessment results tab. */ window.assessLiquidityFactors = function() { const marketConditions = document.getElementById('marketConditions').value; const secondaryMarketActivity = document.getElementById('secondaryMarketActivity').value; const investorDemand = document.getElementById('investorDemand').value; const exitStrategy = document.getElementById('exitStrategy').value; const dealComplexity = document.getElementById('dealComplexity').value; const regulatoryEnvironment = document.getElementById('regulatoryEnvironment').value; liquidityAssessmentData.factors = { marketConditions: marketConditions, secondaryMarketActivity: secondaryMarketActivity, investorDemand: investorDemand, exitStrategy: exitStrategy, dealComplexity: dealComplexity, regulatoryEnvironment: regulatoryEnvironment }; showTab(2); // Move to Assessment Results tab } // --- Assessment Results Calculation & Display --- /** * Calculates and renders the liquidity assessment results. * This is a simplified illustrative model. */ function renderAssessmentResults() { if (!liquidityAssessmentData.investment || !liquidityAssessmentData.factors) { liquidityResultsDisplay.innerHTML = '

Please complete "Investment Details" and "Liquidity Factors" tabs first.

'; return; } const inv = liquidityAssessmentData.investment; const fac = liquidityAssessmentData.factors; let estimatedTimeToLiquidity = inv.holdingPeriod; // Base time in years let potentialLiquidityDiscount = 0; // Base discount % let liquidityRiskScore = 'Medium'; // Default // Adjust Time to Liquidity based on factors if (fac.marketConditions === 'Bear') estimatedTimeToLiquidity += 2; if (fac.marketConditions === 'Bull') estimatedTimeToLiquidity = Math.max(1, estimatedTimeToLiquidity - 1); if (fac.secondaryMarketActivity === 'Low' || fac.secondaryMarketActivity === 'Non-existent') estimatedTimeToLiquidity += 3; if (fac.secondaryMarketActivity === 'High') estimatedTimeToLiquidity = Math.max(1, estimatedTimeToLiquidity - 0.5); if (fac.exitStrategy === 'Liquidation') estimatedTimeToLiquidity -= 1; // Faster but at a cost if (fac.exitStrategy === 'IPO') estimatedTimeToLiquidity += 2; // Longer process // Adjust Liquidity Discount based on factors switch (inv.assetClass) { case 'Private Equity': potentialLiquidityDiscount += 15; break; case 'Private Credit': potentialLiquidityDiscount += 10; break; case 'Real Estate': potentialLiquidityDiscount += 12; break; case 'Infrastructure': potentialLiquidityDiscount += 8; break; case 'Venture Capital': potentialLiquidityDiscount += 25; break; case 'Other': potentialLiquidityDiscount += 18; break; } if (fac.marketConditions === 'Bear') potentialLiquidityDiscount += 10; if (fac.marketConditions === 'Volatile') potentialLiquidityDiscount += 5; if (fac.marketConditions === 'Bull') potentialLiquidityDiscount = Math.max(0, potentialLiquidityDiscount - 5); if (fac.secondaryMarketActivity === 'Low' || fac.secondaryMarketActivity === 'Non-existent') potentialLiquidityDiscount += 15; if (fac.investorDemand === 'Low') potentialLiquidityDiscount += 7; if (fac.dealComplexity === 'High') potentialLiquidityDiscount += 5; if (fac.regulatoryEnvironment === 'Restrictive') potentialLiquidityDiscount += 3; // Determine Liquidity Risk Score if (estimatedTimeToLiquidity > 7 || potentialLiquidityDiscount > 20) { liquidityRiskScore = 'High'; } else if (estimatedTimeToLiquidity > 4 || potentialLiquidityDiscount > 10) { liquidityRiskScore = 'Medium'; } else { liquidityRiskScore = 'Low'; } // Store calculated results liquidityAssessmentData.results = { estimatedTimeToLiquidity: estimatedTimeToLiquidity.toFixed(1), // Years potentialLiquidityDiscount: potentialLiquidityDiscount.toFixed(2), // Percentage liquidityRiskScore: liquidityRiskScore }; let html = `

Based on your inputs, here is the preliminary liquidity assessment:

Investment Name: ${inv.name}
Asset Class: ${inv.assetClass}
Investment Amount: ${formatCurrency(inv.amount)}
Estimated Time to Liquidity: ${liquidityAssessmentData.results.estimatedTimeToLiquidity} Years
Potential Liquidity Discount: ${formatPercentage(liquidityAssessmentData.results.potentialLiquidityDiscount)}
Liquidity Risk Score: ${liquidityAssessmentData.results.liquidityRiskScore}
${inv.notes ? `
Notes: ${inv.notes}
` : ''} `; liquidityResultsDisplay.innerHTML = html; } // --- PDF Generation Logic --- /** * Generates a PDF report of the liquidity assessment. */ window.generatePDF = async function() { if (!liquidityAssessmentData.investment || !liquidityAssessmentData.factors || !liquidityAssessmentData.results) { showCustomMessageBox('Please complete all sections of the tool before generating the PDF report.'); return; } pdfContentContainer.innerHTML = ''; // Clear previous content const inv = liquidityAssessmentData.investment; const fac = liquidityAssessmentData.factors; const res = liquidityAssessmentData.results; let pdfHtml = `

Private Market Liquidity Report

Investment Details

Investment Name:${inv.name}
Asset Class:${inv.assetClass}
Investment Amount:${formatCurrency(inv.amount)}
Investment Date:${formatDate(inv.date)}
Expected Holding Period:${inv.holdingPeriod} Years
Target IRR:${formatPercentage(inv.targetIRR)}
${inv.notes ? `
Notes:${inv.notes}
` : ''}

Liquidity Factors

Current Market Conditions:${fac.marketConditions}
Secondary Market Activity:${fac.secondaryMarketActivity}
General Investor Demand:${fac.investorDemand}
Primary Exit Strategy:${fac.exitStrategy}
Deal Complexity / Covenants:${fac.dealComplexity}
Regulatory Environment:${fac.regulatoryEnvironment}

Liquidity Assessment Results

Estimated Time to Liquidity:${res.estimatedTimeToLiquidity} Years
Potential Liquidity Discount:${formatPercentage(res.potentialLiquidityDiscount)}
Liquidity Risk Score:${res.liquidityRiskScore}
`; pdfContentContainer.innerHTML = pdfHtml; // Temporarily make the container visible (but off-screen) for html2canvas pdfContentContainer.style.display = 'block'; const canvas = await html2canvas(pdfContentContainer, { scale: 2, logging: false, useCORS: true, // Fix: Ensure background is rendered correctly backgroundColor: '#ffffff' }); // Hide the container again immediately pdfContentContainer.style.display = 'none'; const imgData = canvas.toDataURL('image/png'); const { jsPDF } = window.jspdf; const doc = new jsPDF('p', 'mm', 'a4'); const imgWidth = 210; const pageHeight = 297; const imgHeight = canvas.height * imgWidth / canvas.width; let heightLeft = imgHeight; let position = 0; doc.addImage(imgData, 'PNG', 0, position, imgWidth, imgHeight); heightLeft -= pageHeight; while (heightLeft > 0) { position = -heightLeft; // Adjust position for new page doc.addPage(); doc.addImage(imgData, 'PNG', 0, position, imgWidth, imgHeight); heightLeft -= pageHeight; } doc.save('Private_Market_Liquidity_Report.pdf'); pdfContentContainer.innerHTML = ''; // Clean up after download } // --- Initial Setup --- showTab(0); // Show the first tab on load });
Scroll to Top