Reputation: 23
I have this code to calculate IRR (Internal Rate of Return) and it works like the IRR function in Excel (we have the cashflow values and the guess rate).
This is working fine and I have the same results as the Excel function, but when the IRR tax is bigger than 100% this function doesn't work. The max value that I got is 100%.
What do I need to change to get values bigger than 100?
// Credits: algorithm inspired by Apache OpenOffice
// Calculates the resulting amount
var irrResult = function(values, dates, rate) {
var r = rate + 1;
var result = values[0];
for (var i = 1; i < values.length; i++) {
result += values[i] / Math.pow(r, (dates[i] - dates[0]) / 365);
}
return result;
}
// Calculates the first derivation
var irrResultDeriv = function(values, dates, rate) {
var r = rate + 1;
var result = 0;
for (var i = 1; i < values.length; i++) {
var frac = (dates[i] - dates[0]) / 365;
result -= frac * values[i] / Math.pow(r, frac + 1);
}
return result;
}
// Initialize dates and check that values contains at least one positive value and one negative value
var dates = [];
var positive = false;
var negative = false;
for (var i = 0; i < values.length; i++) {
dates[i] = (i === 0) ? 0 : dates[i - 1] + 365;
if (values[i] > 0) positive = true;
if (values[i] < 0) negative = true;
}
// Return error if values does not contain at least one positive value and one negative value
if (!positive || !negative) return 0;
// Initialize guess and resultRate
var guess = (typeof guess === 'undefined') ? 0.1 : guess;
var resultRate = guess;
// Set maximum epsilon for end of iteration
var epsMax = 1e-10;
// Set maximum number of iterations
var iterMax = 200;
// Implement Newton's method
var newRate, epsRate, resultValue;
var iteration = 0;
var contLoop = true;
do {
resultValue = irrResult(values, dates, resultRate);
newRate = resultRate - resultValue / irrResultDeriv(values, dates, resultRate);
epsRate = Math.abs(newRate - resultRate);
resultRate = newRate;
contLoop = (epsRate > epsMax) && (Math.abs(resultValue) > epsMax);
} while(contLoop && (++iteration < iterMax));
if(contLoop) return 0;
// Return internal rate of return
return resultRate;
}
Upvotes: 1
Views: 1237
Reputation: 1
var irrResult = function(values, dates, rate) {
var r = rate + 1;
var result = values[0];
for (var i = 1; i < values.length; i++) {
result += values[i]/ Math.pow(r, (dates[i] - dates[0]) );
}
return result / 365;
}
Upvotes: -1