Skip to content

Commit 1da4b08

Browse files
grin0cjalateras
authored andcommitted
Fix formula RATE.
1 parent d0fb82a commit 1da4b08

File tree

1 file changed

+20
-30
lines changed

1 file changed

+20
-30
lines changed

lib/financial.js

Lines changed: 20 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -798,40 +798,30 @@ exports.RATE = function(periods, payment, present, future, type, guess) {
798798
}
799799

800800
// Set maximum epsilon for end of iteration
801-
var epsMax = 1e-10;
801+
var epsMax = 1e-6;
802802

803803
// Set maximum number of iterations
804-
var iterMax = 50;
805-
806-
// Implement Newton's method
807-
var y, y0, y1, x0, x1 = 0,
808-
f = 0,
809-
i = 0;
804+
var iterMax = 100;
805+
var iter = 0;
806+
var close = false;
810807
var rate = guess;
811-
if (Math.abs(rate) < epsMax) {
812-
y = present * (1 + periods * rate) + payment * (1 + rate * type) * periods + future;
813-
} else {
814-
f = Math.exp(periods * Math.log(1 + rate));
815-
y = present * f + payment * (1 / rate + type) * (f - 1) + future;
816-
}
817-
y0 = present + payment * periods + future;
818-
y1 = present * f + payment * (1 / rate + type) * (f - 1) + future;
819-
i = x0 = 0;
820-
x1 = rate;
821-
while ((Math.abs(y0 - y1) > epsMax) && (i < iterMax)) {
822-
rate = (y1 * x0 - y0 * x1) / (y1 - y0);
823-
x0 = x1;
824-
x1 = rate;
825-
if (Math.abs(rate) < epsMax) {
826-
y = present * (1 + periods * rate) + payment * (1 + rate * type) * periods + future;
827-
} else {
828-
f = Math.exp(periods * Math.log(1 + rate));
829-
y = present * f + payment * (1 / rate + type) * (f - 1) + future;
830-
}
831-
y0 = y1;
832-
y1 = y;
833-
++i;
808+
809+
while (iter < iterMax && !close) {
810+
var t1 = Math.pow(rate + 1, periods);
811+
var t2 = Math.pow(rate + 1, periods - 1);
812+
813+
var f1 = future + t1 * present + payment * (t1 - 1) * (rate * type + 1) / rate;
814+
var f2 = periods * t2 * present - payment * (t1 - 1) *(rate * type + 1) / Math.pow(rate,2);
815+
var f3 = periods * payment * t2 * (rate * type + 1) / rate + payment * (t1 - 1) * type / rate;
816+
817+
var newRate = rate - f1 / (f2 + f3);
818+
819+
if (Math.abs(newRate - rate) < epsMax) close = true;
820+
iter++
821+
rate = newRate;
834822
}
823+
824+
if (!close) return Number.NaN + rate;
835825
return rate;
836826
};
837827

0 commit comments

Comments
 (0)