Search code examples
pythonalgorithmmathfinance

Python: smarter way to calculate loan payments


How to calculate the monthly fee on a loan?

Given is:

  • a: an amount to loan.
  • b: the loan period (number of months).
  • c: the interest rate p.a. (interests is calculated and added every month, 1/12 of the interest is added. So if the interest is on 12%, 1% interest is added every month).
  • d: the amount of money owed after the end of the period.

This problem is a bit different than the usual since, the goal is not to have the loan payed after the loan period has ended, but to still owe an amount that is given. I have been able to find an algorithm so solve the problem if I wanted to pay the entire amount, but it will of course not work for this problem where the goal is to end up owing a given amount rather than not owing anything.

I managed to make a solution to this problem by starting with an guess and then keep on improving that guess until it was close enough. I wondered however, if there is a better way to simply calculate this, rather than just guessing.

Edit: Here's how I'm doing it now.

def find_payment(start, end, months, interest):
    difference = start
    guess = int(start / months * interest)
    while True:
        total = start
        for month in range(1, months + 1):
            ascribe = total * interest / 12
            total = total + ascribe - guess
        difference = total - end
        # See if the guess was good enough.
        if abs(difference) > start * 0.001:
            if difference < 0:
                if abs(difference) < guess:
                    print "payment is %s" % guess
                    return evolution(start, guess, interest, months)
                else:
                    mod = int(abs(difference) / start * guess)
                    if mod == 0:
                        mod = 1
                    guess -= mod
            else:
                mod = int(difference / start * guess)
                if mod == 0:
                    mod = 1
                guess += mod
        else:
            print "payment is %s" % guess
            return evolution(start, guess, interest, months)

evolution is just a function that displays how the loan would look like payment for payment and interest for interest, summing up total amount of interest paid etc.

An example would be if I wanted to find out the monthly payments for a loan starting with $100k and ending at $50k with an interest of 8% and a duration of 70 months, calling

>>> find_payment(100000, 50000, 70, 0.08)
payment is 1363

In the above case I would end up owing 49935, and I went through the loop 5 times. The amount of times needed to go through the loop depends on how close I want to get to the amount and it varies a bit.


Solution

  • This is a basically a mortgage repayment calculation.

    Assuming that start is greater than end, and that interest is between 0 and 1 (i.e. 0.1 for 10% interest)

    First consider the part of the payment you want to pay off.

    Principal = start - end
    

    The monthly payment is given by:

    pay_a = (interest / 12) / (1 - (1+interest/12) ^ (-months))) * Principal
    

    You then need to consider the extra interest. Which is just equal to the remaining principal times the monthly interest

    pay_b = interest / 12 * end
    

    So the total payment is

    payment = (interest / 12) * (1 / (1 - (1+interest/12) ^ (-months))) * Principal + end)
    

    On the example you gave of

    Start: 100000
    End:  50000
    Months: 70
    Interest: 8% 
    pay_a = 896.20
    pay_b = 333.33
    Payment = 1229.54
    

    When I tested these values in Excel, after 70 payments the remaing loan was 50,000. This is assuming you pay the interest on the notional before the payment is made each month.