Computes the internal rate of return (IRR) of a cash flow by finding the annual effective rate that makes its present value equal to zero, using compact actuarial notation.
Arguments
- cf
Numeric vector of cash flows.
- t
Optional numeric vector of cash-flow times in years.
- date
Optional vector of cash-flow dates. If supplied, the earliest date is treated as time 0.
- m
Positive integer used only to report an equivalent nominal annual interest rate convertible
mtimes per year.- interval
Numeric vector of length 2 giving the search interval for the annual effective IRR. Default is
c(-0.99, 10).- tol
Numeric tolerance passed to
uniroot.- maxiter
Maximum number of iterations passed to
uniroot.- day_count
Day-count convention used when
dateis supplied. One of"act/365"or"act/360".
Value
A one-row tibble with:
- irr
Estimated IRR as an annual effective rate.
- i_effective_annual
Same as
irr, reported explicitly.- j_nominal_interest
Equivalent nominal annual interest rate convertible
mtimes.- delta
Equivalent force of interest.
- npv
Present value at the estimated IRR, close to zero.
- interval_left
Left endpoint of the search interval.
- interval_right
Right endpoint of the search interval.
- converged
Logical flag indicating whether a root was found.
- n_iter
Number of iterations used by
uniroot.- n_cashflows
Length of
cf.- has_both_signs
Whether the cash flow has at least one positive and one negative value.
- n_sign_changes
Number of sign changes in the nonzero cash-flow sequence.
If no sign change is present in the cash flow, or if the NPV does not change
sign over interval, the function returns converged = FALSE and
irr = NA_real_.
Details
The cash flow is supplied explicitly through cf. Its timing is given
either through t (in years) or date (calendar dates). If
date is supplied, the earliest date is treated as time 0.
The IRR returned is interpreted as an annual effective rate.
Root finding scales the cash flows by their largest absolute amount; this preserves roots across monetary units. The reported NPV remains in the original currency. Scaling that would erase a nonzero amount through underflow is rejected. The tolerance controls the rate-coordinate solve.
This function follows the compact actuarial notation used throughout
tidyactuarial: cf denotes cash flows, t denotes time,
and m denotes the conversion frequency used to report the equivalent
nominal annual interest rate.
The IRR is defined as the rate \(r\) satisfying $$\sum_{k} C_k (1+r)^{-t_k} = 0$$ where \(C_k\) are the cash flows and \(t_k\) the corresponding times in years.
The root is found using uniroot over the specified
interval. If the NPV does not change sign over the interval, no root
can be bracketed and the function returns gracefully with
converged = FALSE.
The number of sign changes in the nonzero cash-flow sequence is reported as a diagnostic. If there is exactly one sign change, the IRR is usually unique under the usual ordered cash-flow setting.
Examples
irr_flow(
cf = c(-1000, 300, 400, 500),
t = c(0, 1, 2, 3)
)
#> # A tibble: 1 × 12
#> irr i_effective_annual j_nominal_interest delta npv interval_left
#> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 0.0890 0.0890 0.0890 0.0852 1.07e-10 -0.99
#> # ℹ 6 more variables: interval_right <dbl>, converged <lgl>, n_iter <int>,
#> # n_cashflows <int>, has_both_signs <lgl>, n_sign_changes <int>
irr_flow(
cf = c(-1000, 300, 400, 500),
date = as.Date(c("2026-01-01", "2027-01-01", "2028-01-01", "2029-01-01"))
)
#> # A tibble: 1 × 12
#> irr i_effective_annual j_nominal_interest delta npv interval_left
#> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 0.0889 0.0889 0.0889 0.0852 1.08e-10 -0.99
#> # ℹ 6 more variables: interval_right <dbl>, converged <lgl>, n_iter <int>,
#> # n_cashflows <int>, has_both_signs <lgl>, n_sign_changes <int>