/**
* Copyright (C) 2012 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.financial.analytics.model.volatility.surface;
import static com.opengamma.financial.analytics.model.InterpolatedDataProperties.LEFT_X_EXTRAPOLATOR_NAME;
import static com.opengamma.financial.analytics.model.InterpolatedDataProperties.LEFT_Y_EXTRAPOLATOR_NAME;
import static com.opengamma.financial.analytics.model.InterpolatedDataProperties.RIGHT_X_EXTRAPOLATOR_NAME;
import static com.opengamma.financial.analytics.model.InterpolatedDataProperties.RIGHT_Y_EXTRAPOLATOR_NAME;
import static com.opengamma.financial.analytics.model.InterpolatedDataProperties.X_INTERPOLATOR_NAME;
import static com.opengamma.financial.analytics.model.InterpolatedDataProperties.Y_INTERPOLATOR_NAME;
import static com.opengamma.financial.analytics.model.volatility.surface.SABRFittingProperties.PROPERTY_ALPHA;
import static com.opengamma.financial.analytics.model.volatility.surface.SABRFittingProperties.PROPERTY_BETA;
import static com.opengamma.financial.analytics.model.volatility.surface.SABRFittingProperties.PROPERTY_ERROR;
import static com.opengamma.financial.analytics.model.volatility.surface.SABRFittingProperties.PROPERTY_NU;
import static com.opengamma.financial.analytics.model.volatility.surface.SABRFittingProperties.PROPERTY_RHO;
import static com.opengamma.financial.analytics.model.volatility.surface.SABRFittingProperties.PROPERTY_USE_FIXED_ALPHA;
import static com.opengamma.financial.analytics.model.volatility.surface.SABRFittingProperties.PROPERTY_USE_FIXED_BETA;
import static com.opengamma.financial.analytics.model.volatility.surface.SABRFittingProperties.PROPERTY_USE_FIXED_NU;
import static com.opengamma.financial.analytics.model.volatility.surface.SABRFittingProperties.PROPERTY_USE_FIXED_RHO;
import java.util.BitSet;
import java.util.Set;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.opengamma.analytics.math.interpolation.CombinedInterpolatorExtrapolatorFactory;
import com.opengamma.analytics.math.interpolation.GridInterpolator2D;
import com.opengamma.analytics.math.interpolation.Interpolator1D;
import com.opengamma.analytics.math.interpolation.Interpolator2D;
import com.opengamma.analytics.math.matrix.DoubleMatrix1D;
import com.opengamma.engine.ComputationTargetSpecification;
import com.opengamma.engine.value.ValueProperties;
import com.opengamma.engine.value.ValuePropertyNames;
import com.opengamma.engine.value.ValueRequirement;
import com.opengamma.engine.value.ValueRequirementNames;
import com.opengamma.financial.analytics.model.InstrumentTypeProperties;
import com.opengamma.financial.analytics.model.volatility.SmileFittingPropertyNamesAndValues;
import com.opengamma.util.money.Currency;
/**
*
*/
public class SABRFittingPropertyUtils {
/** The logger */
private static final Logger s_logger = LoggerFactory.getLogger(SABRFittingPropertyUtils.class);
public static ValueProperties.Builder addNLSSFittingProperties(final ValueProperties.Builder properties) {
return properties
.withAny(X_INTERPOLATOR_NAME)
.withAny(Y_INTERPOLATOR_NAME)
.withAny(LEFT_X_EXTRAPOLATOR_NAME)
.withAny(LEFT_Y_EXTRAPOLATOR_NAME)
.withAny(RIGHT_X_EXTRAPOLATOR_NAME)
.withAny(RIGHT_Y_EXTRAPOLATOR_NAME)
.withAny(PROPERTY_ALPHA)
.withAny(PROPERTY_BETA)
.withAny(PROPERTY_NU)
.withAny(PROPERTY_RHO)
.withAny(PROPERTY_USE_FIXED_ALPHA)
.withAny(PROPERTY_USE_FIXED_BETA)
.withAny(PROPERTY_USE_FIXED_NU)
.withAny(PROPERTY_USE_FIXED_RHO)
.withAny(PROPERTY_ERROR);
}
public static boolean ensureNLSSFittingProperties(final ValueRequirement desiredValue) {
final ValueProperties constraints = desiredValue.getConstraints();
final Set<String> xInterpolatorName = constraints.getValues(X_INTERPOLATOR_NAME);
if (xInterpolatorName == null || xInterpolatorName.size() != 1) {
return false;
}
final Set<String> yInterpolatorName = constraints.getValues(Y_INTERPOLATOR_NAME);
if (yInterpolatorName == null || yInterpolatorName.size() != 1) {
return false;
}
final Set<String> leftXExtrapolatorName = constraints.getValues(LEFT_X_EXTRAPOLATOR_NAME);
if (leftXExtrapolatorName == null || leftXExtrapolatorName.size() != 1) {
return false;
}
final Set<String> leftYExtrapolatorName = constraints.getValues(LEFT_Y_EXTRAPOLATOR_NAME);
if (leftYExtrapolatorName == null || leftYExtrapolatorName.size() != 1) {
return false;
}
final Set<String> rightXExtrapolatorName = constraints.getValues(RIGHT_X_EXTRAPOLATOR_NAME);
if (rightXExtrapolatorName == null || rightXExtrapolatorName.size() != 1) {
return false;
}
final Set<String> rightYExtrapolatorName = constraints.getValues(RIGHT_Y_EXTRAPOLATOR_NAME);
if (rightYExtrapolatorName == null || rightYExtrapolatorName.size() != 1) {
return false;
}
final Set<String> useFixedAlpha = constraints.getValues(PROPERTY_USE_FIXED_ALPHA);
if (useFixedAlpha == null || useFixedAlpha.size() != 1) {
return false;
}
final Set<String> useFixedBeta = constraints.getValues(PROPERTY_USE_FIXED_BETA);
if (useFixedBeta == null || useFixedBeta.size() != 1) {
return false;
}
final Set<String> useFixedNu = constraints.getValues(PROPERTY_USE_FIXED_NU);
if (useFixedNu == null || useFixedNu.size() != 1) {
return false;
}
final Set<String> useFixedRho = constraints.getValues(PROPERTY_USE_FIXED_RHO);
if (useFixedRho == null || useFixedRho.size() != 1) {
return false;
}
final Set<String> alpha = constraints.getValues(PROPERTY_ALPHA);
if (alpha == null || alpha.size() != 1) {
return false;
}
final Set<String> beta = constraints.getValues(PROPERTY_BETA);
if (beta == null || beta.size() != 1) {
return false;
}
final Set<String> nu = constraints.getValues(PROPERTY_NU);
if (nu == null || nu.size() != 1) {
return false;
}
final Set<String> rho = constraints.getValues(PROPERTY_RHO);
if (rho == null || rho.size() != 1) {
return false;
}
final Set<String> errors = constraints.getValues(PROPERTY_ERROR);
if (errors == null || errors.size() != 1) {
return false;
}
return true;
}
public static ValueRequirement getSurfaceRequirement(final ValueRequirement desiredValue, final String surfaceName, final Currency currency,
final String instrumentType) {
final ValueProperties constraints = desiredValue.getConstraints();
final String fittingMethod = desiredValue.getConstraint(SmileFittingPropertyNamesAndValues.PROPERTY_FITTING_METHOD);
if (fittingMethod == null) {
s_logger.error("No value set for SABR fitting method");
return null;
}
if (fittingMethod.equals(SmileFittingPropertyNamesAndValues.NON_LINEAR_LEAST_SQUARES)) {
final ValueProperties.Builder allProperties = addNLSSFittingProperties(ValueProperties.builder())
.with(ValuePropertyNames.CURRENCY, currency.getCode())
.with(ValuePropertyNames.SURFACE, surfaceName)
.with(InstrumentTypeProperties.PROPERTY_SURFACE_INSTRUMENT_TYPE, instrumentType)
.with(SmileFittingPropertyNamesAndValues.PROPERTY_VOLATILITY_MODEL, SmileFittingPropertyNamesAndValues.SABR)
.with(SmileFittingPropertyNamesAndValues.PROPERTY_FITTING_METHOD, SmileFittingPropertyNamesAndValues.NON_LINEAR_LEAST_SQUARES);
for (final String constraint : constraints.getProperties()) {
if (!constraints.getValues(constraint).isEmpty() && allProperties.get().getProperties().contains(constraint)) {
allProperties
.withoutAny(constraint)
.with(constraint, constraints.getValues(constraint));
}
}
return new ValueRequirement(ValueRequirementNames.SABR_SURFACES, ComputationTargetSpecification.of(currency), allProperties.get());
}
s_logger.error("Could not handle fitting method {}", fittingMethod);
return null;
}
public static DoubleMatrix1D getStartingValues(final ValueRequirement desiredValue) {
final double alpha = Double.parseDouble(desiredValue.getConstraint(PROPERTY_ALPHA));
final double beta = Double.parseDouble(desiredValue.getConstraint(PROPERTY_BETA));
final double rho = Double.parseDouble(desiredValue.getConstraint(PROPERTY_RHO));
final double nu = Double.parseDouble(desiredValue.getConstraint(PROPERTY_NU));
return new DoubleMatrix1D(new double[] {alpha, beta, rho, nu});
}
public static BitSet getFixedValues(final ValueRequirement desiredValue) {
final BitSet result = new BitSet(4);
if (Boolean.parseBoolean(desiredValue.getConstraint(PROPERTY_USE_FIXED_ALPHA))) {
result.set(0);
}
if (Boolean.parseBoolean(desiredValue.getConstraint(PROPERTY_USE_FIXED_BETA))) {
result.set(1);
}
if (Boolean.parseBoolean(desiredValue.getConstraint(PROPERTY_USE_FIXED_RHO))) {
result.set(2);
}
if (Boolean.parseBoolean(desiredValue.getConstraint(PROPERTY_USE_FIXED_NU))) {
result.set(3);
}
return result;
}
public static Interpolator2D getInterpolator(final ValueRequirement desiredValue) {
final String xInterpolatorName = desiredValue.getConstraint(X_INTERPOLATOR_NAME);
final String yInterpolatorName = desiredValue.getConstraint(Y_INTERPOLATOR_NAME);
final String leftXExtrapolatorName = desiredValue.getConstraint(LEFT_X_EXTRAPOLATOR_NAME);
final String rightXExtrapolatorName = desiredValue.getConstraint(RIGHT_X_EXTRAPOLATOR_NAME);
final String leftYExtrapolatorName = desiredValue.getConstraint(LEFT_Y_EXTRAPOLATOR_NAME);
final String rightYExtrapolatorName = desiredValue.getConstraint(RIGHT_Y_EXTRAPOLATOR_NAME);
final Interpolator1D xInterpolator = CombinedInterpolatorExtrapolatorFactory.getInterpolator(xInterpolatorName, leftXExtrapolatorName, rightXExtrapolatorName);
final Interpolator1D yInterpolator = CombinedInterpolatorExtrapolatorFactory.getInterpolator(yInterpolatorName, leftYExtrapolatorName, rightYExtrapolatorName);
return new GridInterpolator2D(xInterpolator, yInterpolator);
}
}