Peer-to-Peer Lending Investment Budget Tool
Budget & Goals Setup
Platform Allocation
Add New P2P Platform
Your Platform Allocations
No platforms added yet.
Total P2P Capital: $0.00
Total Allocated: $0.00
Record Investment/Disbursement
Disbursement Log for Selected Platform:
- No disbursements recorded or no platform selected.
Total Disbursed on this Platform: $0.00
Performance & Projections
Overall Investment Summary
Total P2P Investment Capital: N/A
Total Capital Allocated to Platforms: N/A
Total Capital Actually Disbursed: N/A
Projected Earnings (Based on Disbursed Amounts & Expected Rates)
Weighted Average Expected Annual Rate: N/A %
Projected Gross Annual Earnings: $N/A
Platform Allocation & Disbursement Overview
No platforms allocated or disbursements made yet.
Expected Rate: ${p.expectedRate.toFixed(1)}%
${p.risk ? `Risk Level: ${p.risk}
` : ''} `; p2pPlatformsListContainer.appendChild(div); }); } updateAllocationSummary(); populateP2PPlatformSelects(); renderP2PProjectionsTab(); } function updateAllocationSummary() { if (!p2pDisplayTotalCapital || !p2pDisplayTotalAllocated || !p2pAllocationStatusDiv) return; p2pDisplayTotalCapital.textContent = p2pData.totalCapital.toFixed(2); const totalAllocated = p2pData.platforms.reduce((sum, p) => sum + p.allocation, 0); p2pDisplayTotalAllocated.textContent = totalAllocated.toFixed(2); if (p2pData.totalCapital === 0 && totalAllocated === 0) { p2pAllocationStatusDiv.textContent = 'Status: Please set total capital and add platforms.'; p2pAllocationStatusDiv.className = 'allocation-status'; } else if (totalAllocated > p2pData.totalCapital) { p2pAllocationStatusDiv.textContent = `Status: Over-allocated by $${(totalAllocated - p2pData.totalCapital).toFixed(2)}`; p2pAllocationStatusDiv.className = 'allocation-status status-error'; } else if (totalAllocated < p2pData.totalCapital) { p2pAllocationStatusDiv.textContent = `Status: Under-allocated by $${(p2pData.totalCapital - totalAllocated).toFixed(2)}`; p2pAllocationStatusDiv.className = 'allocation-status status-warn'; } else { p2pAllocationStatusDiv.textContent = 'Status: Fully allocated!'; p2pAllocationStatusDiv.className = 'allocation-status status-good'; } } if (p2pAddPlatformBtn) p2pAddPlatformBtn.addEventListener('click', () => { const name = p2pPlatformNameInput.value.trim(); const allocation = parseFloat(p2pPlatformAllocationInput.value) || 0; const expectedRate = parseFloat(p2pPlatformExpectedRateInput.value) || 0; const risk = p2pPlatformRiskSelect.value; if (!name || allocation <= 0 || expectedRate <= 0) { alert('Please enter valid platform name, allocation amount, and expected rate.'); return; } p2pData.platforms.push({ id: `p2pp-${p2pNextId.platform++}`, name, allocation, expectedRate, risk, disbursements: [] }); renderP2PPlatforms(); p2pPlatformNameInput.value = ''; p2pPlatformAllocationInput.value = ''; p2pPlatformExpectedRateInput.value = ''; p2pPlatformRiskSelect.value = ''; }); if (p2pPlatformsListContainer) p2pPlatformsListContainer.addEventListener('click', function(e) { if (e.target.classList.contains('remove-btn')) { const idToRemove = e.target.dataset.id; p2pData.platforms = p2pData.platforms.filter(p => p.id !== idToRemove); renderP2PPlatforms(); } }); // --- Record Disbursement (Tab 3) --- function populateP2PPlatformSelects() { if (!p2pPlatformSelectForDisbursement) return; const currentVal = p2pPlatformSelectForDisbursement.value; p2pPlatformSelectForDisbursement.innerHTML = ''; p2pData.platforms.forEach(p => { const option = document.createElement('option'); option.value = p.id; option.textContent = `${p.name} (Allocated: $${p.allocation.toFixed(2)})`; p2pPlatformSelectForDisbursement.appendChild(option); }); if (p2pData.platforms.find(p => p.id === currentVal)) { p2pPlatformSelectForDisbursement.value = currentVal; } else { p2pPlatformSelectForDisbursement.value = ""; // Reset if previously selected platform is gone } renderP2PDisbursementsLog(p2pPlatformSelectForDisbursement.value); // Update log based on selection } function renderP2PDisbursementsLog(platformId) { if (!p2pDisbursementsList || !p2pSelectedPlatformNameLog || !p2pTotalDisbursedOnPlatform) return; const platform = p2pData.platforms.find(p => p.id === platformId); p2pSelectedPlatformNameLog.textContent = platform ? platform.name : "Selected Platform"; p2pDisbursementsList.innerHTML = ''; let totalDisbursedThisPlatform = 0; if (platform && platform.disbursements && platform.disbursements.length > 0) { platform.disbursements.slice().reverse().forEach(d => { // Newest first totalDisbursedThisPlatform += d.amount; const li = document.createElement('li'); li.textContent = `Date: ${d.date}, Amount: $${d.amount.toFixed(2)}`; p2pDisbursementsList.appendChild(li); }); } else { p2pDisbursementsList.innerHTML = 'No platforms allocated yet.
'; } p2pData.platforms.forEach(p => { const platformDisbursedAmount = p.disbursements.reduce((sum, d) => sum + d.amount, 0); totalActuallyDisbursed += platformDisbursedAmount; weightedRateNumerator += platformDisbursedAmount * p.expectedRate; const platformSummaryDiv = document.createElement('div'); platformSummaryDiv.className = 'dynamic-list-item'; // Re-use styling platformSummaryDiv.innerHTML = `${p.name}
Target Allocation: $${p.allocation.toFixed(2)}
Actually Disbursed: $${platformDisbursedAmount.toFixed(2)}
Expected Rate: ${p.expectedRate.toFixed(1)}%
`; p2pPlatformSummaryContainer.appendChild(platformSummaryDiv); }); p2pProjTotalDisbursed.textContent = `$${totalActuallyDisbursed.toFixed(2)}`; if (totalActuallyDisbursed > 0) { const weightedAvgRate = weightedRateNumerator / totalActuallyDisbursed; p2pProjWeightedAvgRate.textContent = `${weightedAvgRate.toFixed(2)}`; p2pProjAnnualEarnings.textContent = `${(totalActuallyDisbursed * (weightedAvgRate / 100)).toFixed(2)}`; } else { p2pProjWeightedAvgRate.textContent = '0.00'; p2pProjAnnualEarnings.textContent = '0.00'; } } // --- PDF Download --- if (p2pDownloadPdfBtn) p2pDownloadPdfBtn.addEventListener('click', () => { const pdfPrintEl = document.getElementById('p2pPdfPrintArea'); if (!pdfPrintEl) return; let pdfHtml = `Peer-to-Peer Lending Investment Plan
`; if (p2pData.userName) pdfHtml += `Prepared for: ${p2pData.userName}
`; pdfHtml += `Report Date: ${new Date().toLocaleDateString()}
`; pdfHtml += `Investment Goals
`; pdfHtml += `Total P2P Investment Capital: $${p2pData.totalCapital.toFixed(2)}
`; pdfHtml += `Desired Overall Annual Return: ${p2pData.desiredReturn.toFixed(1)}%
`; pdfHtml += `Investment Horizon: ${p2pData.horizon || 'N/A'}
`; if(p2pData.riskTolerance) pdfHtml += `Overall Risk Tolerance: ${p2pData.riskTolerance}
`; pdfHtml += `Platform Allocation Plan
`; if (p2pData.platforms.length > 0) { pdfHtml += `| Platform Name | Allocated ($) | Expected Rate (%) | % of Total Capital | Risk Level |
|---|---|---|---|---|
| ${p.name} | ${p.allocation.toFixed(2)} | ${p.expectedRate.toFixed(1)} | ${percentOfCapital}% | ${p.risk || 'N/A'} |
No platforms allocated.
`; } const totalDisbursedAllPlatforms = p2pData.platforms.reduce((sum, plat) => sum + plat.disbursements.reduce((dSum, disb) => dSum + disb.amount, 0), 0); pdfHtml += `Disbursement & Projections Summary
`; pdfHtml += `Total Amount Disbursed: $${totalDisbursedAllPlatforms.toFixed(2)}
`; let weightedRateNumerator = 0; p2pData.platforms.forEach(p => { const platformDisbursed = p.disbursements.reduce((s,d) => s + d.amount, 0); weightedRateNumerator += platformDisbursed * p.expectedRate; }); const weightedAvgRate = totalDisbursedAllPlatforms > 0 ? (weightedRateNumerator / totalDisbursedAllPlatforms) : 0; pdfHtml += `Weighted Average Expected Rate (on disbursed): ${weightedAvgRate.toFixed(2)}%
`; pdfHtml += `Projected Gross Annual Earnings: $${(totalDisbursedAllPlatforms * (weightedAvgRate / 100)).toFixed(2)}
`; pdfPrintEl.innerHTML = pdfHtml; window.print(); pdfPrintEl.innerHTML = ''; // Clear after }); // --- Initialization --- function setDefaultP2PDates() { const today = new Date().toISOString().split('T')[0]; if (p2pDisbursementDateInput) p2pDisbursementDateInput.value = today; } updateP2PTabDisplay(); setDefaultP2PDates(); renderP2PPlatforms(); // Includes updating allocation summary and populating selects renderP2PProjectionsTab(); // Initial render of projections });