Python Mortgage Calculator
Build a mortgage calculator that computes monthly payments, generates amortisation schedules, and compares different deposit and rate scenarios. Essential for anyone buying property.
Basic Mortgage Calculator
Calculate your monthly payment, total cost, and total interest using the standard mortgage payment formula.
def mortgage_calculator(property_price, deposit_pct, interest_rate, term_years):
"""Calculate monthly mortgage payment and total cost."""
deposit = property_price * (deposit_pct / 100)
loan = property_price - deposit
monthly_rate = interest_rate / 100 / 12
num_payments = term_years * 12
if monthly_rate == 0:
monthly_payment = loan / num_payments
else:
monthly_payment = loan * (monthly_rate * (1 + monthly_rate)**num_payments) / \
((1 + monthly_rate)**num_payments - 1)
total_paid = monthly_payment * num_payments
total_interest = total_paid - loan
return {
"property_price": property_price,
"deposit": deposit,
"loan_amount": loan,
"monthly_payment": monthly_payment,
"total_paid": total_paid,
"total_interest": total_interest,
"ltv": (loan / property_price) * 100
}
result = mortgage_calculator(300000, 10, 4.5, 25)
for k, v in result.items():
print(f"{k}: {v:,.2f}" if isinstance(v, float) else f"{k}: {v}")Amortisation Schedule
See exactly how much goes to principal vs interest each month. In the early years, most of your payment is interest.
import pandas as pd
def amortisation_schedule(loan, annual_rate, years):
"""Generate full amortisation schedule."""
monthly_rate = annual_rate / 100 / 12
num_payments = years * 12
monthly_payment = loan * (monthly_rate * (1 + monthly_rate)**num_payments) / \
((1 + monthly_rate)**num_payments - 1)
schedule = []
balance = loan
for month in range(1, num_payments + 1):
interest_payment = balance * monthly_rate
principal_payment = monthly_payment - interest_payment
balance -= principal_payment
schedule.append({
"Month": month,
"Payment": round(monthly_payment, 2),
"Principal": round(principal_payment, 2),
"Interest": round(interest_payment, 2),
"Balance": round(max(balance, 0), 2)
})
return pd.DataFrame(schedule)
schedule = amortisation_schedule(270000, 4.5, 25)
print(schedule.head(12))
# Year 1 summary
y1 = schedule[:12]
print(f"\nYear 1: Principal paid = £{y1['Principal'].sum():,.2f}")
print(f"Year 1: Interest paid = £{y1['Interest'].sum():,.2f}")Compare Scenarios
See how different deposit sizes and interest rates affect your monthly payments and total interest paid.
import matplotlib.pyplot as plt
# Compare different deposit sizes
deposits = [5, 10, 15, 20, 25]
results = []
for dep in deposits:
r = mortgage_calculator(300000, dep, 4.5, 25)
results.append({
"Deposit %": f"{dep}%",
"Deposit": f"£{r['deposit']:,.0f}",
"Monthly": f"£{r['monthly_payment']:,.2f}",
"Total Interest": f"£{r['total_interest']:,.0f}",
"LTV": f"{r['ltv']:.0f}%"
})
df = pd.DataFrame(results)
print(df.to_string(index=False))
# Plot monthly payment vs interest rate
rates = [x/10 for x in range(20, 80)] # 2.0% to 7.9%
payments = [mortgage_calculator(300000, 10, r, 25)["monthly_payment"] for r in rates]
plt.figure(figsize=(10, 6))
plt.plot(rates, payments, linewidth=2, color="blue")
plt.xlabel("Interest Rate (%)")
plt.ylabel("Monthly Payment (£)")
plt.title("Monthly Payment vs Interest Rate (£300k, 10% deposit, 25yr)")
plt.grid(True, alpha=0.3)
plt.savefig("mortgage_rates.png", dpi=150)
plt.show()