-- user: JohnKent branch 'default' added greenfield_mortgage.txt added mortgage.py added mortgage_template.py added statement.pdf.jinja added statement.txt.jinja
131 lines
5.5 KiB
Python
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
|