Created
August 2, 2022 06:28
-
-
Save 1FahadShakeel/2ca9e61efc604ded5336b959d7ea4baf to your computer and use it in GitHub Desktop.
The excel RATE() function in Javascript
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var RATE = function(nper, pmt, pv, fv, type, guess) { | |
// Sets default values for missing parameters | |
fv = typeof fv !== 'undefined' ? fv : 0; | |
type = typeof type !== 'undefined' ? type : 0; | |
guess = typeof guess !== 'undefined' ? guess : 0.1; | |
// Sets the limits for possible guesses to any | |
// number between 0% and 100% | |
var lowLimit = 0; | |
var highLimit = 1; | |
// Defines a tolerance of up to +/- 0.00005% of pmt, to accept | |
// the solution as valid. | |
var tolerance = Math.abs(0.00000005 * pmt); | |
// Tries at most 40 times to find a solution within the tolerance. | |
for (var i = 0; i < 40; i++) { | |
// Resets the balance to the original pv. | |
var balance = pv; | |
// Calculates the balance at the end of the loan, based | |
// on loan conditions. | |
for (var j = 0; j < nper; j++ ) { | |
if (type == 0) { | |
// Interests applied before payment | |
balance = balance * (1 + guess) + pmt; | |
} else { | |
// Payments applied before insterests | |
balance = (balance + pmt) * (1 + guess); | |
} | |
} | |
// Returns the guess if balance is within tolerance. If not, adjusts | |
// the limits and starts with a new guess. | |
if (Math.abs(balance + fv) < tolerance) { | |
return guess; | |
} else if (balance + fv > 0) { | |
// Sets a new highLimit knowing that | |
// the current guess was too big. | |
highLimit = guess; | |
} else { | |
// Sets a new lowLimit knowing that | |
// the current guess was too small. | |
lowLimit = guess; | |
} | |
// Calculates the new guess. | |
guess = (highLimit + lowLimit) / 2; | |
} | |
// Returns null if no acceptable result was found after 40 tries. | |
return null; | |
}; |
the result is always null for me, i already set the times to find a solution for a higher number. Can you help?
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@1FahadShakeel ... thanks for providing this! It takes a much simpler, more straightforward approach to the RATE function than the Newton-Raphson approach I saw elsewhere... on which I noticed your comment and thus found my way here. :-)
However, I also found a couple of cases where your code fails to produce the correct value:
pv<0
andpmt>0
(Excel's RATE works in both cases)I fixed these problems by inserting the following at line 15:
... and then changing line 37 (the else if) to...
Sorry for the somewhat-ugly hack, but it now passes all my test cases. :-P Thanks again for providing this code!
P.S. Edited to add comments in my code snippet :-)