Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added Amortization Table #11368

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
108 changes: 108 additions & 0 deletions financial/amortization_table.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
"""
Program creates an amortization table for a loan, given
- Principal borrowed
- Rate of interest per annum
- Years to repay the loan

Wikipedia Reference: https://www.investopedia.com/terms/a/amortization.asp
"""

import pandas as pd


def payment(principal: float, interest_rate: float, payments: int) -> float:
"""
Calculate the monthly payment for a loan.

Parameters
----------
principal : float
The amount of the loan.
interest_rate : float
The annual interest rate for the loan.
years : int
The term of the loan in years.

Returns
-------
float
The monthly payment for the loan.

Examples
--------
>>> payment(1000, 0.1, 1)
1099.9999999999995
"""
payment = principal * interest_rate / (1 - (1 + interest_rate) ** -payments)

return payment


def amortization_table(
principal: float, interest_rate: float, years: int
) -> pd.DataFrame:
"""
Create an amortization table for a loan.

Parameters
----------
principal : float
The amount of the loan.
interest_rate : float
The annual interest rate for the loan.
years : int
The term of the loan in years.

Returns
-------
pd.DataFrame
The amortization table for the loan.

Examples
--------
>>> amortization_table(1000, 0.1, 1)
Payment Principal Interest Remaining
0 0.00 0.00 0.00 1000.00
1 87.92 79.58 8.33 920.42
2 87.92 80.25 7.67 840.17
3 87.92 80.91 7.00 759.26
4 87.92 81.59 6.33 677.67
5 87.92 82.27 5.65 595.40
6 87.92 82.95 4.96 512.45
7 87.92 83.65 4.27 428.80
8 87.92 84.34 3.57 344.46
9 87.92 85.05 2.87 259.41
10 87.92 85.75 2.16 173.66
11 87.92 86.47 1.45 87.19
12 87.92 87.19 0.73 0.00
"""
payments = years * 12
interest_rate /= 12
payment_amount = payment(principal, interest_rate, payments)
amor_table = pd.DataFrame(
index=range(payments + 1),
columns=["Payment", "Principal", "Interest", "Remaining"],
dtype="float",
data=0,
)

amor_table["Payment"][1:] = payment_amount
amor_table["Remaining"][0] = principal
for i in range(1, payments + 1):
amor_table["Interest"][i] = amor_table["Remaining"][i - 1] * interest_rate
amor_table["Principal"][i] = (
amor_table["Payment"][i] - amor_table["Interest"][i]
)
amor_table["Remaining"][i] = (
amor_table["Remaining"][i - 1] - amor_table["Principal"][i]
)
amor_table = amor_table.round(2)
amor_table = amor_table.abs()

return amor_table


if __name__ == "__main__":
import doctest

doctest.testmod()