diff --git a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/views/SecuritiesTable.java b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/views/SecuritiesTable.java index 9105326ad0..4b4c379235 100644 --- a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/views/SecuritiesTable.java +++ b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/views/SecuritiesTable.java @@ -208,6 +208,7 @@ public SecuritiesTable(Composite parent, AbstractFinanceView view) addColumnDateOfLatestPrice(); addColumnDateOfLatestHistoricalPrice(); addQuoteDeltaColumn(); + addQuoteDeltaColumnAnnualized(); support.addColumn(new DistanceFromMovingAverageColumn(LocalDate::now)); support.addColumn(new DistanceFromAllTimeHighColumn(LocalDate::now, view.getPart().getReportingPeriods().stream().collect(toMutableList()))); @@ -585,7 +586,7 @@ private void addQuoteDeltaColumn() // NOSONAR if (previous.getDate().isAfter(interval.getStart())) return null; - return Double.valueOf((latest.getValue() - previous.getValue()) / (double) previous.getValue()); + return Double.valueOf((latest.getValue() / (double) previous.getValue()) - 1); }; Column column = new Column("delta-w-period", Messages.ColumnQuoteChange, SWT.RIGHT, 80); //$NON-NLS-1$ @@ -611,6 +612,59 @@ else if (v2 == null) support.addColumn(column); } + private void addQuoteDeltaColumnAnnualized() // NOSONAR + { + // create a modifiable copy as all menus share the same list of + // reporting periods + List options = view.getPart().getReportingPeriods().stream().collect(toMutableList()); + + BiFunction valueProvider = (element, option) -> { + + Interval interval = option.toInterval(LocalDate.now()); + + Security security = (Security) element; + + SecurityPrice latest = security.getSecurityPrice(interval.getEnd()); + SecurityPrice previous = security.getSecurityPrice(interval.getStart()); + + if (latest == null || previous == null) + return null; + + if (previous.getValue() == 0) + return null; + + if (previous.getDate().isAfter(interval.getStart())) + return null; + + var totalDays = (double) java.time.temporal.ChronoUnit.DAYS.between(previous.getDate(), latest.getDate()); + + var totalGain = latest.getValue() / (double) previous.getValue(); + return Double.valueOf(Math.pow(totalGain, 365 / totalDays)) - 1; + }; + + Column column = new Column("delta-w-period-annualized", Messages.ColumnQuoteChange + " (annualisiert)", SWT.RIGHT, 80); //$NON-NLS-1$ + column.setOptions(new ReportingPeriodColumnOptions(Messages.ColumnQuoteChange_Option + " (p.a.)", options)); + column.setDescription(Messages.ColumnQuoteChange_Description); + column.setLabelProvider(new QuoteReportingPeriodLabelProvider(valueProvider)); + column.setVisible(false); + column.setSorter(ColumnViewerSorter.create((o1, o2) -> { + ReportingPeriod option = (ReportingPeriod) ColumnViewerSorter.SortingContext.getColumnOption(); + + Double v1 = valueProvider.apply(o1, option); + Double v2 = valueProvider.apply(o2, option); + + if (v1 == null && v2 == null) + return 0; + else if (v1 == null) + return -1; + else if (v2 == null) + return 1; + + return Double.compare(v1.doubleValue(), v2.doubleValue()); + })); + support.addColumn(column); + } + private void addAttributeColumns() { AttributeColumn.createFor(getClient(), Security.class) //