lib/exonio/financial.rb in exonio-0.3.0 vs lib/exonio/financial.rb in exonio-0.4.0
- old
+ new
@@ -109,7 +109,50 @@
temp = (1 + rate) ** nper
fact = (1 + rate * end_or_beginning) * (temp - 1) / rate
-(fv + pmt * fact) / temp
end
+
+ # Calculates the interest rate of an annuity investment based on
+ # constant-amount periodic payments and the assumption of a constant interest rate.
+ #
+ # @param nper [Integer] The number of payments to be made (number of periods)
+ # @param pmt [Float] The amount per period to be paid
+ # @param pv [Float] The present value
+ # @param fv [Float] The future value remaining after the final payment has been made
+ # @param end_or_begining [Integer] Whether payments are due at the end (0) or
+ # beggining (1) of each period
+ # @param rate_guess [Float] An estimate for what the interest rate will be
+ #
+ # @return [Float]
+ #
+ # @example
+ # Exonio.rate(12, 363.78, -3056.00) # ==> 0.05963422268883278
+ #
+ def rate(nper, pmt, pv, fv = 0, end_or_beginning = 0, rate_guess = 0.10)
+ guess = rate_guess
+ tolerancy = 1e-6
+ close = false
+
+ begin
+ temp = newton_iter(guess, nper, pmt, pv, fv, end_or_beginning)
+ next_guess = guess - temp
+ diff = (next_guess - guess).abs
+ close = diff < tolerancy
+ guess = next_guess
+ end while !close
+
+ next_guess
+ end
+
+ private
+
+ # This method was borrowed from the NumPy rate formula
+ # which was generated by Sage
+ #
+ def newton_iter(r, n, p, x, y, w)
+ t1 = (r+1)**n
+ t2 = (r+1)**(n-1)
+ ((y + t1*x + p*(t1 - 1)*(r*w + 1)/r) / (n*t2*x - p*(t1 - 1)*(r*w + 1)/(r**2) + n*p*t2*(r*w + 1)/r + p*(t1 - 1)*w/r))
+ end
end
end