2

You'll have to be easy on me, I am new to matlab and SO. I am having an issue using the matlab solver to calculate internal rate of return(IRR). I saw that the financial toolbox in matlab had a function for this, however I don't believe I have it installed and did not want to get the trial version on their site.

Given the simple nature of my particular IRR calculation, I figured it would be easy enough to simply code in matlab. It is the same yearly cashflow, so what I put into matlab was as follows:

syms x k;
IRR = solve(investment == yrSavings* symsum((1+x)^-k,1, nYears));

It doesn't fail, and in fact gives a number. The only problem is the the result is incorrect! I type in the IRR manually and it never equals the investment. Using wolframalpha I found the actual solution, went back and manually typed in wolframalpha's answer, and the symsum function returned the correct result. I'm not sure what's up with the solver!

PearsonArtPhoto
  • 38,970
  • 17
  • 111
  • 142
Sooji
  • 23
  • 5

2 Answers2

2

The way you have the formula written, the symbolic assumption is that you are using x as the iterator variable. I believe you want to use k. Try this:

syms x k;
IRR = solve(investment == yrSavings* symsum((1+x)^-k,k,1, nYears));
PearsonArtPhoto
  • 38,970
  • 17
  • 111
  • 142
0

Another approach would be to use the MATLAB function roots to compute the discount factor and then convert that to an IRR. I happened to write such a function the other day, so I thought I might as well post it here for reference. It is heavily commented but the actual code is only three lines.

% 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