RayDeCampo / java-xirr

Java implementation of xirr with bonus Newton-Raphson implementation
MIT License
75 stars 37 forks source link

Overflow with java-xirr but not with Google Sheets #17

Closed gdressino closed 2 years ago

gdressino commented 4 years ago

This data set causes an overflow with java-xirr but not with Google Sheets and LibreOffice:

2020-01-31 | 2821703.69 2020-03-06 | 12554.96 2020-03-06 | -12554.96 2020-03-27 | -24208.19 2020-03-27 | -437308.92 2020-03-27 | -2598.07 2020-03-27 | -93054.6 2020-03-27 | -26665.85 2020-03-27 | -14531.04 2020-04-01 | -9807.79 2020-04-01 | -97605 2020-04-01 | -21304.64 2020-04-01 | -89577.85 2020-04-01 | -12191.24 2020-04-01 | -7176.47 2020-04-01 | -11337.45 2020-04-01 | -12917.64 2020-04-01 | -11530.63 2020-04-01 | -34625.18 2020-04-01 | -6485.98 2020-04-01 | -21439.77 2020-04-03 | -442.35 2020-05-04 | 186.98 2020-05-04 | -5843.2 2020-06-03 | -3195.16 2020-06-03 | -780315.21 2020-06-08 | 3225.17 2020-06-08 | -759649.19 2020-06-08 | -3225.17 2020-06-08 | 759649.19 2020-06-18 | -116794.53

The result in Google Sheets or Libre Office is: -0.809918434570599

This is the code to test the dataset in Java:

    public static void main(String[] args) {
        Object[][] data = { { "2020-01-31", 2821703.69d }, { "2020-03-06", 12554.96d }, { "2020-03-06", -12554.96d },
                { "2020-03-27", -24208.19d }, { "2020-03-27", -437308.92d }, { "2020-03-27", -2598.07d },
                { "2020-03-27", -93054.6d }, { "2020-03-27", -26665.85d }, { "2020-03-27", -14531.04d },
                { "2020-04-01", -9807.79d }, { "2020-04-01", -97605d }, { "2020-04-01", -21304.64d },
                { "2020-04-01", -89577.85d }, { "2020-04-01", -12191.24d }, { "2020-04-01", -7176.47d },
                { "2020-04-01", -11337.45d }, { "2020-04-01", -12917.64d }, { "2020-04-01", -11530.63d },
                { "2020-04-01", -34625.18d }, { "2020-04-01", -6485.98d }, { "2020-04-01", -21439.77d },
                { "2020-04-03", -442.35d }, { "2020-05-04", 186.98d }, { "2020-05-04", -5843.2d },
                { "2020-06-03", -3195.16d }, { "2020-06-03", -780315.21d }, { "2020-06-08", 3225.17d },
                { "2020-06-08", -759649.19d }, { "2020-06-08", -3225.17d }, { "2020-06-08", 759649.19d },
                { "2020-06-18", -116794.53d } };

        List<Object[]> list = Arrays.asList(data);

        Xirr xirr = new Xirr(
                list.stream().map(m -> new Transaction((double) m[1], (String)m[0])).collect(Collectors.toList()));
        double rate = xirr.xirr();
        System.out.println(rate);
    }
Exception in thread "main" org.decampo.xirr.OverflowException: Candidate overflow: {guess=0.9845005934908324, iteration=1459, candidate=Infinity, value=-5.34085707426003E123, derivative=2.24120486056538E-185}
    at org.decampo.xirr.NewtonRaphson$Calculation.setCandidate(NewtonRaphson.java:166)
    at org.decampo.xirr.NewtonRaphson$Calculation.solve(NewtonRaphson.java:213)
    at org.decampo.xirr.NewtonRaphson.inverse(NewtonRaphson.java:89)
    at org.decampo.xirr.NewtonRaphson.findRoot(NewtonRaphson.java:70)
    at org.decampo.xirr.NewtonRaphson$Builder.findRoot(NewtonRaphson.java:136)
    at org.decampo.xirr.Xirr.xirr(Xirr.java:155)
gdressino commented 4 years ago

Please note that it will work with Excel default guess (0.1):

    public static void main(String[] args) {
        Object[][] data = { { "2020-01-31", 2821703.69d }, { "2020-03-06", 12554.96d }, { "2020-03-06", -12554.96d },
                { "2020-03-27", -24208.19d }, { "2020-03-27", -437308.92d }, { "2020-03-27", -2598.07d },
                { "2020-03-27", -93054.6d }, { "2020-03-27", -26665.85d }, { "2020-03-27", -14531.04d },
                { "2020-04-01", -9807.79d }, { "2020-04-01", -97605d }, { "2020-04-01", -21304.64d },
                { "2020-04-01", -89577.85d }, { "2020-04-01", -12191.24d }, { "2020-04-01", -7176.47d },
                { "2020-04-01", -11337.45d }, { "2020-04-01", -12917.64d }, { "2020-04-01", -11530.63d },
                { "2020-04-01", -34625.18d }, { "2020-04-01", -6485.98d }, { "2020-04-01", -21439.77d },
                { "2020-04-03", -442.35d }, { "2020-05-04", 186.98d }, { "2020-05-04", -5843.2d },
                { "2020-06-03", -3195.16d }, { "2020-06-03", -780315.21d }, { "2020-06-08", 3225.17d },
                { "2020-06-08", -759649.19d }, { "2020-06-08", -3225.17d }, { "2020-06-08", 759649.19d },
                { "2020-06-18", -116794.53d } };

        List<Object[]> list = Arrays.asList(data);

        List<Transaction> txs = list.stream().map(m -> new Transaction((double) m[1], (String) m[0]))
                .collect(Collectors.toList());

        double rate = Xirr.builder().withGuess(.1).withTransactions(txs).xirr();
        System.out.println(rate);
    }
Renukushwah1101 commented 2 years ago

org.decampo.xirr.OverflowException: Candidate overflow: {guess=0.1, iteration=188, candidate=-Infinity, value=-1.536442899055107E11, derivative=-8.345988024991577E-298} at org.decampo.xirr.NewtonRaphson$Calculation.setCandidate(NewtonRaphson.java:166) at org.decampo.xirr.NewtonRaphson$Calculation.solve(NewtonRaphson.java:213) at org.decampo.xirr.NewtonRaphson.inverse(NewtonRaphson.java:89) at org.decampo.xirr.NewtonRaphson.findRoot(NewtonRaphson.java:70) at org.decampo.xirr.NewtonRaphson$Builder.findRoot(NewtonRaphson.java:136) at org.decampo.xirr.Xirr.xirr(Xirr.java:155) at org.decampo.xirr.Xirr$Builder.xirr(Xirr.java:262)

here guess is 0.1 but still it showing this error. how can i fix this error?

RayDeCampo commented 2 years ago

@gdressino if you want the library to use Excel's default guess of .1 all the time then go ahead and set the guess each time. @Renukushwah1101 it's not really appropriate to comment on other issues (especially closed ones as you did elsewhere) with a separate problem. The issue could be with the guess or with your data set.