1+ """
2+ Wiki: https://en.wikipedia.org/wiki/Amortization_calculator
3+ """
4+
5+
16def level_payment (principal , annual_rate_pct , years , payments_per_year = 12 ):
27 if principal <= 0 :
38 raise ValueError ("principal must be > 0" )
@@ -11,14 +16,7 @@ def level_payment(principal, annual_rate_pct, years, payments_per_year=12):
1116 return principal * (r * factor ) / (factor - 1 )
1217
1318
14- def amortization_schedule (
15- principal ,
16- annual_rate_pct ,
17- years ,
18- payments_per_year = 12 ,
19- print_annual_summary = False ,
20- eps = 1e-9 ,
21- ):
19+ def amortization_schedule (principal , annual_rate_pct , years , payments_per_year = 12 , print_annual_summary = False , eps = 1e-9 ):
2220 pmt = level_payment (principal , annual_rate_pct , years , payments_per_year )
2321 r = (annual_rate_pct / 100.0 ) / payments_per_year
2422 n = years * payments_per_year
@@ -28,9 +26,13 @@ def amortization_schedule(
2826
2927 if print_annual_summary :
3028 print (
31- f"{ 'Year' :<6} { 'Months Pd' :<12} { 'Tenure Left' :<13} { 'Payment/Period' :<16} { 'Outstanding' :<14} "
29+ (
30+ f"{ 'Year' :<6} { 'Months Pd' :<12} { 'Tenure Left' :<13} "
31+ f"{ 'Payment/Period' :<16} { 'Outstanding' :<14} "
32+ )
3233 )
3334
35+
3436 for period in range (1 , n + 1 ):
3537 interest = balance * r
3638 principal_component = pmt - interest
@@ -42,22 +44,23 @@ def amortization_schedule(
4244 else :
4345 payment_made = pmt
4446
45- if (
46- principal_component < 0 and principal_component > - eps
47- ): # clamp tiny negatives
47+ if principal_component < 0 and principal_component > - eps : # clamp tiny negatives
4848 principal_component = 0.0
4949
5050 balance = max (0.0 , balance - principal_component )
5151 schedule .append ([period , payment_made , interest , principal_component , balance ])
5252
5353 # streamline for all time periods (monthly/quarterly/biweekly/weekly)
54- months_elapsed = int (round ((period * 12 ) / payments_per_year ))
54+ months_elapsed = (round ((period * 12 ) / payments_per_year ))
5555
5656 if print_annual_summary and (months_elapsed % 12 == 0 or balance <= eps ):
5757 tenure_left_periods = n - period
5858 print (
59- f"{ months_elapsed // 12 :<6} { months_elapsed :<12} { tenure_left_periods :<13} { pmt :<16.2f} { balance :<14.2f} "
59+ (
60+ f"{ months_elapsed // 12 :<6} { months_elapsed :<12} { tenure_left_periods :<13} "
61+ f"{ pmt :<16.2f} { balance :<14.2f} "
6062 )
63+ )
6164
6265 if balance <= eps :
6366 break
@@ -69,7 +72,5 @@ def amortization_schedule(
6972 return round (pmt , 4 ), schedule
7073
7174
72- pmt , sched = amortization_schedule (
73- 10000 , 5.5 , 15 , payments_per_year = 12 , print_annual_summary = True
74- )
75+ pmt , sched = amortization_schedule (10000 , 5.5 , 15 , payments_per_year = 12 , print_annual_summary = True )
7576print (pmt )
0 commit comments