/**
* Copyright (C) 2012 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.financial.analytics.model.pnl;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.opengamma.engine.ComputationTarget;
import com.opengamma.engine.function.FunctionCompilationContext;
import com.opengamma.engine.target.ComputationTargetType;
import com.opengamma.engine.value.ValuePropertyNames;
import com.opengamma.engine.value.ValueRequirement;
import com.opengamma.engine.value.ValueRequirementNames;
import com.opengamma.financial.analytics.OpenGammaFunctionExclusions;
import com.opengamma.financial.analytics.model.InterpolatedDataProperties;
import com.opengamma.financial.analytics.model.forex.ForexVisitors;
import com.opengamma.financial.property.DefaultPropertyFunction;
import com.opengamma.financial.security.FinancialSecurity;
import com.opengamma.financial.security.option.FXBarrierOptionSecurity;
import com.opengamma.financial.security.option.FXDigitalOptionSecurity;
import com.opengamma.financial.security.option.FXOptionSecurity;
import com.opengamma.financial.security.option.NonDeliverableFXDigitalOptionSecurity;
import com.opengamma.financial.security.option.NonDeliverableFXOptionSecurity;
import com.opengamma.util.ArgumentChecker;
import com.opengamma.util.tuple.Pair;
import com.opengamma.util.tuple.Pairs;
/**
*
*/
public class FXOptionBlackPnLSurfaceDefaults extends DefaultPropertyFunction {
private static final Logger s_logger = LoggerFactory.getLogger(FXOptionBlackPnLSurfaceDefaults.class);
private final String _interpolatorName;
private final String _leftExtrapolatorName;
private final String _rightExtrapolatorName;
private final Map<Pair<String, String>, String> _surfaceNameByCurrencyPair;
public FXOptionBlackPnLSurfaceDefaults(final String interpolatorName, final String leftExtrapolatorName, final String rightExtrapolatorName,
final String... surfaceNameByCurrencyPair) {
super(ComputationTargetType.POSITION, true);
ArgumentChecker.notNull(interpolatorName, "interpolator name");
ArgumentChecker.notNull(leftExtrapolatorName, "left extrapolator name");
ArgumentChecker.notNull(rightExtrapolatorName, "right extrapolator name");
ArgumentChecker.notNull(surfaceNameByCurrencyPair, "property values by currency");
ArgumentChecker.isTrue(surfaceNameByCurrencyPair.length % 3 == 0, "Must have one surface name per currency pair");
_interpolatorName = interpolatorName;
_leftExtrapolatorName = leftExtrapolatorName;
_rightExtrapolatorName = rightExtrapolatorName;
_surfaceNameByCurrencyPair = new HashMap<Pair<String, String>, String>();
for (int i = 0; i < surfaceNameByCurrencyPair.length; i += 3) {
final String firstCurrency = surfaceNameByCurrencyPair[i];
final String secondCurrency = surfaceNameByCurrencyPair[i + 1];
ArgumentChecker.isFalse(firstCurrency.equals(secondCurrency), "The two currencies must not be equal; have {} and {}", firstCurrency, secondCurrency);
final String surfaceName = surfaceNameByCurrencyPair[i + 2];
_surfaceNameByCurrencyPair.put(Pairs.of(firstCurrency, secondCurrency), surfaceName);
}
}
@Override
public boolean canApplyTo(final FunctionCompilationContext context, final ComputationTarget target) {
if (!(target.getPosition().getSecurity() instanceof FinancialSecurity)) {
return false;
}
final FinancialSecurity security = (FinancialSecurity) target.getPosition().getSecurity();
final boolean isFXOption = (security instanceof FXOptionSecurity
|| security instanceof FXBarrierOptionSecurity
|| security instanceof FXDigitalOptionSecurity
|| security instanceof NonDeliverableFXOptionSecurity
|| security instanceof NonDeliverableFXDigitalOptionSecurity);
if (!isFXOption) {
return false;
}
final String putCurrency = security.accept(ForexVisitors.getPutCurrencyVisitor()).getCode();
final String callCurrency = security.accept(ForexVisitors.getCallCurrencyVisitor()).getCode();
final Pair<String, String> pair = Pairs.of(putCurrency, callCurrency);
if (_surfaceNameByCurrencyPair.containsKey(pair)) {
return true;
}
return _surfaceNameByCurrencyPair.containsKey(Pairs.of(callCurrency, putCurrency));
}
@Override
protected void getDefaults(final PropertyDefaults defaults) {
defaults.addValuePropertyName(ValueRequirementNames.PNL_SERIES, ValuePropertyNames.SURFACE);
defaults.addValuePropertyName(ValueRequirementNames.PNL_SERIES, InterpolatedDataProperties.X_INTERPOLATOR_NAME);
defaults.addValuePropertyName(ValueRequirementNames.PNL_SERIES, InterpolatedDataProperties.LEFT_X_EXTRAPOLATOR_NAME);
defaults.addValuePropertyName(ValueRequirementNames.PNL_SERIES, InterpolatedDataProperties.RIGHT_X_EXTRAPOLATOR_NAME);
}
@Override
protected Set<String> getDefaultValue(final FunctionCompilationContext context, final ComputationTarget target, final ValueRequirement desiredValue, final String propertyName) {
if (InterpolatedDataProperties.X_INTERPOLATOR_NAME.equals(propertyName)) {
return Collections.singleton(_interpolatorName);
}
if (InterpolatedDataProperties.LEFT_X_EXTRAPOLATOR_NAME.equals(propertyName)) {
return Collections.singleton(_leftExtrapolatorName);
}
if (InterpolatedDataProperties.RIGHT_X_EXTRAPOLATOR_NAME.equals(propertyName)) {
return Collections.singleton(_rightExtrapolatorName);
}
final FinancialSecurity security = (FinancialSecurity) target.getPosition().getSecurity();
final String putCurrency = security.accept(ForexVisitors.getPutCurrencyVisitor()).getCode();
final String callCurrency = security.accept(ForexVisitors.getCallCurrencyVisitor()).getCode();
if (ValuePropertyNames.SURFACE.equals(propertyName)) {
Pair<String, String> pair = Pairs.of(putCurrency, callCurrency);
if (_surfaceNameByCurrencyPair.containsKey(pair)) {
return Collections.singleton(_surfaceNameByCurrencyPair.get(pair));
}
pair = Pairs.of(callCurrency, putCurrency);
if (_surfaceNameByCurrencyPair.containsKey(pair)) {
return Collections.singleton(_surfaceNameByCurrencyPair.get(pair));
}
s_logger.error("Could not get surface name for currency pair {}, {}; should never happen", putCurrency, callCurrency);
}
return null;
}
@Override
public String getMutualExclusionGroup() {
return OpenGammaFunctionExclusions.PNL_SERIES;
}
}