0

I am trying to implement the "RATE()" function in Java as Excel does it. After initial research, I saw I needed to use Newton's method to get to the rate since we cannot solve for r explicitly.

Payment function => P = r × (PV) /(1 − (1 + r) ^ −n)

I calculated the derivative you see below in the static method using Mathmatica and then went back in and added the variables.

The code is producing values that actually get worse with each iteration.

Here are the results from the code below for the first four iterations:

0.0018297879140010277
0.3979496233654264
-1.5652077088934568E102
Infinity

(I will make this a recursive method once it actually works).

Here is the code. Any help what's off would be appreciated.

public static void main(String[] args)
{
    double Pv = 99000.0;   // financed amount, minus any fees.
    double loanAmount = 100000.0; // before fees.
    int numPeriods = 360;  // number of payments
    double lastGuess = 0.00001;  // starting point for Newton's method.
    double newGuess = 0.0;   // calculated Newton result on each iteration

    // first guess

    newGuess = lastGuess - f(Pv, numPeriods, lastGuess, loanAmount) / derivative(Pv, numPeriods, lastGuess);
    System.out.println(newGuess);

    lastGuess = newGuess;

    newGuess = lastGuess - f(Pv, numPeriods, lastGuess, loanAmount) / derivative(Pv, numPeriods, lastGuess);
    System.out.println(newGuess);

    lastGuess = newGuess;

    newGuess = lastGuess - f(Pv, numPeriods, lastGuess, loanAmount) / derivative(Pv, numPeriods, lastGuess);
    System.out.println(newGuess);

    lastGuess = newGuess;

    newGuess = lastGuess - f(Pv, numPeriods, lastGuess, loanAmount) / derivative(Pv, numPeriods, lastGuess);
    System.out.println(newGuess);

}

private static double f(double Pv, int n, double lastGuess, double loanAmount)
{
    return lastGuess * Pv * Math.pow((1 + lastGuess), n) - loanAmount;
}

//---------------------------------------------------
private static double derivative(double Pv, int n, double lastGuess)
//---------------------------------------------------
{
    return (Pv * n * lastGuess) / (Math.pow((1 + lastGuess), n) * Math.pow(1 - (1 / (Math.pow((1 + lastGuess), n))), 2)) -
            Pv / (1 - Math.pow((1 + lastGuess), n));
}

Thanks in advance.

Morkus
  • 517
  • 7
  • 21
  • 1
    Did you try debugging via stepping or playing computer with pencil and paper? Caveat: this is not *my* method. I'm more closely related to Fig. – Dave Newton Jun 29 '19 at 13:54

1 Answers1

0

There are 3 changes that you will have to do.

For the first one, the function with the name f should be getting your the value for the finance amount, given the loan amount, lastGuess for the rate and the period and should be implemented in the following manner.

private static double f(double lastGuess, double loanAmount, int period)
{
    return lastGuess * loanAmount/(1- Math.pow((1 + lastGuess), -period));
}

Secondly, there is a much easier method to get the derivative at a location for a given function. That is by using the slope method. I am guessing you have implemented the equation for f'. Something of that sort can be difficult to debug.

private static double derivative(double lastGuess, int period, double loanAmount)
{
    return (f(lastGuess+0.01,loanAmount,period)-f(lastGuess,loanAmount,period))/0.01;
}

The equation for the next guess should be in the following format

newGuess = lastGuess + ((Pv-f(lastGuess, loanAmount,numPeriods)) / derivative(lastGuess, loanAmount,numPeriods));

Try this out. You will be amazed at how fast the system comes to a conclusion regarding the rate.

Beware, the Rate() function in excel, rounds the rate at the nearest Integer.

Nitro
  • 1,063
  • 1
  • 7
  • 17
  • A bit confused by your posting. I was trying to implement Newton's method: x1 = x0 - f(x0)/f'(x0). The way you calculate newGuess for example, doesn't fit the "-" in the equation above. Since using your code does not give me the expected result (Excel gets :0.592%), I must be typing it in incorrectly. Do you get 0.592%? Thanks. – Morkus Jun 29 '19 at 16:45
  • I just read your code, and you are right. In my code, I had multiplied the inverse derivative, effectively doing the same as you. Also, there was an issue with how the arguments were declared in the function declaration, and how the function was used. – Nitro Jun 29 '19 at 20:29
  • I was checking with my own set of inputs. It seems for the set of inputs that you have given PV=99000, LoanAmount=100000, period=360, I am getting the output as 0.99 for both my code and the excel sheet. – Nitro Jun 29 '19 at 20:33
  • .99 is not the correct result. You don't need the loan amount for this calculation (only to compute the payment). The correct APR result is 7.1%. I did re-work the code and found I made a mistake in computing the derivative. it's correct now. I appreciate your help and replies. :) Thank you. – Morkus Jun 30 '19 at 12:26