From 3ce9954e70b2d138bd95d982acc216b3c9982716 Mon Sep 17 00:00:00 2001 From: Dominique Lasserre Date: Sun, 11 Sep 2022 23:08:39 +0200 Subject: [PATCH] Update IRR widget to add benchmark - Update IRR widget to add benchmark. That way the inflation adjusted IRR can be displayed by selecting a relevant consumer price index as benchmark. --- .../ui/views/dashboard/DataSeriesConfig.java | 27 +++++++++--- .../views/dashboard/IRRDataSeriesConfig.java | 44 +++++++++++++++++++ .../ui/views/dashboard/IRRWidget.java | 39 ++++++++++++++++ .../ui/views/dashboard/WidgetFactory.java | 7 +-- .../heatmap/ExcessReturnDataSeriesConfig.java | 4 +- 5 files changed, 108 insertions(+), 13 deletions(-) create mode 100644 name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/views/dashboard/IRRDataSeriesConfig.java create mode 100644 name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/views/dashboard/IRRWidget.java diff --git a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/views/dashboard/DataSeriesConfig.java b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/views/dashboard/DataSeriesConfig.java index e1983af18d..312fea51a6 100644 --- a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/views/dashboard/DataSeriesConfig.java +++ b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/views/dashboard/DataSeriesConfig.java @@ -20,6 +20,7 @@ public class DataSeriesConfig implements WidgetConfig { private final WidgetDelegate delegate; + private final boolean supportsDataSeries; private final boolean supportsBenchmarks; private final String label; private final Dashboard.Config configurationKey; @@ -29,18 +30,22 @@ public class DataSeriesConfig implements WidgetConfig public DataSeriesConfig(WidgetDelegate delegate, boolean supportsBenchmarks) { - this(delegate, supportsBenchmarks, false, null, Messages.LabelDataSeries, Dashboard.Config.DATA_SERIES); + this(delegate, true, supportsBenchmarks, false, null, Messages.LabelDataSeries, + Dashboard.Config.DATA_SERIES); } public DataSeriesConfig(WidgetDelegate delegate, boolean supportsBenchmarks, Predicate predicate) { - this(delegate, supportsBenchmarks, false, predicate, Messages.LabelDataSeries, Dashboard.Config.DATA_SERIES); + this(delegate, true, supportsBenchmarks, false, predicate, Messages.LabelDataSeries, + Dashboard.Config.DATA_SERIES); } - protected DataSeriesConfig(WidgetDelegate delegate, boolean supportsBenchmarks, boolean supportsEmptyDataSeries, - Predicate predicate, String label, Dashboard.Config configurationKey) + protected DataSeriesConfig(WidgetDelegate delegate, boolean supportsDataSeries, boolean supportsBenchmarks, + boolean supportsEmptyDataSeries, Predicate predicate, String label, + Dashboard.Config configurationKey) { this.delegate = delegate; + this.supportsDataSeries = supportsDataSeries; this.supportsBenchmarks = supportsBenchmarks; this.label = label; this.configurationKey = configurationKey; @@ -60,6 +65,16 @@ public DataSeries getDataSeries() return dataSeries; } + protected void setDataSeries(DataSeries dataSeries) + { + this.dataSeries = dataSeries; + } + + protected WidgetDelegate getDelegate() + { + return delegate; + } + @Override public void menuAboutToShow(IMenuManager manager) { @@ -70,7 +85,9 @@ public void menuAboutToShow(IMenuManager manager) MenuManager subMenu = new MenuManager(label, configurationKey.name()); subMenu.add(new LabelOnly(dataSeries != null ? dataSeries.getLabel() : "-")); //$NON-NLS-1$ subMenu.add(new Separator()); - subMenu.add(new SimpleAction(Messages.MenuSelectDataSeries, a -> doAddSeries(false))); + + if (supportsDataSeries) + subMenu.add(new SimpleAction(Messages.MenuSelectDataSeries, a -> doAddSeries(false))); if (supportsBenchmarks) subMenu.add(new SimpleAction(Messages.MenuSelectBenchmarkDataSeries, a -> doAddSeries(true))); diff --git a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/views/dashboard/IRRDataSeriesConfig.java b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/views/dashboard/IRRDataSeriesConfig.java new file mode 100644 index 0000000000..3933884db7 --- /dev/null +++ b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/views/dashboard/IRRDataSeriesConfig.java @@ -0,0 +1,44 @@ +package name.abuchen.portfolio.ui.views.dashboard; + +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.Separator; + +import name.abuchen.portfolio.model.Dashboard; +import name.abuchen.portfolio.ui.Messages; +import name.abuchen.portfolio.ui.util.SimpleAction; + +public class IRRDataSeriesConfig extends DataSeriesConfig +{ + + public IRRDataSeriesConfig(WidgetDelegate delegate) + { + super(delegate, false, true, true, null, Messages.LabelBenchmarks, + Dashboard.Config.SECONDARY_DATA_SERIES); + } + + @Override + public void menuAboutToShow(IMenuManager manager) + { + super.menuAboutToShow(manager); + if (getDataSeries() != null) + { + IMenuManager subMenu = manager.findMenuUsingPath(Dashboard.Config.SECONDARY_DATA_SERIES.name()); + subMenu.add(new Separator()); + subMenu.add(new SimpleAction(Messages.MenuReportingPeriodDelete, a -> removeBenchmark())); + } + + } + + private void removeBenchmark() + { + if (getDataSeries() == null) + return; + + setDataSeries(null); + getDelegate().getWidget().getConfiguration().remove(Dashboard.Config.SECONDARY_DATA_SERIES.name()); + getDelegate().getWidget().setLabel(WidgetFactory.valueOf(getDelegate().getWidget().getType()).getLabel()); + getDelegate().update(); + getDelegate().getClient().touch(); + } + +} diff --git a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/views/dashboard/IRRWidget.java b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/views/dashboard/IRRWidget.java new file mode 100644 index 0000000000..7b2b7a3337 --- /dev/null +++ b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/views/dashboard/IRRWidget.java @@ -0,0 +1,39 @@ +package name.abuchen.portfolio.ui.views.dashboard; + +import java.time.LocalDate; +import java.util.function.Supplier; + +import name.abuchen.portfolio.model.Dashboard.Widget; +import name.abuchen.portfolio.money.Values; +import name.abuchen.portfolio.ui.views.dataseries.DataSeries; +import name.abuchen.portfolio.util.Interval; + +public class IRRWidget extends IndicatorWidget +{ + public IRRWidget(Widget widget, DashboardData dashboardData) + { + super(widget, dashboardData, false, null); + this.setFormatter(Values.Percent2); + + addConfig(new IRRDataSeriesConfig(this)); + } + + @Override + public Supplier getUpdateTask() + { + return () -> { + double irrBench = 0; + Interval reportingPeriod = get(ReportingPeriodConfig.class).getReportingPeriod() + .toInterval(LocalDate.now()); + DataSeries dsBench = get(IRRDataSeriesConfig.class).getDataSeries(); + if (dsBench != null) + { + irrBench = getDashboardData().calculate(dsBench, reportingPeriod).getPerformanceIRR(); + } + + double irr = getDashboardData().calculate(get(DataSeriesConfig.class).getDataSeries(), reportingPeriod) + .getPerformanceIRR(); + return (irrBench != -1) ? (1 + irr) / (1 + irrBench) - 1 : irr - irrBench; + }; + } +} diff --git a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/views/dashboard/WidgetFactory.java b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/views/dashboard/WidgetFactory.java index 4e0c47f88e..9a6e8e8352 100644 --- a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/views/dashboard/WidgetFactory.java +++ b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/views/dashboard/WidgetFactory.java @@ -58,12 +58,7 @@ public enum WidgetFactory return index.getFinalAccumulatedAnnualizedPercentage(); }).build()), - IRR(Messages.LabelIRR, Messages.ClientEditorLabelPerformance, // - (widget, data) -> IndicatorWidget.create(widget, data) // - .with(Values.Percent2) // - .with((ds, period) -> data.calculate(ds, period).getPerformanceIRR()) // - .withBenchmarkDataSeries(false) // - .build()), + IRR(Messages.LabelIRR, Messages.ClientEditorLabelPerformance, IRRWidget::new), ABSOLUTE_CHANGE(Messages.LabelAbsoluteChange, Messages.LabelStatementOfAssets, // (widget, data) -> IndicatorWidget.create(widget, data) // diff --git a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/views/dashboard/heatmap/ExcessReturnDataSeriesConfig.java b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/views/dashboard/heatmap/ExcessReturnDataSeriesConfig.java index a36a34d263..22722c90df 100644 --- a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/views/dashboard/heatmap/ExcessReturnDataSeriesConfig.java +++ b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/views/dashboard/heatmap/ExcessReturnDataSeriesConfig.java @@ -9,8 +9,8 @@ public class ExcessReturnDataSeriesConfig extends DataSeriesConfig { public ExcessReturnDataSeriesConfig(WidgetDelegate delegate) { - super(delegate, true, true, null, Messages.LabelExcessReturnBaselineDataSeries, - Dashboard.Config.SECONDARY_DATA_SERIES); + super(delegate, true, true, true, null, + Messages.LabelExcessReturnBaselineDataSeries, Dashboard.Config.SECONDARY_DATA_SERIES); } }