Sha256: 0c25d8dc323be56f8b316f7bf9c907ea0833b7072d358cb21611fdb59e0bdfc9

Contents?: true

Size: 1.53 KB

Versions: 1

Compression:

Stored size: 1.53 KB

Contents

# frozen_string_literal: true
require 'bigdecimal/newton'

module Xirr
  # Class to calculate IRR using Newton Method
  class NewtonMethod
    include Base
    include Newton


    # Base class for working with Newton's Method.
    # @api private
    class Function
      values = {
          eps: Xirr.config.eps,
          one:  '1.0',
          two:  '2.0',
          ten:  '10.0',
          zero: '0.0'
      }

      # define default values
      values.each do |key, value|
        define_method key do
          BigDecimal(value, Xirr.config.precision)
        end
      end

      # @param transactions [Cashflow]
      # @param function [Symbol]
      # Initializes the Function with the Cashflow it will use as data source and the function to reduce it.
      def initialize(transactions, function)
        @transactions = transactions
        @function = function
      end

      # Necessary for #nlsolve
      # @param x [BigDecimal]
      def values(x)
        value = @transactions.send(@function, BigDecimal(x[0].to_s, Xirr.config.precision))
        [BigDecimal(value.to_s, Xirr.config.precision)]
      end
    end

    # Calculates XIRR using Newton method
    # @return [BigDecimal]
    # @param guess [Float]
    def xirr(guess, _options)
      func = Function.new(self, :xnpv)
      rate = [guess || cf.irr_guess]
      begin
        nlsolve(func, rate)
        (rate[0] <= -1 || rate[0].nan?) ? nil : rate[0].round(Xirr.config.precision)

          # rate[0].round(Xirr.config.precision)
      rescue
        nil
      end
    end
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
xirr-0.7.0 lib/xirr/newton_method.rb