Class: Xirr::Cashflow
- Inherits:
-
Array
- Object
- Array
- Xirr::Cashflow
- Defined in:
- lib/xirr/cashflow.rb
Overview
A Cashflow should consist of at least two transactions, one positive and one negative.
Expands [Array] to store a set of transactions which will be used to calculate the XIRR
Instance Attribute Summary collapse
-
#fallback ⇒ Object
readonly
Returns the value of attribute fallback.
-
#iteration_limit ⇒ Object
readonly
Returns the value of attribute iteration_limit.
-
#options ⇒ Object
readonly
Returns the value of attribute options.
-
#raise_exception ⇒ Object
readonly
Returns the value of attribute raise_exception.
Instance Method Summary collapse
- #<<(arg) ⇒ Object
- #compact_cf ⇒ Object
-
#initialize(flow: [], period: Xirr::PERIOD, **options) ⇒ Cashflow
constructor
A new instance of Cashflow.
-
#invalid? ⇒ Boolean
Check if Cashflow is invalid.
-
#invalid_message ⇒ String
Error message depending on the missing transaction.
-
#irr_guess ⇒ Float
Calculates a simple IRR guess based on period of investment and multiples.
-
#max_date ⇒ Time
Last investment date.
-
#min_date ⇒ Time
First investment date.
- #other_calculation_method(method) ⇒ Object
- #period ⇒ Object
- #process_options(method, options) ⇒ Object
-
#sum ⇒ Float
Sums all amounts in a cashflow.
-
#switch_fallback(method) ⇒ Symbol
If method is defined it will turn off fallback it return either the provided method or the system default.
-
#valid? ⇒ Boolean
Inverse of #invalid?.
- #xirr(guess: nil, method: nil, **options) ⇒ Float
Constructor Details
#initialize(flow: [], period: Xirr::PERIOD, **options) ⇒ Cashflow
Returns a new instance of Cashflow.
15 16 17 18 19 20 21 |
# File 'lib/xirr/cashflow.rb', line 15 def initialize(flow: [], period: Xirr::PERIOD, ** ) @period = period @fallback = [:fallback] || Xirr::FALLBACK @options = self << flow self.flatten! end |
Instance Attribute Details
#fallback ⇒ Object (readonly)
Returns the value of attribute fallback.
6 7 8 |
# File 'lib/xirr/cashflow.rb', line 6 def fallback @fallback end |
#iteration_limit ⇒ Object (readonly)
Returns the value of attribute iteration_limit.
6 7 8 |
# File 'lib/xirr/cashflow.rb', line 6 def iteration_limit @iteration_limit end |
#options ⇒ Object (readonly)
Returns the value of attribute options.
6 7 8 |
# File 'lib/xirr/cashflow.rb', line 6 def @options end |
#raise_exception ⇒ Object (readonly)
Returns the value of attribute raise_exception.
6 7 8 |
# File 'lib/xirr/cashflow.rb', line 6 def raise_exception @raise_exception end |
Instance Method Details
#<<(arg) ⇒ Object
119 120 121 122 123 |
# File 'lib/xirr/cashflow.rb', line 119 def << arg super arg self.sort! { |x, y| x.date <=> y.date } self end |
#compact_cf ⇒ Object
95 96 97 98 99 100 |
# File 'lib/xirr/cashflow.rb', line 95 def compact_cf # self compact = Hash.new 0 self.each { |flow| compact[flow.date] += flow.amount } Cashflow.new flow: compact.map { |key, value| Transaction.new(value, date: key) }, options: , period: period end |
#invalid? ⇒ Boolean
Check if Cashflow is invalid
25 26 27 |
# File 'lib/xirr/cashflow.rb', line 25 def invalid? inflow.empty? || outflows.empty? end |
#invalid_message ⇒ String
Error message depending on the missing transaction
110 111 112 113 |
# File 'lib/xirr/cashflow.rb', line 110 def return 'No positive transaction' if inflow.empty? return 'No negative transaction' if outflows.empty? end |
#irr_guess ⇒ Float
Calculates a simple IRR guess based on period of investment and multiples.
49 50 51 52 53 |
# File 'lib/xirr/cashflow.rb', line 49 def irr_guess return @irr_guess = 0.0 if periods_of_investment.zero? @irr_guess = valid? ? ((multiple ** (1 / periods_of_investment)) - 1).round(3) : false @irr_guess == 1.0/0 ? 0.0 : @irr_guess end |
#max_date ⇒ Time
Last investment date
43 44 45 |
# File 'lib/xirr/cashflow.rb', line 43 def max_date @max_date ||= self.map(&:date).max end |
#min_date ⇒ Time
First investment date
104 105 106 |
# File 'lib/xirr/cashflow.rb', line 104 def min_date @min_date ||= self.map(&:date).min end |
#other_calculation_method(method) ⇒ Object
91 92 93 |
# File 'lib/xirr/cashflow.rb', line 91 def other_calculation_method(method) method == :newton_method ? :bisection : :newton_method end |
#period ⇒ Object
115 116 117 |
# File 'lib/xirr/cashflow.rb', line 115 def period @temporary_period || @period end |
#process_options(method, options) ⇒ Object
70 71 72 73 74 75 |
# File 'lib/xirr/cashflow.rb', line 70 def (method, ) @temporary_period = [:period] [:raise_exception] ||= @options[:raise_exception] || Xirr::RAISE_EXCEPTION [:iteration_limit] ||= @options[:iteration_limit] || Xirr::ITERATION_LIMIT return switch_fallback(method), end |
#sum ⇒ Float
Sums all amounts in a cashflow
37 38 39 |
# File 'lib/xirr/cashflow.rb', line 37 def sum self.map(&:amount).sum end |
#switch_fallback(method) ⇒ Symbol
If method is defined it will turn off fallback it return either the provided method or the system default
81 82 83 84 85 86 87 88 89 |
# File 'lib/xirr/cashflow.rb', line 81 def switch_fallback method if method @fallback = false method else @fallback = Xirr::FALLBACK Xirr::DEFAULT_METHOD end end |
#valid? ⇒ Boolean
Inverse of #invalid?
31 32 33 |
# File 'lib/xirr/cashflow.rb', line 31 def valid? !invalid? end |
#xirr(guess: nil, method: nil, **options) ⇒ Float
58 59 60 61 62 63 64 65 66 67 68 |
# File 'lib/xirr/cashflow.rb', line 58 def xirr(guess: nil, method: nil, ** ) method, = (method, ) if invalid? raise ArgumentError, if [:raise_exception] BigDecimal(0, Xirr::PRECISION) else xirr = choose_(method).send :xirr, guess, xirr = choose_(other_calculation_method(method)).send(:xirr, guess, ) if (xirr.nil? || xirr.nan?) && fallback xirr || Xirr::REPLACE_FOR_NIL end end |