另一种方法是使用 MATLAB 函数roots
计算折扣因子,然后将其转换为 IRR。前几天碰巧写了这样一个函数,所以我想我不妨把它贴在这里以供参考。它被大量注释,但实际代码只有三行。
% Compute the IRR of a stream of cashflows represented as a vector. For example:
% > irr([-123400, 36200, 54800, 48100])
% ans = 0.059616
%
% If the provided stream of cashflows starts with a negative cashflow and all
% other cashflows are positive then `irr` will return a single scalar result.
%
% If multiple IRRs exist, all possible IRRs are returned as a column vector. For
% example:
% > irr([-1.0, 1.0, 1.1, 1.3, 1.0, -3.7])
% ans =
% 0.050699
% 0.824254
%
% If no IRRs exist, or if infinitely many IRRs exist, an empty array is
% returned. For example:
% > irr([1.0, 2.0, 3.0])
% ans = [](0x1)
%
% > irr([0.0])
% ans = [](0x1)
%
% Unlike Excel's IRR function no initial guess can be provided because all
% possible IRRs are returned anyway
%
% This function is not vectorized and will fail if called with a matrix argument
function irrs = irr(cashflows)
%% Overview
% The IRR is defined as the rate, r, such that:
%
% c0 + c1 / (1 + r) + c2 / (1 + r) ^ 2 + ... + cn / (1 + r) ^ n = 0
%
% where c0, c1, c2, ..., cn are the cashflows
%
% We define discount factors, d = 1 / (1 + r), so that the above becomes a
% polynomial in terms of the discount factors:
%
% c0 + c1 * d + c2 * d^2 + ... + cn * d^n = 0
%
% Such a polynomial will have n complex roots but between 0 and n real roots.
% In the important special case that c0 < 0 and c1, c2, ..., cn > 0 there
% will be exactly one real root.
%% Check that input is a vector, not a matrix
assert(isvector(cashflows), 'Input to irr must be a vector of cashflows');
%% Calculation of IRRs
% We use the built-in functions `roots` to compute all roots of the
% polynomial, which are the discount factors `d`. The user will provide a
% vector as [c0, c1, c2, ..., cn] but roots expects something of the form
% [cn, ..., c2, c2, c0] so we reverse the order of cashflows using (end:-1:1).
% At this stage `d` has n elements, most of which are likely complex.
d = roots(cashflows(end:-1:1));
% The function `roots` provides all roots, including complex ones. We are only
% interested in the real roots, so we filter out the complex roots here. There
% many also be spurious real roots less or equal to 0, which we also filter
% out. Now `rd` could have between 0 and n elements but is likely to have a
% single element
rd = d(imag(d) == 0.0 & real(d) > 0);
% We have solved everything in terms of discount factors, so we convert to
% rates by inverting the defining formula. Since the discount factors are
% real and positive, the IRRs are real and greater than -100%.
irrs = 1.0 ./ rd - 1.0;
end