Files
mortgage/mortgage.py
JohnKent 53327a9e09 Initial commit. Things dont work yet.
--
user: JohnKent
branch 'default'
added greenfield_mortgage.txt
added mortgage.py
added mortgage_template.py
added statement.pdf.jinja
added statement.txt.jinja
2018-12-19 23:09:04 -05:00

131 lines
5.5 KiB
Python

import json
from decimal import *
from datetime import *
# this program reads the json file describing a mortgage and calculate the actual and projected amortization
# the first payment in the file should be the interest paid at closing
# the interest at closing covers interest that would be incurred from the date of closing until the first day
# that will be covered by the first loan payment
# i.e., the first loan payment is expected a month and a half after closing, the first two weeks interest is due
# at closing. The first payment will incur interest from one month before the bill is due.
#read in the file
#filename = "./10Kloan.txt"
filename = "./dadmortgage.txt"
#filename = "./brendamortgage.txt"
#filename = "./greenfield_mortgage.txt"
if filename:
with open(filename, 'r') as f:
datastore = json.load(f)
#read in the loan profile information
annual_rate = Decimal(datastore['interest rate'])/100
daily_interest_rate = annual_rate/360
principal = Decimal(datastore["principal"]).quantize(Decimal("1.00"))
periods_per_year = Decimal(datastore["periods per year"])
total_periods = Decimal(datastore["periods"])
payment_day_of_month = int(datastore['payment day of month'])
if "monthly_payment" in datastore:
monthly_payment = Decimal(datastore["monthly_payment"]).quantize(Decimal("1.00"))
else:
#calculate expected monthly payment
periodic_rate = annual_rate/periods_per_year
discount_factor = (((1+periodic_rate)**total_periods)-1) / (periodic_rate * ((1+periodic_rate)**total_periods))
monthly_payment = (principal / discount_factor).quantize(Decimal("1.00"))
print "Principal: ", principal
print "Interest Rate: ", annual_rate
print "Payments Per Year: ", periods_per_year
print "Loan Term: ", total_periods
print "Monthly Payment", monthly_payment
print "Payments due day: ", payment_day_of_month
print
#loop over the payments and calculate the actual amortization
actual_payments = datastore["payments"]
remaining_principal = principal
annual_interest = 0
total_interest = 0
interest_paid_through_date = datetime.strptime(datastore["start_interest_date"], "%Y-%m-%d").date()
next_payment_date = datetime.strptime(datastore["first payment month"], '%Y-%m-%d').date()
next_bill_date = date(year=next_payment_date.year, month=next_payment_date.month, day=payment_day_of_month)
old_bill_date = next_bill_date
payment_number = 1
current_year = next_bill_date.year
print "Payment History:"
print "\tBill\t\t\tPayment\tDays of\tPayment\t\tRemaining\t\tPrincipal\tInterest\t\t\tNew"
print "#\tDate\t\t\tDate\tInterst\tAmount\t\tPrincipal\t\tPayment\t\tPayment\t\t\tBalance"
for payment in actual_payments:
payment_date = datetime.strptime((payment[0]), '%Y-%m-%d').date()
payment_amount = Decimal(payment[1]).quantize(Decimal("1.00"))
#print next_bill_date, "\t", next_payment_date, "\t",
days_since_last_payment = (payment_date-interest_paid_through_date).days
#print days_since_last_payment
new_interest = (days_since_last_payment * remaining_principal * daily_interest_rate).quantize(Decimal("0.00"))
# new_principal = monthly_payment - new_interest
new_principal = payment_amount - new_interest
print payment_number, " ", next_bill_date, "\t\t", payment_date, "\t", days_since_last_payment, "\t", payment_amount, "\t\t\t", remaining_principal, "\t\t", new_principal,\
"\t\t", new_interest,
interest_paid_through_date = payment_date
total_interest = total_interest + new_interest
annual_interest=annual_interest+new_interest
remaining_principal = remaining_principal - new_principal
print "\t\t\t", remaining_principal
payment_number=payment_number+1
old_bill_date = next_bill_date
if old_bill_date.month < 12:
next_bill_date = date(year=old_bill_date.year, month = old_bill_date.month + 1, day=payment_day_of_month)
print "Total interest paid to date for", old_bill_date.year, " is", annual_interest
else:
next_bill_date = date(year=old_bill_date.year+1, month = 1, day=payment_day_of_month)
print "Total interest for ", old_bill_date.year, " was ", annual_interest
annual_interest = 0
print "Total interest paid to date on this loan is", total_interest
#loop over remaining scheduled payments and present estimated amortization
print "\nEstimated future amortization"
while (payment_number <= total_periods) and (remaining_principal > 0):
print payment_number, "\t",
payment_number = payment_number+1
print next_bill_date,
days_since_last_payment = (next_bill_date-interest_paid_through_date).days
print days_since_last_payment, "\t",
new_interest = (days_since_last_payment * remaining_principal * daily_interest_rate).quantize(Decimal("0.00"))
#make sure the last payment isn't too much
if new_interest+remaining_principal < monthly_payment:
monthly_payment = new_interest + remaining_principal
new_principal = monthly_payment - new_interest
print monthly_payment, "\t\t\t", remaining_principal, "\t\t", new_principal,\
"\t\t", new_interest,
remaining_principal = remaining_principal - new_principal
print "\t", remaining_principal
interest_paid_through_date = next_bill_date
old_bill_date = next_bill_date
if old_bill_date.month < 12:
next_bill_date = date(year=old_bill_date.year, month = old_bill_date.month + 1, day=payment_day_of_month)
else:
next_bill_date = date(year=old_bill_date.year+1, month = 1, day=payment_day_of_month)
if remaining_principal > 0:
print 'Balloon payment due:', remaining_principal