Computes the Macaulay or modified duration of a general cash-flow stream at a specified valuation time.
Arguments
- cf
Numeric vector of cash-flow amounts.
- t
Numeric vector of cash-flow times. Times must be expressed in the same units used by `rate`.
- rate
Effective yield per unit of time. It must be a finite numeric scalar greater than `-1`.
- valuation_time
Finite numeric scalar indicating the valuation time. Defaults to `0`.
- duration
Character scalar indicating the duration measure: `"macaulay"` or `"modified"`.
- output
Character scalar indicating the returned object: `"value"` returns the selected duration as a numeric scalar; `"audit"` returns a detailed tibble.
Value
If `output = "value"`, a numeric scalar.
If `output = "audit"`, a tibble with six columns: `time`, `remaining_time`, `cash_flow`, `discount_factor`, `present_value`, and `duration_contribution`.
Details
Let \(\tau\) be the valuation time. Under an effective yield \(i\), the value of the remaining cash-flow stream is
$$ P_{\tau} = \sum_{j:t_j>\tau} C_j(1+i)^{-(t_j-\tau)}. $$
The Macaulay duration measured from \(\tau\) is
$$ D_{\mathrm{Mac},\tau} = \frac{ \sum_{j:t_j>\tau} (t_j-\tau)C_j(1+i)^{-(t_j-\tau)} }{ P_{\tau} }. $$
The modified duration with respect to the effective yield is
$$ D_{\mathrm{mod},\tau} = \frac{D_{\mathrm{Mac},\tau}}{1+i}. $$
The function follows an ex-cash-flow convention: cash flows occurring exactly at `valuation_time` are excluded. Therefore, the result represents duration immediately after any cash flow paid at that time.
For streams containing both positive and negative cash flows, duration remains a yield-sensitivity measure, but it may not have the usual interpretation as a weighted-average payment time. Relative contributions are computed without first forming a monetary duration numerator. Representable products can be recovered when a standalone discount factor underflows; its audit column can then be zero while present value is positive. Discount factors, present values, their total/absolute sum, and the selected contributions/result must remain finite. A signed stream is rejected when absolute total value is at most `sqrt(.Machine$double.eps)` times the sum of absolute present values.
Examples
duration_cash_flow(
cf = c(100, 100, 1100),
t = c(1, 2, 3),
rate = 0.05
)
#> [1] 2.752519
duration_cash_flow(
cf = c(100, 100, 1100),
t = c(1, 2, 3),
rate = 0.05,
duration = "modified"
)
#> [1] 2.621446
duration_cash_flow(
cf = c(100, 100, 1100),
t = c(1, 2, 3),
rate = 0.05,
valuation_time = 1,
output = "audit"
)
#> # A tibble: 2 × 6
#> time remaining_time cash_flow discount_factor present_value
#> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 2 1 100 0.952 95.2
#> 2 3 2 1100 0.907 998.
#> # ℹ 1 more variable: duration_contribution <dbl>