[QUIZ] Internal Rate of Return (#156)

R

Ruby Quiz

The three rules of Ruby Quiz:

1. Please do not post any solutions or spoiler discussion for this quiz until
48 hours have passed from the time on this message.

2. Support Ruby Quiz by submitting ideas as often as you can:

http://www.rubyquiz.com/

3. Enjoy!

Suggestion: A [QUIZ] in the subject of emails about the problem helps everyone
on Ruby Talk follow the discussion. Please reply to the original quiz message,
if you can.

-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

by Harrison Reiser

Internal Rate of Return (IRR –
http://en.wikipedia.org/wiki/Internal_rate_of_return) is a common financial
metric, used by investment firms to predict the profitability of a company or
project. Finding the IRR of a company amounts to solving for it in the equation
for Net Present Value (NPV – http://en.wikipedia.org/wiki/Net_present_value),
another valuable decision-making metric:

N C_t
NPV = Σ ------------
t=0 (1 + IRR)**t

This week's quiz is to calculate the IRR for any given variable-length list of
numbers, which represent yearly cash flows, the C_t's in the formula above: C_0,
C_1, etc. (C_0 is typically a negative value, corresponding to the initial
investment into the project.) From the example in the Wikipedia article
(http://en.wikipedia.org/wiki/Internal_rate_of_return), for instance, you should
be able to produce a rate of 17.09% (to four decimal places, let's say) from
this or a similar command:

irr([-100,+30,+35,+40,+45])
=> 0.1709...

Keep in mind that an IRR greater than 100% is possible. Extra credit if you can
also correctly handle input that produces negative rates, disregarding the fact
that they make no sense.
 
M

Matthew Moss

Internal Rate of Return (IRR -http://en.wikipedia.org/wiki/Internal_rate_o=
f_return) is a common financial
metric, used by investment firms to predict the profitability of a company= or
project. Finding the IRR of a company amounts to solving for it in the equ= ation
for Net Present Value (NPV -http://en.wikipedia.org/wiki/Net_present_value= ),
another valuable decision-making metric:

N C_t
NPV =3D =D3 ------------
t=3D0 (1 + IRR)**t

This week's quiz is to calculate the IRR for any given variable-length lis= t of
numbers, which represent yearly cash flows, the C_t's in the formula above= : C_0,
C_1, etc. (C_0 is typically a negative value, corresponding to the initial=
investment into the project.) From the example in the Wikipedia article
(http://en.wikipedia.org/wiki/Internal_rate_of_return), for instance, you = should
be able to produce a rate of 17.09% (to four decimal places, let's say) fr= om
this or a similar command:

irr([-100,+30,+35,+40,+45])
=3D> 0.1709...


I think one point, which isn't brought out here and not well in the
wikipedia article either, is that given all of the C_t, you still have
two unknowns: IRR (which we are attempting to solve for) and NPV.

In this case, you want NPV set to zero in order to solve for IRR. Or
did I miss something?
 
J

James Gray

This must be a strange moment for you

Yes, it was odd to think as I launched the quiz this morning, this is
the last time I will do this.

I will miss it, for sure. I am glad to be stopping while it's still
going strong though; we all would have enjoyed it a lot less if I had
let it beat me down.
or maybe it is too early to say THANK YOU FOR ALL THE FISH ;), as
you still have a summary to do,

Well, I appreciate the thought anyway.
but I feel very strange by reading the "last Ruby Quiz".

I think of it more as James's last Ruby Quiz.

I'm switching sides. I'll be solving and occasionally contributing
now. I'm looking forward to that.

I'm sure the new team will take great care of the quiz. I have faith.

James Edward Gray II
 
P

Paolo Bonzini

I think one point, which isn't brought out here and not well in the
wikipedia article either, is that given all of the C_t, you still have
two unknowns: IRR (which we are attempting to solve for) and NPV.

In this case, you want NPV set to zero in order to solve for IRR. Or
did I miss something?

Yes. At least I get the right answer if the "irr" function solves for
NPV=0. :)

Paolo
 
H

Harrison Reiser

In this case, you want NPV set to zero in order to solve for IRR.  Or
did I miss something?

That's correct. I forgot to add that detail when I submitted the
question. Sorry!

Harrison Reiser
 
S

Siep Korteling

James said:
by Harrison Reiser (...)
This week's quiz is to calculate the IRR for any given variable-length
list of numbers, which represent yearly cash flows,

In real life, it's not yearly. IIR needs a time dimension.

irr([-100, a_date],[+30,another_date],[+35,yet_a _date])

James, I learned a LOT thanks to you.

regards,

Siep
 
A

Alex Shulgin

Keep in mind that an IRR greater than 100% is possible. Extra credit if you can
also correctly handle input that produces negative rates, disregarding the fact
that they make no sense.

Can we return 1/0.0 if NPV does not evaluate to 0 for a reasonably
large IRR?

irr([+100,+10,+10,+10])
=> Infinity


Many thanks to James for your great job as the Quizmaster! :)
 
T

ThoML

How should the following values be handeld? According to some info I
found somewhere, 0..2 should be considered illegal, which doesn't
quite match my computations though.

[-1.0, 1.0]
[-1000.0, 999.99]
[-1000.0, 999.0]
[0.0]
[]

Regards,
Thomas.
 
N

Natalie Klein

Yes, you want the NPV to be zero... so you really just have to solve =20
for IRR. Another good thing pointed out in the article which I wish =20
I'd read before trying to solve it generally is that you can't solve =20
it in general with a formula :p

2008/2/8 Matthew Moss said:
Internal Rate of Return (IRR = -http://en.wikipedia.org/wiki/Internal_rate_of_return)=20
is a common financial
metric, used by investment firms to predict the profitability of a =20=
company or
project. Finding the IRR of a company amounts to solving for it in =20=
the equation
for Net Present Value (NPV = -http://en.wikipedia.org/wiki/Net_present_value)=20
,
another valuable decision-making metric:

N C_t
NPV =3D =CE=A3 ------------
t=3D0 (1 + IRR)**t

This week's quiz is to calculate the IRR for any given variable-=20
length list of
numbers, which represent yearly cash flows, the C_t's in the =20
formula above: C_0,
C_1, etc. (C_0 is typically a negative value, corresponding to the =20=
initial
investment into the project.) =46rom the example in the Wikipedia =20=
article
(http://en.wikipedia.org/wiki/Internal_rate_of_return), for =20
instance, you should
be able to produce a rate of 17.09% (to four decimal places, let's =20=
say) from
this or a similar command:

irr([-100,+30,+35,+40,+45])
=3D> 0.1709...


I think one point, which isn't brought out here and not well in the
wikipedia article either, is that given all of the C_t, you still =20
have
two unknowns: IRR (which we are attempting to solve for) and NPV.

In this case, you want NPV set to zero in order to solve for IRR. Or
did I miss something?

Isn't IRR defined as the discount rate that results in an NPV of 0?
 
P

paolo.bonzini

How should the following values be handeld? According to some info I
found somewhere, 0..2 should be considered illegal, which doesn't
quite match my computations though.

[-1.0, 1.0]
0

[-1000.0, 999.99]
-0.00001

[-1000.0, 999.0]
-0.001

[0.0]

does not find a solution (mine returns nil)

division by zero. (nil after I add a begin..rescue..end :)

Paolo
 
B

bug

Keep in mind that an IRR greater than 100% is possible. Extra credit if you can
also correctly handle input that produces negative rates, disregarding the fact
that they make no sense.

Can we return 1/0.0 if NPV does not evaluate to 0 for a reasonably
large IRR?

irr([+100,+10,+10,+10])
=> Infinity

Many thanks to James for your great job as the Quizmaster! :)

Such cases have an undefined IRR, and thus the behavior is undefined.

Harrison Reiser
 
B

bug

How should the following values be handeld? According to some info I
found somewhere, 0..2 should be considered illegal, which doesn't
quite match my computations though.

[-1.0, 1.0]
[-1000.0, 999.99]
[-1000.0, 999.0]
[0.0]
[]

Regards,
Thomas.

Yes, (0..2) doesn't make any sense at all, nor does anything that has
an initial investment of $0. The IRR would be 0/0, which can be
anything, and so you may return anything (or throw an error) if the
first element is a 0. An input list of less than two elements is
similarly ambiguous. As for the others, they do in fact have real
IRRs:

[-1.0, 1.0] => 0.0%
[-1000.0, 999.99] => -0.0001%
[-1000.0, 999.0] => -0.01%

The first case is interesting, however, because you will not be able
to find an IRR of 0% exactly if you are using an iterative solution,
only approach it, depending on how many iterations you use. Also, the
formula does not allow -100% IRR, even though it may be possible.

Harrison Reiser
 
C

Christopher Dicely

How should the following values be handeld? According to some info I
found somewhere, 0..2 should be considered illegal, which doesn't
quite match my computations though.

[-1.0, 1.0]
0

[-1000.0, 999.99]
-0.00001

[-1000.0, 999.0]
-0.001

[0.0]

does not find a solution (mine returns nil)

Its a meaningless input anyway, but wouldn't any rate be a solution?
Since you are looking for the discount rate at which the NPV is 0, if
the only flow is an initial investment of 0, any discount rate will
produce an NPV of 0. (Mine produces 0 for this case.)

division by zero. (nil after I add a begin..rescue..end :)

I would think this would be equivalent to the preceding case and,
likewise, any discount rate you try would be a valid solution. (And,
again, mine produces 0 here.)
 
C

Christopher Dicely

How should the following values be handeld? According to some info I
found somewhere, 0..2 should be considered illegal, which doesn't
quite match my computations though.

[-1.0, 1.0]
[-1000.0, 999.99]
[-1000.0, 999.0]
[0.0]
[]

Regards,
Thomas.

Yes, (0..2) doesn't make any sense at all, nor does anything that has
an initial investment of $0. The IRR would be 0/0, which can be
anything, and so you may return anything (or throw an error) if the
first element is a 0. An input list of less than two elements is
similarly ambiguous. As for the others, they do in fact have real
IRRs:

[-1.0, 1.0] => 0.0%
[-1000.0, 999.99] => -0.0001%
[-1000.0, 999.0] => -0.01%

The first case is interesting, however, because you will not be able
to find an IRR of 0% exactly if you are using an iterative solution,
only approach it, depending on how many iterations you use.

Is that really a special result of the first case? It seems to me any
iterative method is likely to only approximate any result except for
the one used as the initial starting point (of course, if zero is the
initial starting point, then it can get zero exactly).
 
B

bug

James said:
by Harrison Reiser (...)
This week's quiz is to calculate the IRR for any given variable-length
list of numbers, which represent yearly cash flows,

In real life, it's not yearly. IIR needs a time dimension.

irr([-100, a_date],[+30,another_date],[+35,yet_a _date])

James, I learned a LOT thanks to you.

regards,

Siep

I was hoping someone would try this! It wouldn't be very difficult to
adapt an existing yearly algorithm to do it; all that changes is the
exponent for each term. I'd take only two arguments, though: the
starting date and {dates => cash flows}.

Harrison Reiser
 
B

bug

Is that really a special result of the first case? It seems to me any
iterative method is likely to only approximate any result except for
the one used as the initial starting point (of course, if zero is the
initial starting point, then it can get zero exactly).

Heheh, dur...I'm fairly new to iterative solutions. Pardon my
naiveness.
 
T

ThoML

irr([+100,+10,+10,+10])
Such cases have an undefined IRR, and thus the behavior is undefined.

I assume IRR=-1.4228295850 -> -2.8421709430404e-14 wouldn't qualify as
a solution?
 
A

Alex Shulgin

Can we return 1/0.0 if NPV does not evaluate to 0 for a reasonably
large IRR?

irr([+100,+10,+10,+10])
=> Infinity

Such cases have an undefined IRR, and thus the behavior is undefined.

Is it OK to format user's hard drive then? ;-)
 
T

ThoML

I assume IRR=-1.4228295850 -> -2.8421709430404e-14 wouldn't qualify as
Ah... nice catch! :)

In the meantime I read HR's post that the function isn't defined for
-100%. I'd assume it isn't defined for any values < -0.999999... As it
was previously stated, negative values probably are difficult to
interpret anyway. It seems in practice people use certain deprecation
rules in order to exclude such values.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,819
Latest member
masterdaster

Latest Threads

Top