lib/xirr/bisection.rb in xirr-0.6.1 vs lib/xirr/bisection.rb in xirr-0.7.0

- old
+ new

@@ -1,37 +1,35 @@ # frozen_string_literal: true + module Xirr # Methods that will be included in Cashflow to calculate XIRR class Bisection include Base # Calculates yearly Internal Rate of Return # @return [BigDecimal] # @param midpoint [Float] # An initial guess rate will override the {Cashflow#irr_guess} def xirr(midpoint, options) - # Initial values - left = [BigDecimal(-0.99999999, Xirr::PRECISION), cf.irr_guess].min - right = [BigDecimal(9.99999999, Xirr::PRECISION), cf.irr_guess + 1].max + left = [BigDecimal(-0.99999999, Xirr.config.precision), cf.irr_guess].min + right = [BigDecimal(9.99999999, Xirr.config.precision), cf.irr_guess + 1].max @original_right = right midpoint ||= cf.irr_guess midpoint, runs = loop_rates(left, midpoint, right, options[:iteration_limit]) get_answer(midpoint, options, runs) - end - private # @param midpoint [BigDecimal] # @return [Boolean] # Checks if result is the right limit. def right_limit_reached?(midpoint) - (@original_right - midpoint).abs < Xirr::EPS + (@original_right - midpoint).abs < Xirr.config.eps end # @param left [BigDecimal] # @param midpoint [BigDecimal] # @param right [BigDecimal] @@ -52,35 +50,33 @@ # @param left [Float] # @param right [Float] # @return [Float] IRR of the Cashflow def format_irr(left, right) - irr = (right+left) / 2 + irr = (right + left) / 2 end def get_answer(midpoint, options, runs) if runs >= options[:iteration_limit] if options[:raise_exception] raise ArgumentError, "Did not converge after #{runs} tries." - else - nil end else - midpoint.round Xirr::PRECISION + midpoint.round Xirr.config.precision end end def loop_rates(left, midpoint, right, iteration_limit) runs = 0 - while (right - left).abs > Xirr::EPS && runs < iteration_limit do + while (right - left).abs > Xirr.config.eps && runs < iteration_limit do runs += 1 left, midpoint, right, should_stop = bisection(left, midpoint, right) break if should_stop if right_limit_reached?(midpoint) right *= 2 @original_right *= 2 end end - return midpoint, runs + [midpoint, runs] end end end