Search code examples
excel-formulaapache-poiirr

IRR in poi return NaN but correct value in excel


When i calculate Irr value use apache/poi i get Double.NaN, but the same inputs in excel i got a negative value.

So why they return different value?

inputs here:

irr(-1.0601017230994111E8,19150.63,44505.08,22997.34,33936.39,27265.92,2127.66,2108.63,886.53,2482.27,4305.12,3421.58,65644.12,1020.51,2659.57,3191.49,20284508.4,1881279.27,11675415.09,7557862.28,921090.46,622104.32,289267.36,183.41,886.53, 0.1)


Solution

  • For me it gives the #NUM! error in current apache poi 4.1.0, not NaN.

    The problem is about your given guess. In IRR-function it is stated:

    Guess Optional. A number that you guess is close to the result of IRR.

    Microsoft Excel uses an iterative technique for calculating IRR. Starting with guess, IRR cycles through the calculation until the result is accurate within 0.00001 percent. If IRR can't find a result that works after 20 tries, the #NUM! error value is returned.

    In most cases you do not need to provide guess for the IRR calculation. If guess is omitted, it is assumed to be 0.1 (10 percent).

    If IRR gives the #NUM! error value, or if the result is not close to what you expected, try again with a different value for guess.

    The result of your IRR would be -0.050193141 in Excel. But your guess is 0.1. So using that guess the internal apache poi IRR function does not find a result which is accurate within 0.00001 percent after 20 tries. So the #NUM! error value is returned.

    Why apache poi's IRR function is not the same as in Excel? Well because that part of Excel is not open source. So nobody really knows how it works.

    Using a guess of -0.1 works for me.

    Example:

    import java.io.FileOutputStream;
    import org.apache.poi.ss.usermodel.*;
    import org.apache.poi.xssf.usermodel.XSSFWorkbook;
    
    class ExcelEvaluateIRR {
    
     public static void main(String[] args) throws Exception {
    
      try (Workbook workbook = new XSSFWorkbook(); 
           FileOutputStream fileout = new FileOutputStream("Excel.xlsx") ) {
    
       Double[] values = new Double[] {
        -1.0601017230994111E8,
        19150.63,
        44505.08,
        22997.34,
        33936.39,
        27265.92,
        2127.66,
        2108.63,
        886.53,
        2482.27,
        4305.12,
        3421.58,
        65644.12,
        1020.51,
        2659.57,
        3191.49,
        20284508.4,
        1881279.27,
        11675415.09,
        7557862.28,
        921090.46,
        622104.32,
        289267.36,
        183.41,
        886.53
       };
    
       Sheet sheet = workbook.createSheet();
       Row row = null;
       Cell cell = null;
       for (int r = 0; r < values.length; r++) {
        row = sheet.createRow(r);
        cell = row.createCell(0);
        cell.setCellValue(values[r]);
       }
       row = sheet.createRow(values.length);
       cell = row.createCell(0);
       //cell.setCellFormula("IRR(A1:A" + values.length + ",0.1)"); // will not work
       cell.setCellFormula("IRR(A1:A" + values.length + ",-0.1)"); // will work
       FormulaEvaluator formulaEvaluator = workbook.getCreationHelper().createFormulaEvaluator();
       CellValue cellValue = formulaEvaluator.evaluate(cell);
       System.out.println(cellValue);
    
       workbook.write(fileout);
      }
    
     }
    }