Real Estate Calculator

Calculate mortgage payments, home affordability, and real estate investment returns with our free calculator.

Mortgage Loan Details

$
$
%
%
$
$
$
$

Monthly Payment Breakdown

Based on your inputted interest rate of 6.700%

$3,121/mo
Principal & Interest $2,774.70
Property Tax $280.00
Homeowners Insurance $66.00
PMI $0.00
HOA Fees $0.00
Total Monthly Payment $3,120.70

Amortization for Mortgage Loan

Amortization is paying off debt over time in equal installments. A larger share of your payment goes toward principal as the loan progresses.

Based on your inputted interest rate of 6.700%

Loan Amount
$430,000
Total Interest Paid
$568,891
Total Cost of Loan
$998,891
Payoff Date
May 2055

Loan Balance Over Time

Loan Balance
Principal Paid
Interest Paid

Extra Payments?

$
$
$

Amortization Schedule Breakdown

This table shows principal and interest for each payment.

First payment: | Last payment:
| |
`); printWindow.document.close(); printWindow.print(); });exportCsvBtn.addEventListener('click', () => { const rows = [["Year", "Month", "Principal", "Interest", "Remaining Balance"]]; amortizationTableBody.querySelectorAll('details').forEach(detail => { const year = detail.querySelector('summary .summary-year').textContent; detail.querySelectorAll('.monthly-table tbody tr').forEach(row => { const cells = Array.from(row.querySelectorAll('td')).map(td => { const text = td.textContent.replace(/[^0-9A-Za-z\s.]/g, ''); return `"${text.replace(/"/g, '""')}"`; }); rows.push([year, ...cells]); }); }); const csvContent = "data:text/csv;charset=utf-8," + rows.map(e => e.join(",")).join("\n"); const link = document.createElement("a"); link.setAttribute("href", encodeURI(csvContent)); link.setAttribute("download", "amortization_schedule.csv"); document.body.appendChild(link); link.click(); document.body.removeChild(link); });// --- CORE LOGIC --- function updateMonthlyInputs() { taxMonthlyInput.value = formatInput(parseCurrency(propertyTaxInput.value)); insMonthlyInput.value = formatInput(parseCurrency(homeInsuranceInput.value)); pmiMonthlyInput.value = formatInput(parseCurrency(pmiInput.value)); hoaMonthlyInput.value = formatInput(parseCurrency(hoaInput.value)); taxMonthlyDisplay.textContent = formatCurrency(parseCurrency(taxMonthlyInput.value)); insMonthlyDisplay.textContent = formatCurrency(parseCurrency(insMonthlyInput.value)); pmiMonthlyDisplay.textContent = formatCurrency(parseCurrency(pmiMonthlyInput.value)); hoaMonthlyDisplay.textContent = formatCurrency(parseCurrency(hoaMonthlyInput.value)); }function getFormValues() { const homePrice = parseCurrency(homePriceInput.value); const dpAmount = parseCurrency(dpAmountInput.value); const loanAmount = Math.max(0, homePrice - dpAmount); const startDate = startDateInput.value ? new Date(startDateInput.value) : new Date(); const oneTimeDate = oneTimeDateInput.value ? new Date(oneTimeDateInput.value) : new Date(); return { homePrice, dpAmount, dpPercent: parseFloat(dpPercentInput.value) || 0, loanTerm: parseInt(loanTermSelect.value, 10), annualRate: parseFloat(interestRateInput.value) || 0, loanAmount, taxMonthly: parseCurrency(propertyTaxInput.value), insMonthly: parseCurrency(homeInsuranceInput.value), pmiMonthly: parseCurrency(pmiInput.value), hoaMonthly: parseCurrency(hoaInput.value), extraMonthly: parseCurrency(extraMonthlyInput.value), extraYearly: parseCurrency(extraYearlyInput.value), oneTimeAmount: parseCurrency(oneTimeAmountInput.value), oneTimeDate, startDate }; }function calculateAndDisplay() { loadingSpinner.classList.add('active'); setTimeout(() => { const form = getFormValues(); const monthlyRate = form.annualRate / 1200; const numPayments = form.loanTerm * 12;let pni = 0; if (form.loanAmount > 0 && numPayments > 0) { if (monthlyRate > 0) { pni = form.loanAmount * (monthlyRate * Math.pow(1 + monthlyRate, numPayments)) / (Math.pow(1 + monthlyRate, numPayments) - 1); } else { pni = form.loanAmount / numPayments; } } const pniDisplay = Number(pni.toFixed(2)); pniDisplayEl.textContent = formatCurrency(pniDisplay); document.getElementById('pni-monthly').value = formatInput(pniDisplay); updateMonthlyInputs();const payments = { pni: pniDisplay, taxMonthly: form.taxMonthly, insMonthly: form.insMonthly, pmiMonthly: form.pmiMonthly, hoaMonthly: form.hoaMonthly };const amortizationData = generateAmortization( form.loanAmount, monthlyRate, pni, numPayments, form.extraMonthly, form.extraYearly, form.oneTimeAmount, form.oneTimeDate, form.startDate ); updateUI(payments, form, amortizationData); loadingSpinner.classList.remove('active'); doughnutChartEl.classList.add('updated'); setTimeout(() => doughnutChartEl.classList.remove('updated'), 300); }, 100); }function generateAmortization(principal, monthlyRate, pni, totalPayments, extraMonthly, extraYearly, oneTimeAmount, oneTimeDate, startDate) { if (principal <= 0 || totalPayments <= 0) { return { yearlyData: {}, monthlyData: [], totalInterest: 0, firstPaymentDate: new Date(), lastPaymentDate: new Date() }; }let balance = principal; let totalInterest = 0; const firstPaymentDate = new Date(startDate.getFullYear(), startDate.getMonth() + 1, 1); let currentDate = new Date(firstPaymentDate); let lastPaymentDate = currentDate; const monthlyData = []; const yearlyData = {}; let oneTimeApplied = false;for (let i = 0; i < totalPayments && balance > 0.01; i++) { const year = currentDate.getFullYear(); const isYearStart = currentDate.getMonth() === 0;const interestPayment = balance * monthlyRate; let principalPayment = pni - interestPayment + extraMonthly;if (isYearStart && extraYearly > 0 && currentDate > firstPaymentDate) { principalPayment += extraYearly; }if (!oneTimeApplied && oneTimeAmount > 0 && currentDate >= oneTimeDate) { principalPayment += oneTimeAmount; oneTimeApplied = true; }if (principalPayment > balance) { principalPayment = balance; }balance -= principalPayment; totalInterest += interestPayment; lastPaymentDate = new Date(currentDate);monthlyData.push({ date: new Date(currentDate), interest: Number(interestPayment.toFixed(2)), principal: Number(principalPayment.toFixed(2)), balance: Number(Math.max(balance, 0).toFixed(2)) });if (!yearlyData[year]) { yearlyData[year] = { months: [], totalPrincipal: 0, totalInterest: 0, endBalance: 0 }; } yearlyData[year].months.push(monthlyData[monthlyData.length - 1]); yearlyData[year].totalPrincipal += principalPayment; yearlyData[year].totalInterest += interestPayment; yearlyData[year].endBalance = Math.max(balance, 0);currentDate.setMonth(currentDate.getMonth() + 1); }Object.keys(yearlyData).forEach(year => { yearlyData[year].totalPrincipal = Number(yearlyData[year].totalPrincipal.toFixed(2)); yearlyData[year].totalInterest = Number(yearlyData[year].totalInterest.toFixed(2)); yearlyData[year].endBalance = Number(yearlyData[year].endBalance.toFixed(2)); });return { yearlyData, monthlyData, totalInterest: Number(totalInterest.toFixed(2)), firstPaymentDate, lastPaymentDate }; }function updateUI(payments, form, amortizationData) { const { pni, taxMonthly, insMonthly, pmiMonthly, hoaMonthly } = payments; const { yearlyData, monthlyData, totalInterest, firstPaymentDate, lastPaymentDate } = amortizationData;dynamicRateEl.textContent = dynamicRateAmortEl.textContent = form.annualRate.toFixed(3); const totalMonthly = Number((pni + taxMonthly + insMonthly + pmiMonthly + hoaMonthly).toFixed(2)); totalMonthlyPaymentEl.textContent = formatCurrency(totalMonthly);doughnutChartEl.innerHTML = `${formatCurrency(totalMonthly).replace('.00', '')}/mo`; if (totalMonthly > 0) { const pniP = (pni / totalMonthly) * 100; const taxP = (taxMonthly / totalMonthly) * 100; const insP = (insMonthly / totalMonthly) * 100; const pmiP = (pmiMonthly / totalMonthly) * 100; doughnutChartEl.style.backgroundImage = `conic-gradient( var(--br-chart-pni) 0% ${pniP}%, var(--br-chart-tax) ${pniP}% ${pniP + taxP}%, var(--br-chart-ins) ${pniP + taxP}% ${pniP + taxP + insP}%, var(--br-chart-pmi) ${pniP + taxP + insP}% ${pniP + taxP + insP + pmiP}%, var(--br-chart-hoa) ${pniP + taxP + insP + pmiP}% 100% )`; } else { doughnutChartEl.style.backgroundImage = 'conic-gradient(#eee 0% 100%)'; }const payoffDateStr = lastPaymentDate.toLocaleString('default', { month: 'long', year: 'numeric' }); summaryLoanAmountEl.textContent = formatCurrency(form.loanAmount); summaryTotalInterestEl.textContent = formatCurrency(totalInterest); summaryTotalCostEl.textContent = formatCurrency(Number((form.loanAmount + totalInterest).toFixed(2))); summaryPayoffDateEl.textContent = payoffDateStr; firstPaymentDateEl.textContent = firstPaymentDate.toLocaleString('default', { month: 'long', year: 'numeric' }); lastPaymentDateEl.textContent = payoffDateStr;updateAmortizationGraph(yearlyData, form.loanAmount, totalInterest); updateAmortizationTable(yearlyData); }function updateAmortizationGraph(yearlyData, loanAmount, totalInterest) { const svg = document.getElementById('amortization-chart-svg'); svg.innerHTML = ''; if (Object.keys(yearlyData).length === 0 || loanAmount <= 0) { svg.innerHTML = 'No data to display'; return; }const allMonths = Object.values(yearlyData).flatMap(y => y.months); if (allMonths.length === 0) return;const width = 400, height = 220, m = { top: 20, right: 20, bottom: 35, left: 50 }; const w = width - m.left - m.right, h = height - m.top - m.bottom; const maxY = Math.max(loanAmount, totalInterest, 1);const g = document.createElementNS("http://www.w3.org/2000/svg", "g"); g.setAttribute("transform", `translate(${m.left},${m.top})`); svg.appendChild(g);const xScale = i => (i / (allMonths.length - 1)) * w; const yScale = v => h - (v / maxY) * h;const createPath = (data, color) => { const path = document.createElementNS("http://www.w3.org/2000/svg", "path"); path.setAttribute('d', `M0,${yScale(data[0])} ` + data.slice(1).map((d, i) => `L${xScale(i + 1)},${yScale(d)}`).join(' ')); path.setAttribute('class', 'line'); path.style.stroke = color; path.style.strokeWidth = '2.5'; path.style.opacity = '0.9'; return path; };let cumulativePrincipal = 0, cumulativeInterest = 0; const balanceData = allMonths.map(d => d.balance < 0 ? 0 : d.balance); const principalData = allMonths.map(d => (cumulativePrincipal += d.principal, Math.min(cumulativePrincipal, maxY))); const interestData = allMonths.map(d => (cumulativeInterest += d.interest, Math.min(cumulativeInterest, maxY)));[createPath(balanceData, 'var(--br-chart-balance)'), createPath(principalData, 'var(--br-chart-principal)'), createPath(interestData, 'var(--br-chart-interest)')].forEach(path => g.appendChild(path));for (let i = 0; i <= 5; i++) { const y = h * (i / 5); const line = document.createElementNS("http://www.w3.org/2000/svg", "line"); line.setAttribute('x1', 0); line.setAttribute('x2', w); line.setAttribute('y1', y); line.setAttribute('y2', y); line.setAttribute('class', 'grid'); g.appendChild(line); const text = document.createElementNS("http://www.w3.org/2000/svg", "text"); text.setAttribute('x', -10); text.setAttribute('y', y + 4); text.setAttribute('class', 'axis-label'); text.setAttribute('text-anchor', 'end'); text.textContent = `$${(maxY * (1 - i / 5) / 1000).toFixed(0)}k`; g.appendChild(text); }const yearKeys = Object.keys(yearlyData).sort(); const step = Math.max(1, Math.ceil(yearKeys.length / 6)); for (let i = 0; i < yearKeys.length; i += step) { const year = yearKeys[i]; const monthIndex = allMonths.findIndex(d => d.date.getFullYear() == year); if (monthIndex < 0) continue; const x = xScale(monthIndex); const line = document.createElementNS("http://www.w3.org/2000/svg", "line"); line.setAttribute('x1', x); line.setAttribute('x2', x); line.setAttribute('y1', 0); line.setAttribute('y2', h); line.setAttribute('class', 'grid'); g.appendChild(line); const text = document.createElementNS("http://www.w3.org/2000/svg", "text"); text.setAttribute('x', x); text.setAttribute('y', h + 20); text.setAttribute('class', 'axis-label'); text.setAttribute('text-anchor', 'middle'); text.textContent = year; g.appendChild(text); } }function updateAmortizationTable(yearlyData) { amortizationTableBody.innerHTML = ''; Object.keys(yearlyData).sort().forEach(year => { const yearData = yearlyData[year]; const details = document.createElement('details'); details.innerHTML = ` ${year} ${formatCurrency(yearData.totalPrincipal)} ${formatCurrency(yearData.totalInterest)} ${formatCurrency(yearData.endBalance)}
${yearData.months.map(row => ` `).join('')}
MonthPrincipalInterestRemaining Balance
${row.date.toLocaleString('default', { month: 'long' })}${formatCurrency(row.principal)}${formatCurrency(row.interest)}${formatCurrency(row.balance)}
`; amortizationTableBody.appendChild(details); }); }calculateAndDisplay(); });

Analyze Any Property Like a Pro

Instant Cash Flow Analysis

Quickly determine your potential monthly and annual cash flow after all expenses are paid.

Calculate Key Metrics

Our real estate calculator instantly computes vital metrics like Cap Rate and Cash on Cash ROI.

Factor in All Costs

Account for everything from your mortgage and property taxes to maintenance and management fees.

Compare Properties

Run scenarios for multiple properties to find the best investment opportunity for your goals.

Find Your Break-Even Point

Understand the occupancy rate needed to cover your costs and start turning a profit.

Project Long-Term Growth

Estimate the potential appreciation of your property value over the long term.

Making Smart Decisions with a Real Estate Investment Calculator

Investing in real estate can be a powerful way to build wealth, but success depends on making informed decisions. A great deal starts with great numbers. Our investment property calculator is designed to take the guesswork out of your analysis, providing you with the key financial metrics you need to evaluate any potential property. Whether you're a seasoned investor or just starting out, this tool helps you understand the true profitability of a rental property.

How to Use Our Real Estate Calculator

Our tool simplifies complex calculations into a few easy steps. By inputting the property's financial details, you can generate a comprehensive analysis in seconds.

  • Purchase Information: Start by entering the purchase price, your down payment, and the loan details, including the interest rate and term.
  • Income Details: Input the gross monthly rent you expect to collect from the property.
  • Operating Expenses: This is crucial. Add all your anticipated monthly expenses, such as property taxes, insurance, maintenance costs, property management fees, and any HOA dues.
  • Review Your Analysis: The calculator will instantly provide a detailed breakdown, including your rental property ROI, cap rate, and net operating income.

Key Metrics for Real Estate Investors

Understanding these terms is essential for evaluating any deal:

  • Cash Flow: This is the profit you have left over each month after collecting rent and paying all expenses, including your mortgage. Positive cash flow is the primary goal for most rental property investors.
  • Capitalization Rate (Cap Rate): This metric measures a property's rate of return based on its income. It's calculated by dividing the Net Operating Income (NOI) by the property's market value. A higher cap rate often indicates a better return, but it can also signal higher risk.
  • Cash on Cash Return (CoC): This shows you the return you're getting on the actual cash you invested (your down payment, closing costs, and rehab expenses). It's a powerful way to measure the performance of your capital.

By using this real estate calculator for your cash flow analysis, you can move forward with confidence, knowing your investment is built on a solid financial foundation.