0

For some reason calculating APR is very difficult. A lot of people ask, but not a lot of great answers. I'm working on a project, where I need to calculate APR. I have already calculated what the loan is, how much the user has to pay each month, and I have the amount of months. I found a formula online, but it doesn't make a lot of sense.

function calculateAPR(loan, repayments, months) {
    var p = 1;
    var tmp = 1;
    var a = p;
    var b = 0;
    while (Math.abs(tmp) > 0.0001) {
        p = (a - b) / 2 + b;
        tmp = (loan / repayments) - (1 - Math.pow(1 + p, -months)) / p;
        if (tmp > 0) {
            a = p;
        } else {
            b = p;
        }
    }
    var apr = Math.pow((1 + p), 12) - 1;
    return apr;
}

Math.pow()'s second argument is what you want to power by an amount. Basically 1+p^12 on the third last line. Math.abs() returns the absolute value (-10 becomes 10). If I input this:

loan = 80000
repayments = 7366
months = 12

I get an APR of 20.56%. That seems correct according to the site I got the formula from, but when I input the numbers into other websites, I get no where near the same result.

Can someone explain how this formula works? Why is there a loop? Is it because of compound interest? Is there a better formula? I'm looking for any kind of help, because I can't seem to find answers that solve this programmably. Thanks.

  • You could be interested by http://math.stackexchange.com/questions/1536653/approximating-the-compond-interest-for-a-loan – Claude Leibovici Feb 07 '17 at 09:22
  • @ClaudeLeibovici I appreciate your comment! However, it looks like that person gave up (last line of his answer) :( – MortenMoulder Feb 07 '17 at 09:31
  • What makes you think that code is wrong? For the example you gave, which sites give answers other than the one you got from the code? – quasi Feb 07 '17 at 09:32
  • @MortenMoulder. This was a post of mine ! You can use the results for an estimate and start using Newton or whichever method you want. – Claude Leibovici Feb 07 '17 at 09:34
  • @quasi I don't think the code is wrong. I just don't understand how it works and why there is a loop. Why I think it might be wrong, is because all the other calculators I tried, this one shows a different result each time. – MortenMoulder Feb 07 '17 at 09:35
  • @ClaudeLeibovici Can you explain what the numbers are? r = 0.01 and n = 180? – MortenMoulder Feb 07 '17 at 09:39
  • @MortenMoulder: Can you give a link to an online APR calculator that gives an answer other than the one produced by the code for the example you posted? – quasi Feb 07 '17 at 10:12
  • @quasi You can try this one: http://www.calculatorsoup.com/calculators/financial/apr-calculator.php - I already know the loan, repayments (monthly), and the total amount of months. – MortenMoulder Feb 07 '17 at 10:17
  • @MortenMoulder: that website gives the same answer as your program, using the following inputs: \begin{align} \text{loan}&=80,000.00\ \text{interest rate}&= 20.5406\ \text{compounding}&= \text{annual}\ \text{number of payments}&= 12\ \text{payment frequency}&= \text{monthly}\ \text{all fees}&= 0 \end{align} – quasi Feb 07 '17 at 10:46
  • @MortenMoulder: You can lso use EXCEL: https://support.office.com/en-us/article/IRR-function-64925eaa-9988-495b-b290-3ad0c163c1bc – cgiovanardi Feb 08 '17 at 12:48
  • @quasi The interest rate is not $20.5406$ though? Where did you get that from? – MortenMoulder Feb 08 '17 at 20:48
  • @cgiovanardi No Excel. – MortenMoulder Feb 08 '17 at 20:48
  • @MortenMoulder: Why is that not the interest rate? An interest rate of 20.5406% is consistent with the input data. – quasi Feb 08 '17 at 21:49
  • @quasi Where did you get it from? I only know $loan = 80,000.00$, $number of payments = 12$ and $monthly repayments = 8,000.00$ - Based on those 3 numbers, how do you get $interest rate = 20.5406$? – MortenMoulder Feb 09 '17 at 08:20
  • @MortenMoulder: That rate comes from your posted formula, and it also matches the results from the online calculator for which you posted a link. – quasi Feb 09 '17 at 09:24
  • @quasi We agree that the formula I posted and the formula on that website are basically the same? Let's imagine I didn't have my formula, but I only had the website. How would you get the interest rate then? – MortenMoulder Feb 09 '17 at 10:26
  • @MortenMoulder: Look way back in the comments. I gave you the inputs for the website. – quasi Feb 09 '17 at 10:44
  • @quasi I don't think you understand. Based on these three numbers: $loan = 80000$, $number of months = 12$, and $repayments = 7366$ how do you get the interest rate just from that website I sent you? Forget the interest rate, because that is completely unknown. – MortenMoulder Feb 10 '17 at 10:34
  • That website doesn't calculate the interest rate. You have to enter the interest rate as input. It then calculates the monthly payment. But the site can be used to verify that the results based on your code are correct. Look back in the comments -- I specified the inputs I used to check the results from the code. The results checked. – quasi Feb 10 '17 at 11:01

1 Answers1

1

The loop is designed to progressively narrow the interval in which the correct apr resides. At the outset, the program assumes (arbitrarily) that the correct monthly apr, $r$ say, is between $0$ and $1$ (i.e., between $0\text{%}$ and $100\text{%}$).

The variables $a,b$ denotes the bounds on $r$, where $b \le r \le a$.

As the program progresses, the values of $a$ and $b$ are adjusted, as follows . . .

The variable $p$ is set to the middle of the known range (i.e., $p = b + (a-b)/2$).

The value $p$ is then tested to see whether it's too low or too high.

If too low, $b$ is set to $p$, and $a$ is left as is.

If too high, $a$ is set to $p$, and $b$ is left as is.

After each pass through the loop, the value of $a - b$ is half its previous value.

When $a-b$ is less than $0.0001$ (an arbitrary tolerance), the loop terminates.

Then the value of $p$ at the end is the desired $r$, which is then adjusted from a monthly rate to an annual rate in the standard way.

quasi
  • 61,115
  • Thanks a lot! So basically what it does, is continue calculating tmp until tmp is below 0.0001. I get all the code and how it works, I just don't understand why it has to be above 0.0001 and why we have to grab the middle of the known range. – MortenMoulder Feb 07 '17 at 10:16
  • The loop will never get the exact value of $r$, so the choice needs to be made as to when $p$ is "close enough" to the true $r$. When the $a-b < 0.0001$, the value of $p$ at that stage is no more than $0.0001$ away from the true value of $r$. Thus, the program is using $0.0001$ as an acceptable error tolerance. – quasi Feb 07 '17 at 10:20
  • Oh, okay! So if I decrease the $0.0001$ (like to $0.00001$), it will compute more times but get a more precise APR? – MortenMoulder Feb 07 '17 at 10:24
  • When the bounding interval is $[b,a]$, the next interval will be either $[b,p]$ or $[p,a]$, Choosing $p$ as the midpoint of $[a,b]$ guarantees that the length of the new interval will be half that of the old interval. – quasi Feb 07 '17 at 10:27
  • Yes, a smaller tolerance will increase the accuracy at the expense of greater computation time. But be careful -- if the error tolerance is set too low, floating point calculations will produce errors which will dominate the error tolerance, making the apparently more accurate result an illusion. – quasi Feb 07 '17 at 10:30
  • Right, that makes sense. So the whole tmp = (loan / repayments) - (1 - Math.pow(1 + p, -months)) / p line, what exactly does that do? Does it follow some kind of formula? It doesn't look like anything I have seen before. – MortenMoulder Feb 07 '17 at 10:35
  • Multiply both sides by the (constant) repayment, regard the LHS as effectively zero, and solve for loan. That will give the standard meaning. – quasi Feb 07 '17 at 10:39
  • I have no clue what you just said. When do we multiply both sides? What's LHS? – MortenMoulder Feb 07 '17 at 10:42
  • LHS means "left hand side" (of the equation). In this case, the equation is tmp $= ;...$. If you multiply both sides by repayment, the new LHS is repayment $\times$ tmp. Since tmp is close to zero, and repayment is a fixed constant, the new LHS is also close to zero. If you replace the new LHS by zero, and then solve for loan, you get the usual formula connecting the quantities loan, repayment, number of periods, apr. – quasi Feb 07 '17 at 10:54
  • Oh okay, it all starts to make more sense now. I wouldn't exactly say I understnad this fully, but I'm starting to understand the overall of it. Thanks a lot :) – MortenMoulder Feb 07 '17 at 11:06