Skip to content
All library documents

Fixing Newton Iteration State in an IRR Calculation

Article Quant Q&A · Author: sl007

Summary

The document diagnoses a JavaScript implementation of an internal rate of return calculation using Newton’s method. It evaluates dated cash flows by discounting each amount according to its time from the initial date, then updates the rate using the ratio of net present value to its derivative. The reported implementation returns a rate that does not make net present value zero, despite a spreadsheet calculation suggesting a solution near the expected value.

The accepted answer identifies a state-reset bug: the accumulated present value and derivative are initialized before the iteration loop, so each pass adds to prior-pass totals. They should be reset at the start of every Newton step. This is a targeted debugging explanation rather than a general treatment of IRR. The code also relies on Newton convergence and a single starting guess; the note does not discuss multiple IRRs, invalid rates, zero derivatives, or other failure conditions.

Key ideas

  • Newton’s method needs fresh net present value and derivative totals on each iteration.
  • The implementation accumulates those values across iterations because it initializes them outside the loop.
  • Resetting the accumulators allows each rate update to use the current rate’s cash-flow valuation.
  • The example does not address convergence problems or cases with multiple valid IRRs.

Tags

Full text
# Javascript calculating IRR using Newton method


# Javascript calculating IRR using Newton method












I leveraged the github code (https://gist.github.com/ghalimi/4591338) to compute IRR using Newton method. When I replicated the codes step by step in excel, I'm able to find the optimized resultRate around -0.006. However when I ran the code directly, it generated a resultRate that doesn't accomplish a 0 NPV at all. Can someone please have a look and let me know what went wrong here?

```
FUNCTION IRRCalc(cash_flow ARRAY<FLOAT64>, date_delta ARRAY<INT64>){
    
      var positive = false;
      var negative = false;
      for (var i = 0; i < cash_flow.length; i++) {
        //dates[i] = (i === 0) ? 0 : dates[i - 1] + 365;
        if (cash_flow[i] > 0) {positive = true};
        if (cash_flow[i] < 0) {negative = true};
      }

      if (!positive || !negative) {return null;}
    
      var guess = (typeof guess === 'undefined') ? 0.1 : guess;
      var resultRate = guess;
      
      var epsMax = 1e-4;
      var iterMax = 100000;
    
      var newRate, epsRate;
      var resultValue = 0;
      var irrResultDeriv = 0;
      var iteration = 0;
      var contLoop = true;
      do {
        
        for (var i=0; i < cash_flow.length; i++){
          resultValue  += cash_flow[i]/Math.pow((1+resultRate),date_delta[i]/365);
        }
        
        for (var j=1; j < cash_flow.length; j++){
          var frac = date_delta[j] / 365;
          irrResultDeriv -= frac * cash_flow[j]/Math.pow((1+resultRate),(frac + 1));
        }
        
        newRate = resultRate - resultValue / irrResultDeriv;
        epsRate = Math.abs(newRate - resultRate);
        resultRate = newRate;
        contLoop = (epsRate > epsMax) && (Math.abs(resultValue) > epsMax);
      } while(contLoop && (++iteration < iterMax));
    
      if(contLoop) {return null};
    
      return resultRate;
}
```

Raw data:

#### cash_flow_date   date_delta  cash_flow

2017-07-18 0 -32984.35400000001 2017-11-23 128 744.2457850912499 2018-04-02 258 32093.94362265

## Answer by sl007 (score 1, accepted)

https://quant.stackexchange.com/a/39222

The issue comes from below two variables are defined outside of do...while...

```
  var resultValue = 0;
  var irrResultDeriv = 0;
```

These statements need to be moved to immediately after the "do {" as they provide initialization for the two "for" statements immediately following.

Shown in full with attribution under the source's licence. Licence: CC BY-SA 4.0 (Stack Exchange)

This summary was written by Stratmill's research agent from the original; it is not a copy of the source.