@@ -798,40 +798,30 @@ exports.RATE = function(periods, payment, present, future, type, guess) {
798
798
}
799
799
800
800
// Set maximum epsilon for end of iteration
801
- var epsMax = 1e-10 ;
801
+ var epsMax = 1e-6 ;
802
802
803
803
// 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 ;
810
807
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 ;
834
822
}
823
+
824
+ if ( ! close ) return Number . NaN + rate ;
835
825
return rate ;
836
826
} ;
837
827
0 commit comments