*************************** ** Maximo Sangiacomo ** ** Feb 2013. Version 2.0 ** *************************** program define irr, rclass version 10 syntax varname [if] [in] marksample touse quietly count if `touse' if `r(N)' == 0 error 2000 mata: irr("`varlist'", "`touse'") disp as txt "Internal Rate of Return = " as res scalar(irr) return scalar NPV = scalar(NPV) return scalar irr = scalar(irr) end mata: void irr(string scalar vname, string scalar touse) { st_view(v1=., ., vname, touse) // validate I0 if (v1[1]>=0) { errprintf("I0 should be a negative number placed as the first observation of %s\n", vname) exit(198) } // validate CFs for (i=2;i<=rows(v1);i++) { if (v1[i]<0) { errprintf("Each cash flow in %s should be a possitive number (or zero)\n", vname) exit(198) } } // validate Net Current Value v4 = v1'*J(rows(v1), 1, 1) if (v4<=0) { errprintf("Net Current Value is negative or zero [ = %f]\n", v4) exit(198) } v5 = v1[1] v3 = J(1,1,.) v2 = J(rows(v1), 1, 0) irr0 = .0001 if (abs(v4/v5) > 10) { v3bis = J(1,1,.) v2bis = J(rows(v1), 1, 0) irr_bis = 1 for (i=1;i<=rows(v1);i++) { j = i - 1 di = 1/(1+irr_bis)^j v2bis[i] = di } v3bis = v1'*v2bis if (v3bis[1]>0) { irr0 = irr_bis } } for (i=1;i<=rows(v1);i++) { j = i - 1 di = 1/(1+irr0)^j v2[i] = di } v3 = v1'*v2 if (v3[1]>=0) { irr = irr0 } else { while (v3[1]<0) { irr0 = irr0/10 for (i=1;i<=rows(v1);i++) { j = i - 1 di = 1/(1+irr0)^j v2[i] = di } v3 = v1'*v2 } irr = irr0 } irrplus = irr/10 while (v3[1]>=.00001) { for (i=1;i<=rows(v1);i++) { j = i - 1 di = 1/(1+irr)^j v2[i] = di } v3 = v1'*v2 st_numscalar("irr", irr) st_numscalar("NPV", v3) irr = irr + irrplus } } end