Closed t-pa closed 6 years ago
Wow! Will look it over soon.
I pulled this into my local repo to play. Currently, it's failing on my personal data with internalRateOfReturn returning Nan.
Nov 30, 2017 5:35:09 AM jgnash.uifx.report.PortfolioReportController$PortfolioReportTableModel <init> SEVERE: null java.lang.NumberFormatException at java.math.BigDecimal.<init>(BigDecimal.java:494) at java.math.BigDecimal.<init>(BigDecimal.java:383) at java.math.BigDecimal.<init>(BigDecimal.java:806) at java.math.BigDecimal.valueOf(BigDecimal.java:1274) at jgnash.engine.InvestmentPerformanceSummary.calculateInternalRateOfReturn(InvestmentPerformanceSummary.java:349) at jgnash.engine.InvestmentPerformanceSummary.runCalculations(InvestmentPerformanceSummary.java:375) at jgnash.engine.InvestmentPerformanceSummary.<init>(InvestmentPerformanceSummary.java:83) at jgnash.engine.InvestmentPerformanceSummary.<init>(InvestmentPerformanceSummary.java:52) at jgnash.uifx.report.PortfolioReportController$PortfolioReportTableModel.<init>(PortfolioReportController.java:128) at jgnash.uifx.report.PortfolioReportController.createJasperPrint(PortfolioReportController.java:83) at jgnash.uifx.report.jasper.JasperViewerDialogController.lambda$initialize$1(JasperViewerDialogController.java:259)
Is there a better means to avoid NaN?
I've modified the check for convergence and added some logging so we can see what values cause the failure. Also, the NaN value is now handled gracefully: it is simply omitted in the reports and no longer causes them to crash. Could you try this again with your data?
Merged into master. It works with some of my accounts.
I will see about expanding the unit test with my offending data to see what's next..
Thanks!
That would be great. The problem might have to do with shares that yield dividends but have been bought before the start date. In that case, there is a gain without a (visible) investment.
I created a unit test with the failing data. It is a model of an account with an opening balance (no prior shares) and only reinvested dividends...
Ideally, Add shares would have been used prior to the addition of the dividend data.
The test data contains only gains without any investments. The rate of return relative is therefore infinite and the calculation does not converge, just as it should.
In order to provide a more meaningful performance indicator, we should probably put a fictitious BUY transaction at the start date. With this BUY transaction the then-current number of shares is bought at the market price at that date, just as a fictitious SELL is already used to account for the unrealized gains.
However, I believe that would conflict with the way all the other report values are calculated. Those do not take the number of existing shares at the start date into account. Or am I missing something?
This adds a simple calculation of the (annualized) internal rate of return to the investment portfolio summary and displays the results in the portfolio reports.