Fifty Shades of J/Chapter 49

From J Wiki
Jump to navigation Jump to search

Table of Contents ... Glossary ... Previous Chapter ... Next Chapter

Financial Maths and J – part 1, IRR and APR

Principal Topics

IRR (Internal rate of return), income stream. NPV (net present value), APR (annualized percentage rate)

A common way of assessing the profitability or otherwise of an investment is through the rate of return. There are several ways in which ‘rate of return’ can be calculated, one of the most common being Internal Rate of Return (IRR). Computing IRRs for different income streams is a way of comparing different investment strategies, e.g. when a company makes choices about which of a variety of potential products to develop. Moreover IRR carries on increasing with length of input stream provided inflows are positive, and so it may make sense to abandon further product development when the IRR begins to tail off.


The phenomenon of 5% compound interest growth can be described equivalently by any one of four numbers namely 5, 0.05, 1.05 and (1.05)-1. These differences are expressible in J terms as :

p=.percentage rate                        (p>_100)
r=.fractional rate  so r=.0.01*p          (r>_1)
k=.multiplication factor so  k=.>:r       (k>0) factor so d=.%k or %>:0.01*p  (d>0)

All of these forms are equivalent ways of describing the same underlying phenomenon, so it is immaterial which value is quoted provided that the intend form is clear. Conversions between the various quantities are given by


Negative growth, that is decay, is indicated by p<0, r<0, k<1 and d>1.


The significance of ‘internal’ is that the final worth of an income stream after discounting IRR is equal to zero. In other words ultimate worth is neither increased nor decreased so that IRR can be viewed as the continuous money decline which would need to occur to make the overall project do no more than break even in real terms. If the actual rate of money decline exceeds the IRR, then it would have been better not to have undertaken the project. IRRs should in general be used in a relative sense to compare alternatives, rather than as absolute measures - the higher the IRR of a project alternative, the more flexibility there is for its success compared with other proposals. For valid comparisons, project proposals should have approximately the same initial outlays and the same income stream lengths. If these conditions are not met further considerations concerning investment of surplus and realised funds need to be taken into account.

Computing IRRs

Obtaining values for IRRs means solving polynomial equations for which income streams provide the coefficients.

   is=._100 20 50 70 80        NB. an income stream
│80│_1.21963 _0.20558j1.14621 _0.20558j_1.14621 0.755789│

A d value of 0.75579 is extracted and converted to p form by

   dtop 0.75579

to obtain an IRR of 32.3%. In words IRR is calculated as ‘convert to p form the positive real root of the income stream regarded as polynomial coefficients’.

The final worth of the income stream can be obtained by using the d value as left input to the polynomial evaluator #. Notice that the coefficients in the argument for p. are in ascending power order, while those for are in descending order, so that the value of 0.75579 is confirmed by

   0.75579 #.|.is
0.00046177            NB. effectively zero

It is always nice to have a simple case confirmed, so using the first example above

   p. _100 0 0 200
│200│0.793701 _0.39685j0.687365 _0.39685j_0.687365│

from which 0.7937 leads to a compound interest growth of 26%

   dtop 0.7937

d values are obtained by opening the second box resulting from p. :

   roots=.>@{:@p.         NB. extract list of roots

and obtaining the single non-negative, non-complex value, the latter property being tested for by comparison with conjugates as provided by + applied to complex numbers. From tally it is one small step to #~ as shorthand for 'select', which leads to two further building blocks

   real=.#~ (= +)        NB. select real values
   pos=.#~ >&0        NB. select positive values

The process of obtaining the internal rate of return then consists of four steps in sequence :

   irr=.dtop@pos@real@roots    NB. internal rate of return for an is
   irr is

IRR calculations mirror those for fair loan repayment rates. The formula (rkn)/(kn-1) gives the fraction of an amount loaned which must be repaid in each of n periods when interest p% is paid on the declining balance. The words ‘declining balance’ reflect the fact that IRR calculations make an implicit assumption that the inflows are reinvested at the calculated compound interest rate, which can sometimes lead to a rosy-eyed picture of absolute IRR values. Using the input stream is as an illustration, if k = the IRR, the progress of each flow the residual capital value is

-100k4 + 20k3 + 50k2 + 70k + 80.

which is evaluated as

   (|.is) p.ptok irr is

More generally the residual value of the stream following a given discount rate is defined by

   resid=.dyad :'(|.y)p. ptok x'
   0 resid is            NB. equivalent to +/is
   10 resid is           NB. discounted by 10%


   Repay=.dyad : '(x*(1+x)^y)%_1+(1+x)^y' NB. Repayment Amounts

so that the consequent repayment amount for a loan of 10000 are given by

   0.005 Repay 12        NB. factor for monthly rate of 0.5%
   10000*0.086066        NB. monthly repayments

A lender sees the transaction as an income stream of -10000 followed by 12 monthly payments of 860.66 whose IRR is therefore

   irr _10000, 12#860.66
0.49992            NB. i.e. monthly rate of 0.5%

illustrating that IRR matches the fair rate of loan interest paid by equal installments on a declining balance. 'Thus irr and Repay are related by the equivalence :

r -: irr _1,n#(r Repay n)

IRR is reduced if payments are deferred, whereas if a loan is paid off early using the same proportionate repayments, the IRR increases. These statements are confirmed by

   irr _10000, (11#860.664),0,860.664   NB. last inflow delayed
   irr _10000,6#2*860.664               NB. inflow rate doubled

The related term ized (Annual Percentage Rate) takes into account that the equivalent annual rate is not 12*0.005, corresponding to 6%, but rather this rate compounded over the 12 periods :

1.06168         NB. APR is 6.17%

To describe APR, use the conversions to and from p to k :

   apr=.ktop@(ptok@irr ^ <:@#)
   apr _10000, 12#860.66

Note on computational practicalities

irr may fail if the income stream is too long, or if the data generates a pathological situation for p.'s underlying root solver. In such circumstances, alternative numerical methods must be employed such as the Newton Raphson method (see Numerical Problems analysed in J, which can be expressed in the adverb

   Newton=.1 :']-x % x D.1'(^:_)("0)

Suppose that a loan of 1000 is repaid in 24 instalments of 45.27. The APR is worked out by

   ms=.(24$45.27),_1000        NB. money stream reversed
   fn=.#.&ms                   NB. define a polynomial
   dtop fn Newton 0.9          NB. guess d=0.9 and apply N-R
 0.67447                       NB. monthly rate of return = 0.6745%
   1.0067447^12                NB. convert to annual rate
1.084                          NB. APR = 8.4%

Net Present Value and Sequential IRRs

After two periods the value of the IRR on the series is is

   irr _100 20 50

The interpretation of this negative IRR is that the inflows must be inflated by (100-18.56)% = 0.814 to achieve the final overall zero outcome, that is

Sequential IRRs can be obtained by a verb

   irrs=.;@:(irr every)@}.@(<\)    NB. successive irr's
   irrs is
_18.5857 15.6152 32.3121

When the IRR becomes positive in the third period the calculation becomes

   +/_100 20 50 70%1.1561^i.4

The concept of Net Present Value is that future values are discounted progressively by a given percentage. This is expressed in the verb

   npv=.]*(ptod@[)^(i.@#@])            NB. net present value
   +/15.61 npv _100 20 50 70

Assuming that the calculation is about money, and the periods are years, the combination of factors such as price inflation, deprciation, obsolsence, foregone returns on alternative investments, etc. are all bracketed under the heading ‘inflation’. A decision to proceed with investment should be based on whether inflation over the entire period of investment is expcted to be less than 32.3%. If future returns are promised as, say, interest payments at a rate of interest, say 10%, npv may be more appropriate than including this factor in IRR. The effect is naturally to reduce IRR :

   irr 10 npv is
   irr 25 npv is

Next consider an income stream such as

   is1=._100 20 45 60 _10 55 70 20 10 10

where some items are negative, reflecting, for example, costs incurred in developing a second version of a software product. Since polynomials of even order must have an even number of positive roots, using p. means that spurious values of IRR will necessarily arise, as for example in

   irr _100 20 45 60 _10
_85.04 6.67385

where the massive compound 85% decay is inadmissible. To deal with such circumstances it makes sense to insert a filter at the d level to exclude discount rates of greater than, say 3, or, at the other end of the scale, than 0.5, hence

   filter=.#~ (<&3)*.(>&0.5)
   irrs is1
0 _22.18 10.22 6.674 19.96 27.96 29.33 29.82 30.19

The initial value of -80 following the first inflow has been filtered to 0. Following the third inflow of 60 the IRR becomes positive at 10.2%, following which there is a dip to 6.67 due to the negative inflow of 10. Towards the end of the series subsequent increases in IRR tail off as a result of smaller inflows.

Now define another income stream is2 with the same values as is1 (total outflows = 110, total inflows =290), only in a different order with the higher values deferred :

   is2=._100 20 45 60 _10 10 10 20 70 55
   irrs is2
0 _22.18 10.22 6.674 9.919 12.37 15.81 22.4 25.22

which shows that the slower progress of the IRR.

Code Summary

ptod=: %@>:@(0.01&*)                         
dtop=: 100&*@<:@%                            
ktop=: *&100@<:                              
ptok=: >:@*&0.01                             
irr=: dtop@filter@pos@real@roots             NB. internal rate of return
dtop=: 100&*@<:@%                            NB. discount factor to %age
filter=: #~ (<&3)*.(>&0.5)                   
pos=: #~ >&0                                 NB. select positive values
real=: #~ (= +)                              NB. select real values
roots=: >@{:@p.                              NB. extract list of roots
irrs=: ;@:(irr every)@}.@(<\)                NB. successive irr's
resid=: dyad :'(|.y)p. ptok x'               NB. residual value
Repay=: dyad : '(x*(1+x)^y)%_1+(1+x)^y'      NB. Repayment Amounts
npv=: ]*(ptod@[)^(i.@#@])                    NB. net present value
apr=: ktop@(ptok@irr ^ <:@#)                 
Newton=: 1 :']-x % x D.1'(^:_)("0)