/** * Copyright (C) 2013 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.integration.marketdata.manipulator.dsl; import static com.opengamma.engine.value.ValueRequirementNames.BLACK_VOLATILITY_SURFACE; import static com.opengamma.engine.value.ValueRequirementNames.INTERPOLATED_VOLATILITY_SURFACE; import static com.opengamma.engine.value.ValueRequirementNames.VOLATILITY_SURFACE; import java.util.Objects; import java.util.Set; import java.util.regex.Pattern; import com.google.common.collect.ImmutableSet; import com.opengamma.core.marketdatasnapshot.VolatilitySurfaceKey; import com.opengamma.engine.marketdata.manipulator.DistinctMarketDataSelector; import com.opengamma.engine.marketdata.manipulator.SelectorResolver; import com.opengamma.engine.value.SurfaceAndCubePropertyNames; import com.opengamma.engine.value.ValuePropertyNames; import com.opengamma.engine.value.ValueSpecification; import com.opengamma.id.UniqueId; import com.opengamma.util.ArgumentChecker; import com.opengamma.util.RegexUtils; /** * Selects volatility surfaces for manipulation. */ public class VolatilitySurfaceSelector implements DistinctMarketDataSelector { private static final ImmutableSet<String> s_compatibleVRNames = ImmutableSet.of(INTERPOLATED_VOLATILITY_SURFACE, VOLATILITY_SURFACE, BLACK_VOLATILITY_SURFACE); private final Set<String> _calcConfigNames; private final Set<String> _names; private final PatternWrapper _nameMatchPattern; private final PatternWrapper _nameLikePattern; private final Set<String> _instrumentTypes; private final Set<String> _quoteTypes; private final Set<String> _quoteUnits; /* package */ VolatilitySurfaceSelector(Set<String> calcConfigNames, Set<String> names, Pattern nameMatchPattern, Pattern nameLikePattern, Set<String> instrumentTypes, Set<String> quoteTypes, Set<String> quoteUnits) { _calcConfigNames = calcConfigNames; _names = names; _nameMatchPattern = PatternWrapper.wrap(nameMatchPattern); _nameLikePattern = PatternWrapper.wrap(nameLikePattern); _instrumentTypes = instrumentTypes; _quoteTypes = quoteTypes; _quoteUnits = quoteUnits; } @Override public boolean hasSelectionsDefined() { return true; } @Override public DistinctMarketDataSelector findMatchingSelector(ValueSpecification valueSpecification, String calculationConfigurationName, SelectorResolver resolver) { if (_calcConfigNames != null && !_calcConfigNames.contains(calculationConfigurationName)) { return null; } if (!s_compatibleVRNames.contains(valueSpecification.getValueName())) { return null; } VolatilitySurfaceKey key = createKey(valueSpecification); if (!contains(_names, key.getName())) { return null; } if (_nameMatchPattern != null && !_nameMatchPattern.getPattern().matcher(key.getName()).matches()) { return null; } if (_nameLikePattern != null && !_nameLikePattern.getPattern().matcher(key.getName()).matches()) { return null; } if (!contains(_instrumentTypes, key.getInstrumentType())) { return null; } if (!contains(_quoteTypes, key.getQuoteType())) { return null; } if (!contains(_quoteUnits, key.getQuoteUnits())) { return null; } return this; } private static VolatilitySurfaceKey createKey(ValueSpecification valueSpecification) { UniqueId uniqueId = valueSpecification.getTargetSpecification().getUniqueId(); String surface = valueSpecification.getProperties().getStrictValue(ValuePropertyNames.SURFACE); String instrumentType = valueSpecification.getProperties().getStrictValue("InstrumentType"); String quoteType = valueSpecification.getProperties().getStrictValue(SurfaceAndCubePropertyNames.PROPERTY_SURFACE_QUOTE_TYPE); String quoteUnits = valueSpecification.getProperties().getStrictValue(SurfaceAndCubePropertyNames.PROPERTY_SURFACE_UNITS); return VolatilitySurfaceKey.of(uniqueId, surface, instrumentType, quoteType, quoteUnits); } private static boolean contains(Set<String> set, String str) { if (set == null) { return true; } else { return set.contains(str); } } /* package */ Set<String> getCalcConfigNames() { return _calcConfigNames; } /* package */ Set<String> getNames() { return _names; } /* package */ Pattern getNameMatchPattern() { return _nameMatchPattern == null ? null : _nameMatchPattern.getPattern(); } /* package */ Pattern getNameLikePattern() { return _nameLikePattern == null ? null : _nameLikePattern.getPattern(); } /* package */ Set<String> getInstrumentTypes() { return _instrumentTypes; } /* package */ Set<String> getQuoteTypes() { return _quoteTypes; } /* package */ Set<String> getQuoteUnits() { return _quoteUnits; } @Override public int hashCode() { return Objects.hash(_calcConfigNames, _names, _nameMatchPattern, _nameLikePattern, _instrumentTypes, _quoteTypes, _quoteUnits); } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null || getClass() != obj.getClass()) { return false; } final VolatilitySurfaceSelector other = (VolatilitySurfaceSelector) obj; return Objects.equals(this._calcConfigNames, other._calcConfigNames) && Objects.equals(this._names, other._names) && Objects.equals(this._nameMatchPattern, other._nameMatchPattern) && Objects.equals(this._nameLikePattern, other._nameLikePattern) && Objects.equals(this._instrumentTypes, other._instrumentTypes) && Objects.equals(this._quoteTypes, other._quoteTypes) && Objects.equals(this._quoteUnits, other._quoteUnits); } @Override public String toString() { return "VolatilitySurfaceSelector [" + "_calcConfigNames=" + _calcConfigNames + ", _names=" + _names + ", _nameMatchPattern=" + _nameMatchPattern + ", _nameLikePattern=" + _nameLikePattern + ", _instrumentTypes=" + _instrumentTypes + ", _quoteTypes=" + _quoteTypes + ", _quoteUnits=" + _quoteUnits + "]"; } public static class Builder { /** The scenario to which manipulations are added. */ private final Scenario _scenario; private Set<String> _names; private Pattern _nameMatchPattern; private Pattern _nameLikePattern; private Set<String> _instrumentTypes; private Set<String> _quoteTypes; private Set<String> _quoteUnits; /* package */ Builder(Scenario scenario) { ArgumentChecker.notNull(scenario, "scenario"); _scenario = scenario; } public VolatilitySurfaceManipulatorBuilder apply() { VolatilitySurfaceSelector selector = getSelector(); return new VolatilitySurfaceManipulatorBuilder(_scenario, selector); } /* package */ VolatilitySurfaceSelector getSelector() { return new VolatilitySurfaceSelector(_scenario.getCalcConfigNames(), _names, _nameMatchPattern, _nameLikePattern, _instrumentTypes, _quoteTypes, _quoteUnits); } public Builder named(String... names) { ArgumentChecker.notEmpty(names, "names"); if (_names != null) { throw new IllegalStateException("named() can only be called once"); } if (_nameMatchPattern != null) { throw new IllegalStateException("Can't specify exact name and a match for the name"); } if (_nameLikePattern != null) { throw new IllegalStateException("Can't specify exact name and a match for the name"); } _names = ImmutableSet.copyOf(names); return this; } public Builder nameMatches(String regex) { ArgumentChecker.notNull(regex, "regex"); if (_nameMatchPattern != null) { throw new IllegalStateException("nameMatches() can only be called once"); } if (_names != null) { throw new IllegalStateException("Can't specify exact name and a regular expression for the name"); } if (_nameLikePattern != null) { throw new IllegalStateException("Can't specify exact name and a regular expression for the name"); } _nameMatchPattern = Pattern.compile(regex); return this; } public Builder nameLike(String glob) { ArgumentChecker.notEmpty(glob, "glob"); if (_nameLikePattern != null) { throw new IllegalStateException("nameLike() can only be called once"); } if (_names != null) { throw new IllegalStateException("Can't specify exact name and a regular expression for the name"); } if (_nameMatchPattern != null) { throw new IllegalStateException("Can't specify exact name and a regular expression for the name"); } _nameLikePattern = RegexUtils.globToPattern(glob); return this; } public Builder instrumentTypes(String... types) { ArgumentChecker.notEmpty(types, "types"); if (_instrumentTypes != null) { throw new IllegalStateException("instrumentTypes() can only be called once"); } _instrumentTypes = ImmutableSet.copyOf(types); return this; } public Builder quoteTypes(String... types) { ArgumentChecker.notEmpty(types, "types"); if (_quoteTypes != null) { throw new IllegalStateException("quoteTypes() can only be called once"); } _quoteTypes = ImmutableSet.copyOf(types); return this; } public Builder quoteUnits(String... units) { ArgumentChecker.notEmpty(units, "units"); if (_quoteUnits != null) { throw new IllegalStateException("quoteUntis() can only be called once"); } _quoteUnits = ImmutableSet.copyOf(units); return this; } /* package */ Scenario getScenario() { return _scenario; } } }