/** * Copyright (C) 2013 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.financial.analytics.model.bondyield; import static com.opengamma.engine.value.ValuePropertyNames.CURVE; import static com.opengamma.engine.value.ValueRequirementNames.YIELD_CURVE; import static com.opengamma.engine.value.ValueRequirementNames.Z_SPREAD; import static com.opengamma.financial.analytics.model.curve.CurveCalculationPropertyNamesAndValues.PROPERTY_CURVE_TYPE; import java.util.Collections; import java.util.Set; import com.google.common.collect.Iterables; import com.opengamma.OpenGammaRuntimeException; import com.opengamma.analytics.financial.interestrate.bond.definition.BondFixedTransaction; import com.opengamma.analytics.financial.interestrate.bond.provider.BondSecurityDiscountingMethod; import com.opengamma.analytics.financial.legalentity.LegalEntity; import com.opengamma.analytics.financial.legalentity.LegalEntityFilter; import com.opengamma.analytics.financial.model.interestrate.curve.YieldAndDiscountCurve; import com.opengamma.analytics.financial.provider.description.interestrate.IssuerProvider; import com.opengamma.engine.ComputationTarget; import com.opengamma.engine.ComputationTargetSpecification; import com.opengamma.engine.function.FunctionCompilationContext; import com.opengamma.engine.function.FunctionInputs; import com.opengamma.engine.value.ComputedValue; import com.opengamma.engine.value.ValueProperties; import com.opengamma.engine.value.ValueRequirement; import com.opengamma.engine.value.ValueRequirementNames; import com.opengamma.engine.value.ValueSpecification; import com.opengamma.util.tuple.Pair; /** * Calculates the z-spread of a bond from the clean price. */ public class BondZSpreadFromYieldFunction extends BondFromYieldAndCurvesFunction { /** The z-spread calculator */ private static final BondSecurityDiscountingMethod CALCULATOR = BondSecurityDiscountingMethod.getInstance(); /** * Sets the value requirement name to {@link ValueRequirementNames#Z_SPREAD} */ public BondZSpreadFromYieldFunction() { super(Z_SPREAD); } @Override protected Set<ComputedValue> getResult(final FunctionInputs inputs, final BondFixedTransaction bond, final IssuerProvider issuerCurves, final double cleanPrice, final ValueSpecification spec) { final YieldAndDiscountCurve curve = (YieldAndDiscountCurve) inputs.getValue(YIELD_CURVE); final LegalEntity legalEntity = bond.getBondTransaction().getIssuerEntity(); final Set<Pair<Object, LegalEntityFilter<LegalEntity>>> keys = issuerCurves.getIssuers(); Pair<Object, LegalEntityFilter<LegalEntity>> keyOfCurveToReplace = null; for (final Pair<Object, LegalEntityFilter<LegalEntity>> key : keys) { if (key.getFirst().equals(key.getSecond().getFilteredData(legalEntity))) { keyOfCurveToReplace = key; break; } } if (keyOfCurveToReplace == null) { throw new OpenGammaRuntimeException("Could not find key for " + legalEntity); } final IssuerProvider curvesWithReplacement = issuerCurves.withIssuerCurve(keyOfCurveToReplace, curve); final double zSpread = 10000 * CALCULATOR.zSpreadFromCurvesAndYield(bond.getBondTransaction(), curvesWithReplacement, cleanPrice); return Collections.singleton(new ComputedValue(spec, zSpread)); } @Override public Set<ValueRequirement> getRequirements(final FunctionCompilationContext context, final ComputationTarget target, final ValueRequirement desiredValue) { final ValueProperties constraints = desiredValue.getConstraints(); final Set<String> curves = constraints.getValues(CURVE); if (curves == null || curves.size() != 1) { return null; } final Set<ValueRequirement> requirements = super.getRequirements(context, target, desiredValue); if (requirements == null) { return null; } final String curve = Iterables.getOnlyElement(curves); final ValueProperties curveProperties = ValueProperties.builder() .with(CURVE, curve) .with(PROPERTY_CURVE_TYPE, constraints.getValues(PROPERTY_CURVE_TYPE)) .get(); requirements.add(new ValueRequirement(YIELD_CURVE, ComputationTargetSpecification.NULL, curveProperties)); return requirements; } @Override protected ValueProperties.Builder getResultProperties(final ComputationTarget target) { return super.getResultProperties(target) .withAny(CURVE); } }