diff --git a/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/model/SecurityTest.java b/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/model/SecurityTest.java index ee1949f250..c8da76cff3 100644 --- a/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/model/SecurityTest.java +++ b/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/model/SecurityTest.java @@ -50,7 +50,7 @@ else if (p.getPropertyType() == int.class && p.getWriteMethod() != null) skipped++; } - assertThat(skipped, equalTo(14)); + assertThat(skipped, equalTo(15)); Security target = source.deepCopy(); assertThat(target.getUUID(), not(equalTo(source.getUUID()))); diff --git a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/Messages.java b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/Messages.java index 73a4d69f74..b02bd80e4a 100644 --- a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/Messages.java +++ b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/Messages.java @@ -1280,6 +1280,8 @@ public class Messages extends NLS public static String SecurityListFilterOnlyExchangeRates; public static String SecurityListFilterOnlyInactive; public static String SecurityListFilterOnlySecurities; + public static String SecurityListFilterOnlySecuritiesNonOpts; + public static String SecurityListFilterOnlySecuritiesOpts; public static String SecurityMenuAddEvent; public static String SecurityMenuAddNewSecurity; public static String SecurityMenuAddNewSecurityDescription; diff --git a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages.properties b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages.properties index 937a78e606..e295b49343 100644 --- a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages.properties +++ b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages.properties @@ -2554,6 +2554,10 @@ SecurityListFilterOnlyInactive = Only inactive instruments SecurityListFilterOnlySecurities = Only securities +SecurityListFilterOnlySecuritiesNonOpts = Securities - non-options + +SecurityListFilterOnlySecuritiesOpts = Securities - options + SecurityMenuAddEvent = Event... SecurityMenuAddNewSecurity = Add new investment instrument diff --git a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/views/SecurityListView.java b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/views/SecurityListView.java index f32ea1dec5..38b5610611 100644 --- a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/views/SecurityListView.java +++ b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/views/SecurityListView.java @@ -3,6 +3,7 @@ import java.io.File; import java.time.LocalDate; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.function.Predicate; import java.util.regex.Pattern; @@ -165,6 +166,8 @@ private class FilterDropDown extends DropDown implements IMenuListener private final Predicate securityIsNotInactive = record -> !record.isRetired(); private final Predicate securityIsInactive = record -> record.isRetired(); private final Predicate onlySecurities = record -> !record.isExchangeRate(); + private final Predicate onlyOpts = record -> record.isOption(); + private final Predicate onlyNonOpts = record -> !record.isOption(); private final Predicate onlyExchangeRates = record -> record.isExchangeRate(); private final Predicate sharesNotZero = record -> getSharesHeld(getClient(), record) != 0; private final Predicate sharesEqualZero = record -> getSharesHeld(getClient(), record) == 0; @@ -199,6 +202,10 @@ else if (watchlist != null) filter.add(limitPriceExceeded); if ((savedFilters & (1 << 7)) != 0) filter.add(securityIsInactive); + if ((savedFilters & (1 << 8)) != 0) + filter.add(onlyOpts); + if ((savedFilters & (1 << 9)) != 0) + filter.add(onlyNonOpts); if (!filter.isEmpty()) setImage(Images.FILTER_ON); @@ -224,6 +231,10 @@ else if (watchlist != null) savedFilter += (1 << 6); if (filter.contains(securityIsInactive)) savedFilter += (1 << 7); + if (filter.contains(onlyOpts)) + savedFilter += (1 << 8); + if (filter.contains(onlyNonOpts)) + savedFilter += (1 << 9); if (watchlist != null) preferenceStore.setValue( this.getClass().getSimpleName() + "-filterSettings" + "-" + watchlist.getName(), //$NON-NLS-1$ //$NON-NLS-2$ @@ -294,6 +305,8 @@ public void menuAboutToShow(IMenuManager manager) manager.add(createAction(Messages.SecurityListFilterOnlyInactive, securityIsInactive)); manager.add(new Separator()); manager.add(createAction(Messages.SecurityListFilterOnlySecurities, onlySecurities)); + manager.add(createAction(" " + Messages.SecurityListFilterOnlySecuritiesOpts, onlyOpts)); + manager.add(createAction(" " + Messages.SecurityListFilterOnlySecuritiesNonOpts, onlyNonOpts)); manager.add(createAction(Messages.SecurityListFilterOnlyExchangeRates, onlyExchangeRates)); manager.add(new Separator()); manager.add(createAction(Messages.SecurityFilterSharesHeldNotZero, sharesNotZero)); @@ -320,9 +333,13 @@ public void run() if (!isChecked) { if (predicate == onlySecurities) - filter.remove(onlyExchangeRates); + filter.removeAll(Arrays.asList(onlyExchangeRates, onlyOpts, onlyNonOpts)); + else if (predicate == onlyOpts) + filter.removeAll(Arrays.asList(onlyExchangeRates, onlySecurities, onlyNonOpts)); + else if (predicate == onlyNonOpts) + filter.removeAll(Arrays.asList(onlyExchangeRates, onlySecurities, onlyOpts)); else if (predicate == onlyExchangeRates) - filter.remove(onlySecurities); + filter.removeAll(Arrays.asList(onlySecurities, onlyOpts, onlyNonOpts)); else if (predicate == sharesEqualZero) filter.remove(sharesNotZero); else if (predicate == sharesNotZero) diff --git a/name.abuchen.portfolio/src/name/abuchen/portfolio/model/Security.java b/name.abuchen.portfolio/src/name/abuchen/portfolio/model/Security.java index 5725032bab..ffc91c7f34 100644 --- a/name.abuchen.portfolio/src/name/abuchen/portfolio/model/Security.java +++ b/name.abuchen.portfolio/src/name/abuchen/portfolio/model/Security.java @@ -31,6 +31,8 @@ */ public final class Security implements Attributable, InvestmentVehicle { + private static final Pattern OPTION_PATTERN = Pattern.compile("^([A-Z]+\\d*)(\\d{6})([CP])(\\d{8})$"); //$NON-NLS-1$ + public static final class ByName implements Comparator, Serializable { private static final long serialVersionUID = 1L; @@ -318,6 +320,20 @@ public boolean isExchangeRate() return this.targetCurrencyCode != null; } + /** + * Is this an option symbol? + * + * @return true for options, else false + */ + public boolean isOption() + { + if (this.tickerSymbol != null) + { + return OPTION_PATTERN.matcher(this.tickerSymbol).matches(); + } + return false; + } + /** * Returns ISIN, Ticker or WKN - whatever is available. */