Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Rebalance by Purchase value #4240

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -927,6 +927,7 @@ public class Messages extends NLS
public static String MenuConfigureCurrentDashboard;
public static String MenuConfigureDashboards;
public static String MenuConfigureRebalancingIndicator;
public static String MenuConfigureRebalancingPurchaseValue;
public static String MenuConfigureView;
public static String MenuConfirmDeleteAllTransactions;
public static String MenuConvertToBuy;
Expand Down Expand Up @@ -1200,6 +1201,7 @@ public class Messages extends NLS
public static String PresetsPrefPageTitle;
public static String RebalanceAmbiguousTooltip;
public static String RebalanceInexactTooltip;
public static String RebalancingPurchaseValue;
public static String SearchSecurityWizardPageSymbolAlreadyExistsInfo;
public static String SecuritiesChart_NoDataMessage_NoHoldings;
public static String SecuritiesChart_NoDataMessage_NoPrices;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1846,6 +1846,8 @@ MenuConfigureDashboards = Configure dashboards

MenuConfigureRebalancingIndicator = Configure {0}/{1} Rule

MenuConfigureRebalancingPurchaseValue = Rebalancing by Purchase Value

MenuConfigureView = Configure view

MenuConfirmDeleteAllTransactions = Delete all transactions of securities {0}?
Expand Down Expand Up @@ -2392,6 +2394,8 @@ RebalanceAmbiguousTooltip = The rebalancing result is ambiguous.\n\nYou can refi

RebalanceInexactTooltip = The rebalancing result is not exact, because there is no exact solution.\n\nThis solution minimizes the mean square error while respecting that the results have to add up to 0.\n\nYou can coarsen the taxonomy or include more securities in the rebalancing to get an exact solution.

RebalancingPurchaseValue = Purchase Value

SearchSecurityWizardPageSymbolAlreadyExistsInfo = A security with the symbol ''{0}'' already exists.

SecuritiesChart_NoDataMessage_NoHoldings = No holdings existent
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,31 @@ private void bindMandatoryDecimalInput(final String label, String property, Text
new UpdateValueStrategy<Long, String>().setConverter(new CurrencyToStringConverter(type)));
}

public final Control bindPositiveAmountInput(Composite editArea, final String label, String property, int style,
int lenghtInCharacters)
{
Text txtValue = createTextInput(editArea, label, style, lenghtInCharacters);
FrenchKeypadSupport.configure(txtValue);
bindPositiveDecimalInput(label, property, txtValue, Values.Amount);
return txtValue;
}

private void bindPositiveDecimalInput(final String label, String property, Text txtValue, Values<?> type)
{
StringToCurrencyConverter converter = new StringToCurrencyConverter(type);

UpdateValueStrategy<String, Long> input2model = new UpdateValueStrategy<>();
input2model.setAfterGetValidator(converter);
input2model.setConverter(converter);
input2model.setAfterConvertValidator(v -> v != null && v.longValue() >= 0 ? ValidationStatus.ok()
: ValidationStatus.error(MessageFormat.format(Messages.MsgDialogInputRequired, label)));

IObservableValue<String> targetObservable = WidgetProperties.text(SWT.Modify).observe(txtValue);
IObservableValue<Long> modelObservable = BeanProperties.value(property, Long.class).observe(model);
context.bindValue(targetObservable, modelObservable, input2model,
new UpdateValueStrategy<Long, String>().setConverter(new CurrencyToStringConverter(type)));
}

private Text createTextInput(Composite editArea, final String label)
{
return createTextInput(editArea, label, SWT.NONE, SWT.DEFAULT);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package name.abuchen.portfolio.ui.views.taxonomy;

import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Shell;

import name.abuchen.portfolio.ui.Messages;
import name.abuchen.portfolio.ui.dialogs.AbstractDialog;

public class EditRebalancingPurchaseValueDialog extends AbstractDialog
{
public EditRebalancingPurchaseValueDialog(Shell parentShell, RebalancingPurchaseValue purchaseValue)
{
super(parentShell, Messages.LabelViewReBalancing, purchaseValue);
}

@Override
protected void createFormElements(Composite editArea)
{
bindings().bindPositiveAmountInput(editArea, Messages.RebalancingPurchaseValue, "purchaseValue", //$NON-NLS-1$
SWT.NONE, 10);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package name.abuchen.portfolio.ui.views.taxonomy;

import java.beans.PropertyChangeListener;
import java.text.MessageFormat;
import java.time.LocalDate;

Expand Down Expand Up @@ -557,6 +558,18 @@ public void configMenuAboutToShow(IMenuManager manager)
manager.add(new SimpleAction(MessageFormat.format(Messages.MenuConfigureRebalancingIndicator, //
rule.getAbsoluteThreshold(), rule.getRelativeThreshold()),
a -> new EditRebalancingColoringRuleDialog(ActiveShell.get(), rule).open()));

RebalancingPurchaseValue purchaseValue = new RebalancingPurchaseValue(getModel().getClient());
manager.add(new SimpleAction(Messages.MenuConfigureRebalancingPurchaseValue,
a -> new EditRebalancingPurchaseValueDialog(ActiveShell.get(), purchaseValue).open()));

PropertyChangeListener listener = evt -> {
getModel().recalculate();
getNodeViewer().refresh();
};
getModel().getClient().addPropertyChangeListener(listener);
getNodeViewer().getControl()
.addDisposeListener(e -> getModel().getClient().removePropertyChangeListener(listener));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package name.abuchen.portfolio.ui.views.taxonomy;

import name.abuchen.portfolio.model.Client;
import name.abuchen.portfolio.money.Values;
import name.abuchen.portfolio.ui.util.BindingHelper;

public class RebalancingPurchaseValue extends BindingHelper.Model
{
private static final String KEY_PURCHASE_VALUE = "taxonomy.rebalancing.purchase"; //$NON-NLS-1$

private long purchaseValue = Values.Amount.factorize(100);

public RebalancingPurchaseValue(Client client)
{
super(client);

purchaseValue = client.getPropertyInt(KEY_PURCHASE_VALUE);
}

public long getPurchaseValue()
{
return purchaseValue;
}

public void setPurchaseValue(long purchaseValue)
{
firePropertyChange("purchaseValue", this.purchaseValue, this.purchaseValue = purchaseValue); // NOSONAR //$NON-NLS-1$
}

@Override
public void applyChanges()
{
Client client = getClient();
client.setProperty(KEY_PURCHASE_VALUE, String.valueOf(purchaseValue));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@ public void recalculate(TaxonomyModel model)
TaxonomyNode virtualRootNode = model.getVirtualRootNode();
TaxonomyNode unassignedNode = model.getUnassignedNode();

virtualRootNode.setTarget(virtualRootNode.getActual().subtract(unassignedNode.getActual()));
RebalancingPurchaseValue purchaseValue = new RebalancingPurchaseValue(model.getClient());
Money purchaseMoney = Money.of(model.getCurrencyCode(), purchaseValue.getPurchaseValue());

virtualRootNode.setTarget(virtualRootNode.getActual().subtract(unassignedNode.getActual())
.add(purchaseMoney));

model.visitAll(node -> {
if (node.isClassification() && !node.isRoot())
Expand Down