Financial Independence (FI) Tracker
Step 1: Your Financial Snapshot & FI Goals
Personal & Income
Assets & Liabilities
Stocks, bonds, retirement accounts, rental equity generating income, etc.
E.g., primary home equity if considered separately, valuable collectibles.
Student loans, credit cards, personal loans.
FI Goal & Investment Plan
In today's dollars. Defaults to current expenses.
After inflation (e.g., 5-7%).
Step 2: Years to Financial Independence Projection
This projection uses your current invested assets, annual savings, expected real return, and FI Number calculated in Tab 1.
Enter 0 if your annual savings amount will stay the same (in today's dollars).
Projection Summary (Sample Years):
Step 3: Your FI Progress Summary
Complete calculations on Tab 1 and Tab 2 to see your summary.
Progress to FI Number: 0%
0%
Key Factors for Your FI Journey:
- Savings Rate: The higher your savings rate, the faster you build investable assets.
- Investment Returns: Consistent, reasonable real returns significantly impact your growth over time.
- Managing Expenses: Keeping your desired retirement spending realistic affects your FI Number.
- Consistency: Regularly saving and investing is crucial.
- This tool provides estimates. Market conditions and personal circumstances can change. Review your plan periodically.
Progress to FI: ${progress.toFixed(1)}%
Estimated Years to FI: ${fiReportData.projection.yearsToFi === Infinity ? '>100 (Review Inputs)' : fiReportData.projection.yearsToFi + ' years'}
Estimated Age at FI: ${fiReportData.projection.ageAtFi === Infinity ? '>100+' : fiReportData.projection.ageAtFi + ' years old'}
Current Savings Rate: ${fiReportData.snapshot.savingsRate.toFixed(1)}%
`; const progressBar = document.getElementById('fiProgressBar'); progressBar.style.width = `${progress.toFixed(1)}%`; progressBar.textContent = `${progress.toFixed(1)}%`; document.getElementById('progressPercentageDisplay').textContent = progress.toFixed(1); document.getElementById('downloadFiPdfButton').disabled = false; } function downloadFiPdf() { if (!fiReportData.snapshot || !fiReportData.snapshot.fiNumber || !fiReportData.projection || fiReportData.projection.yearsToFi === undefined) { alert("Please complete all calculation steps 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, snapshot, projection } = fiReportData; const primaryColor = '#007bff', textColor = '#212529', tableHeaderColor = '#e9ecef'; let yPos = 22; const pageHeight = doc.internal.pageSize.height; const margin = 20; function checkY(increment = 10) { if (yPos + increment > pageHeight - margin) { doc.addPage(); yPos = margin; } } doc.setFontSize(18); doc.setTextColor(primaryColor); doc.text("Financial Independence Progress Report", 14, yPos); yPos += 8; doc.setFontSize(10); doc.setTextColor(textColor); doc.text(`Report Date: ${new Date().toLocaleDateString()}`, 14, yPos); yPos += 10; checkY(25); doc.setFontSize(12); doc.setTextColor(primaryColor); doc.text("Your Financial Profile", 14, yPos); yPos += 6; let profileBody = [ ['Current Age:', `${inputs.currentAge} years`], ['Annual Net Income:', `$${inputs.annualNetIncome.toFixed(2)}`], ['Annual Living Expenses:', `$${inputs.annualExpenses.toFixed(2)}`], ['Annual Savings:', `$${snapshot.annualSavings.toFixed(2)}`], ['Savings Rate:', `${snapshot.savingsRate.toFixed(1)}%`] ]; doc.autoTable({startY: yPos, body: profileBody, theme:'plain', styles:{fontSize:9}, columnStyles:{0:{fontStyle:'bold'}}}); yPos = doc.lastAutoTable.finalY + 7; checkY(30); doc.setFontSize(12); doc.setTextColor(primaryColor); doc.text("Net Worth Statement", 14, yPos); yPos += 6; let netWorthBody = [ ['Liquid Savings:', `$${inputs.liquidSavings.toFixed(2)}`], ['Invested Assets (for FI):', `$${inputs.investedAssets.toFixed(2)}`], ['Other Assets:', `$${inputs.otherAssets.toFixed(2)}`], [{content:'Total Assets:', styles:{fontStyle:'bold'}}, `$${snapshot.totalAssets.toFixed(2)}`], ['Total Debt:', `$${inputs.totalDebt.toFixed(2)}`], [{content:'Net Worth:', styles:{fontStyle:'bold', textColor:[0,100,0]}}, {content:`$${snapshot.netWorth.toFixed(2)}`, styles:{fontStyle:'bold', textColor:[0,100,0]}}] ]; doc.autoTable({startY: yPos, body: netWorthBody, theme:'plain', styles:{fontSize:9}, columnStyles:{0:{fontStyle:'bold'}}}); yPos = doc.lastAutoTable.finalY + 7; checkY(30); doc.setFontSize(12); doc.setTextColor(primaryColor); doc.text("Financial Independence Goal", 14, yPos); yPos += 6; let goalBody = [ ['Desired Annual Spending in Retirement:', `$${inputs.desiredRetirementSpending.toFixed(2)}`], ['Safe Withdrawal Rate (SWR):', `${inputs.swr.toFixed(1)}%`], [{content:'Your FI Number:', styles:{fontStyle:'bold'}}, {content:`$${snapshot.fiNumber.toFixed(2)}`, styles:{fontStyle:'bold'}}], ['Progress to FI (Invested Assets):', `${snapshot.progressToFi.toFixed(1)}%`] ]; doc.autoTable({startY: yPos, body: goalBody, theme:'plain', styles:{fontSize:9}, columnStyles:{0:{fontStyle:'bold'}}}); yPos = doc.lastAutoTable.finalY + 10; checkY(30 + (projection.fullTable.length > 0 ? 20 : 0) ); // More space if table exists doc.setFontSize(12); doc.setTextColor(primaryColor); doc.text("Projection to Financial Independence", 14, yPos); yPos += 6; let projectionSummaryBody = [ ['Current Invested Assets:', `$${inputs.investedAssets.toFixed(2)}`], ['Annual Savings (Year 1):', `$${snapshot.annualSavings.toFixed(2)}`], ['Annual Savings Increase Rate:', `${(getNumFi('annualSavingsIncreaseRate',0)).toFixed(1)}%`], ['Expected Real Return Rate:', `${inputs.realReturnRate.toFixed(1)}%`], [{content:'Estimated Years to FI:', styles:{fontStyle:'bold'}}, {content:`${projection.yearsToFi === Infinity ? '>100 years' : projection.yearsToFi + ' years'}`, styles:{fontStyle:'bold'}}], [{content:'Estimated Age at FI:', styles:{fontStyle:'bold'}}, {content:`${projection.ageAtFi === Infinity ? '>100+' : projection.ageAtFi + ' years old'}`, styles:{fontStyle:'bold'}}] ]; doc.autoTable({startY: yPos, body: projectionSummaryBody, theme:'plain', styles:{fontSize:9}, columnStyles:{0:{fontStyle:'bold'}}}); yPos = doc.lastAutoTable.finalY + 7; if (projection.fullTable && projection.fullTable.length > 0 && projection.yearsToFi !== Infinity) { checkY(10); doc.setFontSize(10); doc.setTextColor(textColor); doc.text("Year-by-Year Projection Details:", 14, yPos); yPos += 5; const tableHead = [['Year', 'Start Investments ($)', 'Savings Added ($)', 'Investment Growth ($)', 'End Investments ($)']]; const tableBody = projection.fullTable.map(row => [ row.year, row.startInvestments.toFixed(0), row.savingsAdded.toFixed(0), row.investmentGrowth.toFixed(0), row.endInvestments.toFixed(0) ]); doc.autoTable({ startY: yPos, head: tableHead, body: tableBody, theme: 'grid', headStyles: {fillColor: tableHeaderColor, textColor: textColor, fontStyle:'bold', fontSize:8}, styles: {fontSize:7.5, cellPadding:1.2, halign:'right'}, columnStyles: {0:{halign:'center'}} }); } else if (projection.yearsToFi === Infinity) { checkY(10); doc.setFontSize(9); doc.setTextColor(textColor); doc.text("Detailed year-by-year projection not shown as FI is estimated to take over 100 years with current inputs.", 14, yPos); yPos+=5; } doc.save("Financial_Independence_Report.pdf"); } // Initial calls updateFiNavButtons(); // Set default desired retirement spending on load document.getElementById('desiredRetirementSpending').value = document.getElementById('annualExpenses').value;