Skip to content

Instantly share code, notes, and snippets.

@dylanjm
Created January 1, 2021 19:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dylanjm/aa813d29661e63f77b26b3c2230c6cf8 to your computer and use it in GitHub Desktop.
Save dylanjm/aa813d29661e63f77b26b3c2230c6cf8 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python3
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from tabulate import tabulate
def amort(principal, rate, n):
return principal * (rate * ((1 + rate) ** n)) / ((1 + rate) ** n - 1)
def compute_schedule(bal, pmt, rate):
while bal > 0:
new_bal = bal - (pmt - (bal * rate))
period_interest = (bal * rate)
period_principal = pmt - (bal * rate)
if new_bal > 0:
yield (new_bal, period_interest, period_principal)
bal = new_bal
# def amort_table(loan_amt, pmt, rate):
# df = pd.DataFrame(
# columns=['Amount', 'Interest', 'Principal', 'Balance'],
# index = np.arange(1, 361, 1)
# )
# for x, (b, i, p) in enumerate(compute_schedule(loan_amt, pmt, rate)):
# df.iloc[x + 1] = pd.Series(
# {
# 'Amount': round(pmt, 2),
# 'Interest': round(i, 2),
# 'Principal': round(p, 2),
# 'Balance': round(b, 2)
# }
# )
# print(df.to_markdown())
def dollar_fmt(var):
return f'${var:>12,.2f}'
def indent(txt, spaces=2):
return "\n".join(" "*spaces + ln for ln in txt.splitlines())
class color:
PURPLE = '\033[95m'
CYAN = '\033[96m'
DARKCYAN = '\033[36m'
BLUE = '\033[94m'
GREEN = '\033[92m'
YELLOW = '\033[93m'
RED = '\033[91m'
BOLD = '\033[1m'
UNDERLINE = '\033[4m'
END = '\033[0m'
def pct_input(message):
var = float(input(message))
if var > 1.0:
var_string = f'{var:.2f}%'
var = var / 100
else:
var_string = f'{var*100:.2f}%'
return (var, var_string)
def main():
print('\n' + color.UNDERLINE + color.YELLOW + "Loan Term Questions" + color.END)
ask_price = float(input("Enter the current asking price ($): "))
cc_pct, cc_pct_str = pct_input("Enter closing costs as percent of asking price (%): ")
pct_down, pct_down_str = pct_input("Enter down payment as percent of purchase price (%): ")
ann_rate, ann_rate_str = pct_input("Enter the annual interest rate on loan (%): ")
max_fha = 331_760.00
closing_costs = cc_pct * ask_price
purchase = ask_price + closing_costs
down_pmt = purchase * pct_down
loan_amt = purchase - down_pmt
rate = ann_rate / 12
n = 30 * 12
fha_delta = loan_amt - max_fha
if fha_delta > 0:
loan_fha_str = color.RED + dollar_fmt(fha_delta) + color.END
else:
loan_fha_str = color.GREEN + dollar_fmt(fha_delta) + color.END
print('\n' + color.UNDERLINE + color.BLUE + color.BOLD + "Loan Terms:" + color.END)
inputs_table = [
['Asking Price:', dollar_fmt(ask_price)],
['Closing Costs:', dollar_fmt(closing_costs), f'@ {cc_pct_str} asking price'],
['Purchase Price:', dollar_fmt(purchase)],
['Down Payment:', dollar_fmt(down_pmt), f'@ {pct_down_str} purchase price'],
['Loan Amount:', dollar_fmt(loan_amt)],
['FHA Maximum:', dollar_fmt(max_fha), 'low-cost region maximum'],
['Δ FHA/Loan:', f'{loan_fha_str}', 'constrained: Δ < 0'],
['Period Rate:', f'{rate*100:.2f}%', f'@ {ann_rate_str} fixed annual'],
['Periods:', n]
]
for row in inputs_table:
row[0] = color.BOLD + row[0] + color.END
print(indent(tabulate(inputs_table, colalign=('left', 'right', 'right'), tablefmt='plain')))
print('\n' + color.UNDERLINE + color.BLUE + color.BOLD + "Monthly Summary:" + color.END)
annual_pmi = loan_amt * 0.0082
monthly_pmi = annual_pmi / 12
annual_taxes = 1700.00
monthly_taxes = 1700.00 / 12
annual_insurance = 727.32
monthly_insurance = annual_insurance / 12
monthly_pmt = amort(loan_amt, rate, n)
monthly_total = monthly_pmt + monthly_taxes + monthly_pmi + monthly_insurance
pmt_table = [
['Monthly Payment:', f'${monthly_pmt:>10,.2f}'],
['Property Taxes:', f'${monthly_taxes:>10,.2f}', f'@ ${annual_taxes:>9,.2f} Annual'],
['Mortgage Insurance:', f'${monthly_pmi:>10,.2f}', f'@ ${annual_pmi:>9,.2f} Annual'],
['Home Insurance:', f'${monthly_insurance:>10,.2f}', f'@ ${annual_insurance*12:>9,.2f} Annual'],
['Total Monthly Payment:', f'${monthly_total:>10,.2f}']
]
for row in pmt_table:
row[0] = color.BOLD + row[0] + color.END
print(indent(tabulate(pmt_table, colalign=('left', 'right', 'right'), tablefmt='plain')))
gs_savings = 15_500
ally_savings = 1_200
car_money = 1_300
total_savings = gs_savings + ally_savings + car_money
inspections = 800
break_lease = 1_200
moving = 500
total_expenses = down_pmt + inspections + break_lease + moving
remaining_reserves = total_savings - total_expenses
if remaining_reserves < 0:
remaining_reserves_str = color.RED + f'${remaining_reserves:>12,.2f}' + color.END
else:
remaining_reserves_str = color.GREEN + f'${remaining_reserves:>12,.2f}' + color.END
print('\n' + color.UNDERLINE + color.BLUE + color.BOLD + "Expenses Summary:" + color.END)
upfront = [
['Total Savings:', f'${total_savings:>12,.2f}'],
['Total Expenses:', f'${(total_expenses)*-1:>12,.2f}'],
[' - Down Payment', f'${down_pmt*-1:>12,.2f}'],
[' - Inspections & Appraisal', f'${inspections*-1:>12,.2f}'],
[' - Break Lease', f'${break_lease*-1:>12,.2f}'],
[' - Moving', f'${moving*-1:>12,.2f}'],
['Remaining:', remaining_reserves_str]
]
for row in upfront:
row[0] = color.BOLD + row[0] + color.END
print(indent(tabulate(upfront, colalign=('left', 'right'), tablefmt='plain')))
print('\n' + color.UNDERLINE + color.BLUE + color.BOLD + "Financial Summary:" + color.END)
savings = [
['Goldman Sachs', f'$ {gs_savings:,.2f}'],
['Ally', f'$ {ally_savings:,.2f}'],
['Car Money', f'$ {car_money:,.2f}'],
['Total Saved', f'${gs_savings + ally_savings + car_money:,.2f}']
]
pay_rate = 6_228
annual_salary = pay_rate * 12
debt_ratio = (monthly_total / pay_rate) * 100
pay_rates = [
['Pay Rate:', f'${pay_rate:>10,.2f}'],
['Annual Salary:', f'${annual_salary:>10,.2f}'],
['Mortgage-Income Ratio:', f'{debt_ratio:,.2f}%']
]
for row in pay_rates:
row[0] = color.BOLD + row[0] + color.END
print(indent(tabulate(pay_rates, colalign=('left', 'right'), tablefmt='plain')))
# print(tabulate(savings, colalign=('left', 'right')))
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment