Skip to content

Instantly share code, notes, and snippets.

@es0m
Last active June 28, 2018 12:17
Show Gist options
  • Save es0m/b73ca29ec29e7cdb0d26af4447dc5da1 to your computer and use it in GitHub Desktop.
Save es0m/b73ca29ec29e7cdb0d26af4447dc5da1 to your computer and use it in GitHub Desktop.
# compares the costs of two consecutive 5 year mortgages with one 10 year mortgage
from matplotlib import pyplot as plt
def installment(rate, principal, terms):
c = rate*principal/(1-pow(1+rate, -terms))
return c
def interest(rate, principal):
c = rate*principal
return c
def round(value):
return 1.0*int(value*100)/100
def fixed_term_mortgage(rate, principal, terms, terms_paid, overpayment):
c0 = installment(rate, principal, terms)
i0 = interest(rate, principal)
#downpayment = c0-i0 # what goes straight to balance
#print("installment: {}".format(c0))
payment = c0 + overpayment
balance = principal
interest_paid = 0
balances = []
for i in range(terms_paid):
i0 = interest(rate, balance)
interest_paid = interest_paid + i0
downpayment = (payment-i0)
if ( balance-downpayment < 0 ) :
balance = 0
terms_paid = i
break
balance = balance - downpayment
balances.append(balance)
total_paid = interest_paid + (principal-balance)
return (balance, interest_paid, total_paid, balances)
def run(principal, overpayment10ys, rate5ys_percent, rate10ys_percent):
# base rate for 5 years mortgage
rate5ys = rate5ys_percent/100/12
# overall lenght of mortgage to run
terms = 25*12
terms_5ys = 5*12
# base rate for 10 years mortgage
rate10ys = rate10ys_percent/100/12
terms_10ys = 10*12
installment10ys = installment(rate10ys, principal, terms)
installment5ys = installment(rate5ys, principal, terms)
# how much do we overpay for 5ys as the 10ys mortgage should be more expensive
overpayment5ys = max(0, overpayment10ys+installment10ys-installment5ys)
print("overpayment: {}, installments 10years: {}, installments 5ys: {}".format(overpayment5ys, installment10ys, installment5ys))
(balance10ys, interest_paid10ys, total_paid10, balances10ys) = fixed_term_mortgage(rate10ys, principal, terms, terms_10ys, overpayment10ys)
print("balance: {}, interest paid: {}, terms paid: {}, total paid: {}".format(round(balance10ys),
round(interest_paid10ys), terms_10ys, round(total_paid10)))
plt.plot(range(len(balances10ys)), balances10ys, color='b', linestyle='--')
(balance5ys, interest_paid5ys, total_paid5, balances5ys) = fixed_term_mortgage(rate5ys, principal, terms, terms_5ys, overpayment5ys)
print("balance: {}, interest paid: {}, terms paid: {}".format(balance5ys, interest_paid5ys, terms_5ys))
plt.plot(range(len(balances5ys)), balances5ys, color='r', linestyle='--')
rates = []
end_balances = []
for r in range(20):
extra_rate = r/4
r2 = rate5ys + extra_rate/100/12
new_installment = installment(r2, balance5ys, terms-terms_5ys)
overpayment5ys = max(0, overpayment10ys+(installment(rate10ys, principal, terms)-new_installment))
print("overpayment: {}, installments 10years: {}, installments 5ys: {}".format(overpayment5ys,
installment(rate10ys, principal, terms), new_installment))
(balance5and5ys, interest_paid5and5ys, total_paid52, balances_rest) = fixed_term_mortgage(r2, balance5ys, terms-terms_5ys, terms_5ys, overpayment5ys)
plt.plot(range(len(balances5ys), len(balances5ys)+len(balances_rest)), balances_rest, color='g', linestyle='--', linewidth=0.1)
#print("balance: {}, interest paid: {}, terms paid: {}".format(r2, balance5and5ys, interest_paid5and5ys, terms_5ys))
print("rate: {}, total balance: {}, interest paid: {}, terms paid: {}, total paid: {}".format(round(rate5ys_percent+extra_rate),
round(balance5and5ys), round(interest_paid5ys+interest_paid5and5ys), 2*terms_5ys, round(total_paid5+total_paid52)))
rates.append(r2)
end_balances.append(balance5and5ys)
plt.show()
plt.clf()
#plt.plot(rates, end_balances)
#plt.show()
if __name__ == '__main__':
import argparse
parser = argparse.ArgumentParser(description='check mortgage balances')
parser.add_argument('-o', '--overpayment',
help='overpayment for 10 years', type=int, default=0)
parser.add_argument('-p', '--principal',
help='initial principal for the mortgage', type=int, default=100000)
parser.add_argument('-r5', '--rate5ys',
help='annual rate for 5 years in percent', type=float, default=1.94)
parser.add_argument('-r10', '--rate10ys',
help='annual rate for 10 years in percent', type=float, default=2.74)
args = parser.parse_args()
run(args.principal, args.overpayment, args.rate5ys, args.rate10ys)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment