Last active
April 26, 2017 18:11
-
-
Save jerivas/bbce6110f2ae534bd876f02539da75a7 to your computer and use it in GitHub Desktop.
Loan calculator
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def mortgage_calculator(form_data): | |
""" | |
Takes a single object `form_data` and returns all calculations in a `results` object. | |
Notes: | |
- The `Decimal` class simply takes any number or string and casts it into a decimal | |
value for calculations. See https://docs.python.org/2/library/decimal.html | |
- When you see '%.2f' that's simply forcing a value to be displayed with two | |
decimal places, i.e. 15.4504 comes out as 15.45. | |
""" | |
import math | |
from decimal import Decimal | |
results = {} | |
# Clean up POST data if required | |
if 'principal' in form_data: | |
form_data['principal'] = form_data['principal'].replace(',', '').replace('$', '') | |
if 'annual_interest_rate' in form_data: | |
form_data['annual_interest_rate'] = form_data['annual_interest_rate'].replace('%', '') | |
if 'payment_amount' in form_data: | |
form_data['payment_amount'] = (form_data['payment_amount'].replace(',', '').replace('$', '')) | |
if 'additional_payment' in form_data: | |
form_data['additional_payment'] = (form_data['additional_payment'].replace(',', '').replace('$', '')) | |
# Perform calculations | |
calc_type = form_data['calc_type'] | |
principal = form_data['principal'] | |
loan_years = form_data['loan_duration'] | |
if loan_years == 0: | |
loan_years = 1 | |
show_amort = form_data['show_amort'] | |
no_payments = loan_years * 12 | |
air = form_data['annual_interest_rate'] * Decimal('.01') | |
mir = air / 12 # E5 | |
pow = math.pow(mir + 1, no_payments) # E6 | |
additional_payment = form_data['additional_payment'] | |
p_tax = form_data['property_tax'] | |
h_ins = form_data['hazard_insurance'] | |
m_ins = form_data['mortgage_insurance'] | |
hoa_fees = form_data['hoa_fees'] | |
other = form_data['other'] | |
payment = round(mir * (principal * Decimal(pow / (pow - 1))), 2) | |
# Amortization schedule | |
amort = [] | |
balance = principal | |
payment = Decimal(payment) | |
if additional_payment: | |
payment = payment + additional_payment | |
if p_tax: | |
p_tax = Decimal(p_tax) | |
else: | |
p_tax = 0 | |
if h_ins: | |
h_ins = Decimal(h_ins) | |
else: | |
h_ins = 0 | |
if m_ins: | |
m_ins = Decimal(m_ins) | |
else: | |
m_ins = 0 | |
if hoa_fees: | |
hoa_fees = Decimal(hoa_fees) | |
else: | |
hoa_fees = 0 | |
if other: | |
other = Decimal(other) | |
else: | |
other = 0 | |
fees = Decimal(round(p_tax + h_ins + m_ins + hoa_fees + other, 2)) | |
# Type "I" calculations | |
# Returns early and prevents the rest of the function from running | |
if calc_type == 'I': | |
interest_only_payment = principal * air / 12 | |
total_payment = interest_only_payment + fees | |
results['interest_only_payment'] = '%.2f' % interest_only_payment | |
results['fees'] = fees | |
results['total_payment'] = '%.2f' % total_payment | |
return results | |
# Other calculations | |
pmt_no = 0 | |
total_interest = 0 | |
total_principal = 0 | |
while (balance > 0): | |
pmt_no += 1 | |
i_part = Decimal(round(balance * mir, 2)) | |
total_interest += i_part | |
if balance < payment: | |
p_part = balance | |
else: | |
p_part = Decimal(payment - i_part) | |
total_principal += p_part | |
balance = balance - p_part | |
if pmt_no == no_payments: | |
p_part += balance | |
balance = 0 | |
amort.append({'pmt_no': pmt_no, | |
'i_part': '%.2f' % i_part, | |
'p_part': '%.2f' % p_part, | |
'cum_prin': '%.2f' % total_principal, | |
'cum_int': '%.2f' % total_interest, | |
'balance': '%.2f' % balance}) | |
results['show_amort'] = show_amort | |
results['amort'] = amort | |
results['fees'] = fees | |
results['loan_payment'] = '%.2f' % payment | |
results['total_payment'] = '%.2f' % (payment + fees) | |
results['number_payments'] = pmt_no | |
results['total_interest'] = round(total_interest, 2) | |
return results |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<form action="" class="calc-form" method="post"> | |
<label for="id_calc_type">Calculate...</label> | |
<select id="id_calc_type" name="calc_type"> | |
<option value="PI"> | |
Principal and Interest | |
</option> | |
<option value="I"> | |
Interest Only | |
</option> | |
</select> | |
<label for="id_principal">Loan Amount:</label> | |
<input id="id_principal" name="principal" type="text"> | |
<label for="id_loan_duration">Loan Term (in years):</label> | |
<input id="id_loan_duration" name="loan_duration" type="text"> | |
<label for="id_annual_interest_rate">Annual Interest Rate:</label> | |
<input id="id_annual_interest_rate" name="annual_interest_rate" type="text"> | |
<label for="id_additional_payment">(Optional) Additional Monthly Principal Payment:</label> | |
<input id="id_additional_payment" name="additional_payment" type="text"> | |
<span class="helptext">(optional) See how your amortization schedule would change by accelerating payments.</span> | |
<label for="id_show_amort">Show Amortization Schedule:</label> | |
<input id="id_show_amort" name="show_amort" type="checkbox"> | |
<label for="id_property_tax">Monthly Property Tax:</label> | |
<input class="fees" id="id_property_tax" name="property_tax" type="text" value="0"> | |
<label for="id_hazard_insurance">Monthly Hazard Insurace:</label> | |
<input class="fees" id="id_hazard_insurance" name="hazard_insurance" type="text" value="0"> | |
<label for="id_mortgage_insurance">Monthly Mortgage Insurance:</label> | |
<input class="fees" id="id_mortgage_insurance" name="mortgage_insurance" type="text" value="0"> | |
<label for="id_hoa_fees">Monthly HOA Dues:</label> | |
<input class="fees" id="id_hoa_fees" name="hoa_fees" type="text" value="0"> | |
<label for="id_other">Other:</label> | |
<input class="fees" id="id_other" name="other" type="text" value="0"> | |
</form> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment