Module: Xirr Abstract
- Includes:
- ActiveSupport::Configurable
- Defined in:
- lib/xirr.rb,
lib/xirr/tvm.rb,
lib/xirr/base.rb,
lib/xirr/bonds.rb,
lib/xirr/brent.rb,
lib/xirr/rates.rb,
lib/xirr/config.rb,
lib/xirr/rtsafe.rb,
lib/xirr/returns.rb,
lib/xirr/version.rb,
lib/xirr/cashflow.rb,
lib/xirr/periodic.rb,
lib/xirr/rtsafe_c.rb,
lib/xirr/bisection.rb,
lib/xirr/transaction.rb,
lib/xirr/depreciation.rb,
lib/xirr/newton_method.rb,
ext/xirr/xirr_native.c
Overview
adds a Cashflow and Transaction classes to calculate IRR of irregular transactions.
Calculates Xirr
Defined Under Namespace
Modules: Base, Bonds, Depreciation, Native, Rates, Returns, TVM Classes: Bisection, Brent, Cashflow, NewtonMethod, RtSafe, RtSafeC, Transaction
Constant Summary collapse
- VERSION =
Version of the Gem
'1.0.0'
Class Method Summary collapse
-
.irr(amounts, guess: 0.1) ⇒ Float
Internal rate of return of
amountsat periods 0, 1, 2, …. -
.mirr(amounts, finance_rate, reinvest_rate) ⇒ Float
Modified internal rate of return of periodic
amounts. -
.npv(rate, amounts) ⇒ Float
Net present value of
amountsat periods 0, 1, 2, … discounted atrate.
Class Method Details
.irr(amounts, guess: 0.1) ⇒ Float
19 20 21 22 23 24 |
# File 'lib/xirr/periodic.rb', line 19 def irr(amounts, guess: 0.1) flows = validated_flows(amounts) rate = RtSafe.find(flows, guess: guess) raise ArgumentError, 'IRR did not converge' if rate.nil? rate end |
.mirr(amounts, finance_rate, reinvest_rate) ⇒ Float
Modified internal rate of return of periodic amounts. Positive flows are
assumed reinvested at reinvest_rate, negative flows financed at
finance_rate.
Xirr.mirr([-120_000, 39_000, 30_000, 21_000, 37_000, 46_000], 0.10, 0.12)
# => 0.126094
54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/xirr/periodic.rb', line 54 def mirr(amounts, finance_rate, reinvest_rate) values = validated_amounts(amounts) periods = values.length - 1 future_of_inflows = values.each_with_index.inject(0.0) do |acc, (value, i)| value > 0 ? acc + value * (1.0 + reinvest_rate) ** (periods - i) : acc end present_of_outflows = values.each_with_index.inject(0.0) do |acc, (value, i)| value < 0 ? acc + value / (1.0 + finance_rate) ** i : acc end ((future_of_inflows / -present_of_outflows) ** (1.0 / periods) - 1).round(Xirr.config.precision) end |
.npv(rate, amounts) ⇒ Float
Net present value of amounts at periods 0, 1, 2, … discounted at rate.
The first amount sits at period 0 and is left undiscounted, so
Xirr.npv(Xirr.irr(a), a) comes out to roughly zero. This differs from a
spreadsheet NPV, which places the first amount at period 1.
Xirr.npv(0.1, [-1000, 1100]) # => 0.0
Xirr.npv(0.1, [-1000, 600, 600]) # => 41.322314
37 38 39 40 41 |
# File 'lib/xirr/periodic.rb', line 37 def npv(rate, amounts) amounts.each_with_index.inject(0.0) do |sum, (amount, i)| sum + amount.to_f / (1.0 + rate) ** i end.round(Xirr.config.precision) end |