Home Loan Refinancing Budget Planner

Step 1: Enter Current Loan & Refinance Offer

Current Home Loan Details

Refinance Offer Details

Enter if different from remaining balance (e.g., cash-out).

Analysis Date

Defaults to current month/year (May 2025). This date is used to calculate remaining balance.

Step 2: Refinance Cost & Savings Analysis

Complete loan details in Tab 1 and click "Prepare Refinance Analysis" to see results here.

Step 3: Budget Impact, Amortization & Download

Budget Impact (Optional)

Enter your income and other debts to see how refinancing might affect your DTI ratio.

Amortization Schedule Previews

Current Loan (Remaining Term)
New Refinanced Loan

Refinancing results in lifetime savings, primarily due to factors other than monthly payment reduction (e.g., shorter term, significantly lower total interest despite higher payments).

`; } if (inputs.refiNewLoanAmountUser > 0 && inputs.refiNewLoanAmountUser !== currentLoan.remainingBalance) { let cashOutOrIn = inputs.refiNewLoanAmountUser - currentLoan.remainingBalance; analysisHTML += `

Note: New loan amount ($${inputs.effectiveNewLoanAmount.toFixed(2)}) differs from current remaining balance. This analysis primarily compares the cost of the old debt vs. an equivalent amount of new debt. ${cashOutOrIn > 0 ? `You are taking out an additional $${cashOutOrIn.toFixed(2)}.` : `You are bringing $${Math.abs(cashOutOrIn).toFixed(2)} to closing.` }

`; } container.innerHTML = analysisHTML; // Also update amortization previews on Tab 3 displayAmortizationTable(refiReportData.amortization.current, 'currentLoanAmortizationPreview', "Current Loan Amortization (Remaining)"); displayAmortizationTable(refiReportData.amortization.new, 'newLoanAmortizationPreview', "New Refinanced Loan Amortization"); } function calculateBudgetImpact() { const gmi = getRefiNum('budgetGrossMonthlyIncome'); const otherDebts = getRefiNum('budgetOtherMonthlyDebts'); const outputDiv = document.getElementById('budgetImpactOutput'); if (gmi <= 0 || !refiReportData.currentLoanCalcs.monthlyPI || !refiReportData.newLoanCalcs.monthlyPI) { outputDiv.innerHTML = "

Please enter Gross Monthly Income and ensure refinance analysis is complete to see budget impact.

"; return; } const currentHousingPITI = refiReportData.currentLoanCalcs.monthlyPI; // Simplified: Using P&I as main housing cost for this DTI. const newHousingPITI = refiReportData.newLoanCalcs.monthlyPI; // User should add taxes/insurance if comparing full PITI const currentFrontDTI = (currentHousingPITI / gmi) * 100; const currentBackDTI = ((currentHousingPITI + otherDebts) / gmi) * 100; const newFrontDTI = (newHousingPITI / gmi) * 100; const newBackDTI = ((newHousingPITI + otherDebts) / gmi) * 100; const cashFlowChange = refiReportData.comparison.monthlyPaymentDifference || 0; // P&I difference refiReportData.budgetImpact = { gmi, otherDebts, currentFrontDTI, currentBackDTI, newFrontDTI, newBackDTI, cashFlowChange }; outputDiv.innerHTML = `

Budget Impact Analysis:

Change in Monthly Cash Flow (P&I): $${Math.abs(cashFlowChange).toFixed(2)} ${cashFlowChange >= 0 ? 'Improved' : 'Reduced'}

Current Front-End DTI (Housing): ${currentFrontDTI.toFixed(1)}% | New Front-End DTI: ${newFrontDTI.toFixed(1)}%

Current Back-End DTI (Total): ${currentBackDTI.toFixed(1)}% | New Back-End DTI: ${newBackDTI.toFixed(1)}%

Note: DTI calculation here uses P&I for housing. For full PITI, add taxes & insurance to housing costs.`; } function displayAmortizationTable(schedule, containerId, title) { const container = document.getElementById(containerId); if (!schedule || schedule.length === 0) { container.innerHTML = `

${title}: No data to display.

`; return; } // Show first 5, ellipsis if more than 10, then last 5 let displaySchedule = schedule; if (schedule.length > 12) { displaySchedule = [ ...schedule.slice(0, 5), { month: '...', beginningBalance: '...', payment: '...', interest: '...', principal: '...', lumpSum: '...', endingBalance: '...' }, ...schedule.slice(-5) ]; } let tableHTML = ``; displaySchedule.forEach(row => { tableHTML += ``; }); tableHTML += `
MthStart Bal.PaymentInterestPrincipalLump SumEnd Bal.
${row.month} ${typeof row.beginningBalance === 'number' ? row.beginningBalance.toFixed(2) : row.beginningBalance} ${typeof row.payment === 'number' ? row.payment.toFixed(2) : row.payment} ${typeof row.interest === 'number' ? row.interest.toFixed(2) : row.interest} ${typeof row.principal === 'number' ? row.principal.toFixed(2) : row.principal} ${typeof row.lumpSum === 'number' ? row.lumpSum.toFixed(2) : row.lumpSum} ${typeof row.endingBalance === 'number' ? row.endingBalance.toFixed(2) : row.endingBalance}
Showing summarized schedule. Full schedule in PDF.`; container.innerHTML = `
${title}
${tableHTML}`; } function downloadRefiPdf() { if (!refiReportData.comparison || refiReportData.comparison.monthlyPaymentDifference === undefined) { alert("Please prepare and view the refinance analysis first."); return; } if (typeof window.jspdf === 'undefined' || typeof window.jspdf.jsPDF === 'undefined') { alert('PDF generation library (jsPDF) is not loaded.'); return; } const jsPDFConstructor = window.jspdf.jsPDF; const doc = new jsPDFConstructor(); if (typeof doc.autoTable !== 'function') { alert('jsPDF AutoTable plugin not loaded.'); return; } const { inputs, currentLoanCalcs, newLoanCalcs, comparison, budgetImpact, amortization } = refiReportData; const primaryColor = '#007bff', textColor = '#212529', tableHeaderColor = '#e9ecef'; let yPos = 22; const pageHeight = doc.internal.pageSize.height; const margin = 20; function checkYPdf(increment = 10) { if (yPos + increment > pageHeight - margin) { doc.addPage(); yPos = margin; } } doc.setFontSize(18); doc.setTextColor(primaryColor); doc.text("Home Loan Refinance Analysis", 14, yPos); yPos += 8; doc.setFontSize(10); doc.setTextColor(textColor); doc.text(`Report Date: ${new Date().toLocaleDateString()} | Analysis As Of: ${inputs.refiAsOfMonth}/${inputs.refiAsOfYear}`, 14, yPos); yPos += 10; // Current Loan Summary checkYPdf(30); doc.setFontSize(12); doc.setTextColor(primaryColor); doc.text("Current Loan Details", 14, yPos); yPos += 6; let currentLoanBody = [ ['Original Amount:', `$${inputs.currentOrigLoanAmount.toFixed(2)}`], ['Original Rate:', `${inputs.currentOrigInterestRate.toFixed(3)}%`], ['Original Term:', `${inputs.currentOrigLoanTerm} years`], ['Start Date:', `${inputs.currentLoanStartMonth}/${inputs.currentLoanStartYear}`], [{content:'Status as of ' + inputs.refiAsOfMonth+'/'+inputs.refiAsOfYear, styles:{fontStyle:'bold', halign:'left', cellWidth:'wrap'}}], [' Remaining Balance:', `$${currentLoanCalcs.remainingBalance.toFixed(2)}`], [' Monthly P&I:', `$${currentLoanCalcs.monthlyPI.toFixed(2)}`], [' Remaining Term:', `${Math.floor(currentLoanCalcs.remainingTermMonths/12)}y ${currentLoanCalcs.remainingTermMonths%12}m`] ]; doc.autoTable({startY: yPos, body: currentLoanBody, theme:'plain', styles:{fontSize:9, cellPadding:1.2}, columnStyles:{0:{fontStyle:'bold'}}}); yPos = doc.lastAutoTable.finalY + 7; // Refinance Offer Summary checkYPdf(30); doc.setFontSize(12); doc.setTextColor(primaryColor); doc.text("Refinance Offer Details", 14, yPos); yPos += 6; let refiOfferBody = [ ['New Loan Amount:', `$${inputs.effectiveNewLoanAmount.toFixed(2)}`], ['New Rate:', `${inputs.refiNewInterestRate.toFixed(3)}%`], ['New Term:', `${inputs.refiNewLoanTerm} years`], ['Est. Closing Costs:', `$${inputs.refiClosingCosts.toFixed(2)}`], ['New Monthly P&I:', `$${newLoanCalcs.monthlyPI.toFixed(2)}`] ]; doc.autoTable({startY: yPos, body: refiOfferBody, theme:'plain', styles:{fontSize:9, cellPadding:1.2}, columnStyles:{0:{fontStyle:'bold'}}}); yPos = doc.lastAutoTable.finalY + 10; // Comparative Analysis checkYPdf(40); doc.setFontSize(12); doc.setTextColor(primaryColor); doc.text("Refinance Comparison Summary", 14, yPos); yPos +=6; const comparisonBody = [ ['Monthly P&I Payment Difference:', `$${comparison.monthlyPaymentDifference.toFixed(2)} ${comparison.monthlyPaymentDifference >= 0 ? '(Savings)' : '(Increased Cost)'}`], ['Total Future Interest (Current Loan):', `$${comparison.totalRemainingInterestCurrent.toFixed(2)}`], ['Total Future Interest (New Loan):', `$${comparison.totalInterestNew.toFixed(2)}`], ['Interest Savings (New vs Current):', `$${(comparison.totalRemainingInterestCurrent - comparison.totalInterestNew).toFixed(2)}`], ['Net Lifetime Financial Impact:', `$${Math.abs(comparison.lifetimeSavings).toFixed(2)} ${comparison.lifetimeSavings >= 0 ? 'Total Savings' : 'Total Cost'}`], ['Break-Even Point for Closing Costs:', `${isFinite(comparison.breakEvenMonths) ? comparison.breakEvenMonths + ' months' : 'N/A (No monthly savings)'}`] ]; doc.autoTable({startY: yPos, body: comparisonBody, theme:'plain', styles:{fontSize:9, cellPadding:1.2}, columnStyles:{0:{fontStyle:'bold'}}}); yPos = doc.lastAutoTable.finalY + 7; // Budget Impact if(budgetImpact && budgetImpact.gmi > 0){ checkYPdf(30); doc.setFontSize(12); doc.setTextColor(primaryColor); doc.text("Budget Impact Analysis", 14, yPos); yPos +=6; const budgetBody = [ ['Gross Monthly Income:', `$${budgetImpact.gmi.toFixed(2)}`], ['Other Monthly Debts:', `$${budgetImpact.otherDebts.toFixed(2)}`], ['Change in Monthly Cash Flow (P&I):', `$${Math.abs(budgetImpact.cashFlowChange).toFixed(2)} ${budgetImpact.cashFlowChange >=0 ? 'Improved' : 'Reduced'}`], ['Current Front-End DTI:', `${budgetImpact.currentFrontDTI.toFixed(1)}% -> New: ${budgetImpact.newFrontDTI.toFixed(1)}%`], ['Current Back-End DTI:', `${budgetImpact.currentBackDTI.toFixed(1)}% -> New: ${budgetImpact.newBackDTI.toFixed(1)}%`] ]; doc.autoTable({startY: yPos, body: budgetBody, theme:'plain', styles:{fontSize:9, cellPadding:1.2}, columnStyles:{0:{fontStyle:'bold'}}}); yPos = doc.lastAutoTable.finalY + 10; } // Amortization Schedules function addAmortToPdf(title, scheduleData) { if (!scheduleData || scheduleData.length === 0) return; checkYPdf(20); doc.setFontSize(11); doc.setTextColor(primaryColor); doc.text(title, 14, yPos); yPos += 6; const head = [['Month', 'Start Bal.', 'Payment', 'Interest', 'Principal', 'Lump Sum', 'End Bal.']]; const body = scheduleData.map(r => [ r.month, r.beginningBalance.toFixed(2), r.payment.toFixed(2), r.interest.toFixed(2), r.principal.toFixed(2), r.lumpSum.toFixed(2), r.endingBalance.toFixed(2) ]); doc.autoTable({ startY: yPos, head: head, body: body, theme: 'grid', headStyles: {fillColor: tableHeaderColor, textColor:textColor, fontStyle:'bold', fontSize:8}, styles:{fontSize:7, cellPadding:1, halign:'right'}, columnStyles:{0:{halign:'center'}}, pageBreak: 'auto' // Let autotable handle page breaks for long tables }); yPos = doc.lastAutoTable.finalY + 10; } addAmortToPdf("Amortization: Current Loan (Remaining Term)", amortization.current); addAmortToPdf("Amortization: New Refinanced Loan", amortization.new); doc.save("Home_Loan_Refinance_Analysis.pdf"); } updateRefiNavButtons(); // Initial call
Scroll to Top