Skip to content

Instantly share code, notes, and snippets.

@jjrdev
Forked from ghalimi/IRR.js
Last active January 12, 2018 13:34
Show Gist options
  • Save jjrdev/5f6f5597cf7050e7cb558a8fe7284740 to your computer and use it in GitHub Desktop.
Save jjrdev/5f6f5597cf7050e7cb558a8fe7284740 to your computer and use it in GitHub Desktop.

Revisions

  1. jjrdev revised this gist Jan 12, 2018. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion IRR.js
    Original file line number Diff line number Diff line change
    @@ -23,7 +23,7 @@
    *
    *************************************************************/

    function IRR(values, guess) {
    export function IRR(values, guess) {
    // Credits: algorithm inspired by Apache OpenOffice

    // Calculates the resulting amount
  2. jjrdev revised this gist Jan 12, 2018. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion package.json
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,4 @@
    {
    "name": "IRR",
    "name": "ghalimiirr",
    "version": "0.1.0"
    }
  3. jjrdev revised this gist Jan 12, 2018. 1 changed file with 4 additions and 0 deletions.
    4 changes: 4 additions & 0 deletions package.json
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,4 @@
    {
    "name": "IRR",
    "version": "0.1.0"
    }
  4. @ghalimi ghalimi created this gist Jan 22, 2013.
    89 changes: 89 additions & 0 deletions IRR.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,89 @@
    // Copyright (c) 2012 Sutoiku, Inc. (MIT License)

    // Some algorithms have been ported from Apache OpenOffice:

    /**************************************************************
    *
    * Licensed to the Apache Software Foundation (ASF) under one
    * or more contributor license agreements. See the NOTICE file
    * distributed with this work for additional information
    * regarding copyright ownership. The ASF licenses this file
    * to you under the Apache License, Version 2.0 (the
    * "License"); you may not use this file except in compliance
    * with the License. You may obtain a copy of the License at
    *
    * http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing,
    * software distributed under the License is distributed on an
    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    * KIND, either express or implied. See the License for the
    * specific language governing permissions and limitations
    * under the License.
    *
    *************************************************************/

    function IRR(values, guess) {
    // 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 '#NUM!';

    // 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 = 50;

    // 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 '#NUM!';

    // Return internal rate of return
    return resultRate;
    }