/** * Copyright (C) 2011 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.financial.filtering; import java.math.BigDecimal; import java.util.Collection; import java.util.Map; import org.threeten.bp.LocalDate; import org.threeten.bp.OffsetTime; import com.google.common.collect.Maps; import com.opengamma.core.position.Counterparty; import com.opengamma.core.position.Position; import com.opengamma.core.position.Trade; import com.opengamma.core.security.Security; import com.opengamma.core.security.SecurityLink; import com.opengamma.financial.expression.UserExpression; import com.opengamma.financial.expression.UserExpression.DynamicAttributes; import com.opengamma.financial.expression.UserExpression.DynamicVariables; import com.opengamma.financial.expression.UserExpression.Evaluator; import com.opengamma.financial.expression.deprecated.ExpressionParser; import com.opengamma.id.UniqueId; import com.opengamma.util.money.Currency; /** * Filters a portfolio according to a provided {@link UserExpression} */ public class ExpressionPortfolioFilter extends AbstractFilteringFunction { private final UserExpression _expression; /** * Creates a new filter from a string expression (in the Expr.g form) * * @param expression string expression * @deprecated Use the alternative constructor so that the parsing dialect is explicit */ @Deprecated public ExpressionPortfolioFilter(final String expression) { this(new ExpressionParser().parse(expression)); } /** * Creates a new filter from an arbitrary user expression * * @param expression the parsed user expression */ public ExpressionPortfolioFilter(final UserExpression expression) { super("User expression"); _expression = expression; } private UserExpression getExpression() { return _expression; } private static class AnyTradeAttribute implements Trade { private final Collection<Trade> _trades; public AnyTradeAttribute(final Collection<Trade> trades) { _trades = trades; } public Collection<Trade> getTrades() { return _trades; } private Trade getTrade() { return getTrades().iterator().next(); } @Override public UniqueId getUniqueId() { return getTrade().getUniqueId(); } @Override public BigDecimal getQuantity() { return getTrade().getQuantity(); } @Override public SecurityLink getSecurityLink() { return getTrade().getSecurityLink(); } @Override public Security getSecurity() { return getTrade().getSecurity(); } @Override public Map<String, String> getAttributes() { Map<String, String> allAttributes = Maps.newHashMap(); for (Trade trade : _trades) { allAttributes.putAll(trade.getAttributes()); } return allAttributes; } @Override public void setAttributes(Map<String, String> attributes) { throw new UnsupportedOperationException(); } @Override public void addAttribute(String key, String value) { throw new UnsupportedOperationException(); } @Override public Counterparty getCounterparty() { return getTrade().getCounterparty(); } @Override public LocalDate getTradeDate() { return getTrade().getTradeDate(); } @Override public OffsetTime getTradeTime() { return getTrade().getTradeTime(); } @Override public Double getPremium() { return getTrade().getPremium(); } @Override public Currency getPremiumCurrency() { return getTrade().getPremiumCurrency(); } @Override public LocalDate getPremiumDate() { return getTrade().getPremiumDate(); } @Override public OffsetTime getPremiumTime() { return getTrade().getPremiumTime(); } } private static final DynamicAttributes s_dynamicAttributes = new DynamicAttributes() { @Override public Object getValue(final Object object, final String name) { if (object instanceof Position) { final Position position = (Position) object; if ("trade".equals(name)) { final Collection<Trade> trades = position.getTrades(); if (trades.size() == 1) { return trades.iterator().next(); } else if (trades.isEmpty()) { return UserExpression.NA; } else { return new AnyTradeAttribute(trades); } } else { Object value = position.getAttributes().get(name); if (value != null) { return value; } else { for (Trade trade : position.getTrades()) { value = trade.getAttributes().get(name); if (value != null) { return value; } } return UserExpression.NA; } } } else if (object instanceof AnyTradeAttribute) { final AnyTradeAttribute trades = (AnyTradeAttribute) object; for (Trade trade : trades.getTrades()) { final Object value = trade.getAttributes().get(name); if (value != null) { return value; } } return UserExpression.NA; } else if (object instanceof Trade) { final Trade trade = (Trade) object; final Object value = trade.getAttributes().get(name); if (value != null) { return value; } else { return UserExpression.NA; } } else { return UserExpression.NA; } } }; @Override public boolean acceptPosition(final Position position) { final Evaluator eval = getExpression().evaluator(); eval.setVariable("position", position); eval.setVariable("quantity", position.getQuantity().doubleValue()); eval.setVariable("security", position.getSecurity()); eval.setDynamicVariables(new DynamicVariables() { @Override public Object getValue(final String name) { return s_dynamicAttributes.getValue(position, name); } }); eval.setDynamicAttributes(s_dynamicAttributes); return Boolean.TRUE.equals(eval.evaluate()); } }