Package com.opengamma.financial.analytics.model.curve

Source Code of com.opengamma.financial.analytics.model.curve.ISDACompliantCurveFunction

/*
* Copyright (C) 2013 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/

package com.opengamma.financial.analytics.model.curve;

import static com.opengamma.engine.value.ValuePropertyNames.CURVE;
import static com.opengamma.engine.value.ValueRequirementNames.CURVE_DEFINITION;
import static com.opengamma.engine.value.ValueRequirementNames.CURVE_MARKET_DATA;
import static com.opengamma.engine.value.ValueRequirementNames.CURVE_SPECIFICATION;

import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

import org.threeten.bp.Clock;
import org.threeten.bp.LocalDate;
import org.threeten.bp.Period;
import org.threeten.bp.ZonedDateTime;

import com.opengamma.OpenGammaRuntimeException;
import com.opengamma.analytics.financial.credit.creditdefaultswap.pricing.vanilla.isdanew.ISDACompliantYieldCurve;
import com.opengamma.analytics.financial.credit.creditdefaultswap.pricing.vanilla.isdanew.ISDACompliantYieldCurveBuild;
import com.opengamma.analytics.financial.credit.isdayieldcurve.ISDAInstrumentTypes;
import com.opengamma.core.marketdatasnapshot.SnapshotDataBundle;
import com.opengamma.engine.ComputationTarget;
import com.opengamma.engine.ComputationTargetSpecification;
import com.opengamma.engine.function.AbstractFunction;
import com.opengamma.engine.function.FunctionCompilationContext;
import com.opengamma.engine.function.FunctionExecutionContext;
import com.opengamma.engine.function.FunctionInputs;
import com.opengamma.engine.target.ComputationTargetType;
import com.opengamma.engine.value.ComputedValue;
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.engine.value.ValueSpecification;
import com.opengamma.financial.OpenGammaExecutionContext;
import com.opengamma.financial.analytics.curve.CurveSpecification;
import com.opengamma.financial.analytics.ircurve.strips.CashNode;
import com.opengamma.financial.analytics.ircurve.strips.CurveNodeWithIdentifier;
import com.opengamma.financial.analytics.ircurve.strips.SwapNode;
import com.opengamma.financial.analytics.model.cds.ISDAFunctionConstants;
import com.opengamma.financial.convention.Convention;
import com.opengamma.financial.convention.ConventionSource;
import com.opengamma.financial.convention.DepositConvention;
import com.opengamma.financial.convention.IborIndexConvention;
import com.opengamma.financial.convention.SwapFixedLegConvention;
import com.opengamma.financial.convention.VanillaIborLegConvention;
import com.opengamma.financial.convention.daycount.DayCount;
import com.opengamma.financial.convention.daycount.DayCountFactory;
import com.opengamma.id.ExternalId;
import com.opengamma.util.ArgumentChecker;
import com.opengamma.util.async.AsynchronousExecution;

/**
* Produces an ISDA compatible yield curve
*/
// non compiled for now to allow dynamic config db lookup
public class ISDACompliantCurveFunction extends AbstractFunction.NonCompiledInvoker {

  /** ISDA fixes yield curve daycout to Act/365 */
  private static final DayCount ACT_365 = DayCountFactory.INSTANCE.getDayCount("ACT/365");

  /** the curve configuration name */
  private final String _curveName;

  /**
   * The name of the curve produced by this function.
   * @param curveName The curve name, not null
   */
  public ISDACompliantCurveFunction(final String curveName) {
    ArgumentChecker.notNull(curveName, "curve name");
    _curveName = curveName;
  }

  @Override
  public Set<ComputedValue> execute(final FunctionExecutionContext executionContext, final FunctionInputs inputs, final ComputationTarget target,
                                    final Set<ValueRequirement> desiredValues) throws AsynchronousExecution {
    final Clock snapshotClock = executionContext.getValuationClock();
    final ValueRequirement desiredValue = desiredValues.iterator().next();
    final ZonedDateTime now = ZonedDateTime.now(snapshotClock);
    final ConventionSource conventionSource = OpenGammaExecutionContext.getConventionSource(executionContext);

    final CurveSpecification specification = (CurveSpecification) inputs.getValue(ValueRequirementNames.CURVE_SPECIFICATION);
    final SnapshotDataBundle snapshot = (SnapshotDataBundle) inputs.getValue(ValueRequirementNames.CURVE_MARKET_DATA);
    final LocalDate spotDate = (!desiredValue.getConstraints().getValues(ISDAFunctionConstants.ISDA_CURVE_DATE).isEmpty())
        ? LocalDate.parse(desiredValue.getConstraint(ISDAFunctionConstants.ISDA_CURVE_DATE))
        : now.toLocalDate();

    DepositConvention cashConvention = null;
    VanillaIborLegConvention floatLegConvention = null;
    SwapFixedLegConvention fixLegConvention = null;
    IborIndexConvention liborConvention = null;

    final int nNodes = specification.getNodes().size();
    final double[] marketDataForCurve = new double[nNodes];
    final ISDAInstrumentTypes[] instruments = new ISDAInstrumentTypes[nNodes];
    final Period[] tenors = new Period[nNodes];
    int k = 0;
    for (final CurveNodeWithIdentifier node : specification.getNodes()) {
      final Double marketData = snapshot.getDataPoint(node.getIdentifier());
      if (marketData == null) {
        throw new OpenGammaRuntimeException("Could not get market data for " + node.getIdentifier());
      }
      marketDataForCurve[k] = marketData;
      tenors[k] = node.getCurveNode().getResolvedMaturity().getPeriod();
      if (node.getCurveNode() instanceof CashNode) {
        instruments[k] = ISDAInstrumentTypes.MoneyMarket;
        final ExternalId cashConventionId = ((CashNode) node.getCurveNode()).getConvention();
        if (cashConvention == null) {
          cashConvention = conventionSource.getConvention(DepositConvention.class, cashConventionId);
        } else if (!cashConvention.getExternalIdBundle().contains(cashConventionId)) {
          throw new OpenGammaRuntimeException("Got 2 types of cash convention: " + cashConvention.getExternalIdBundle() + " " + cashConventionId);
        }
      } else if (node.getCurveNode() instanceof SwapNode) {
        instruments[k] = ISDAInstrumentTypes.Swap;
        final ExternalId payConventionId = ((SwapNode) node.getCurveNode()).getPayLegConvention();
        final Convention payConvention = conventionSource.getConvention(payConventionId);
        if (payConvention == null) {
          throw new OpenGammaRuntimeException("Convention '" + payConventionId + "' not found");
        }
        final ExternalId receiveConventionId = ((SwapNode) node.getCurveNode()).getReceiveLegConvention();
        final Convention receiveConvention = conventionSource.getConvention(receiveConventionId);
        if (receiveConvention == null) {
          throw new OpenGammaRuntimeException("Convention '" + receiveConventionId + "' not found");
        }
        if (payConvention instanceof VanillaIborLegConvention) {  // float leg
          if (floatLegConvention == null) {
            floatLegConvention = (VanillaIborLegConvention) payConvention;
          } else if (!floatLegConvention.getExternalIdBundle().contains(payConventionId)) {
            throw new OpenGammaRuntimeException("Got 2 types of float leg convention: " + payConvention.getExternalIdBundle() + " " + payConventionId);
          }
        } else if (payConvention instanceof SwapFixedLegConvention) {
          if (fixLegConvention == null) {
            fixLegConvention = (SwapFixedLegConvention) payConvention;
          } else if (!fixLegConvention.getExternalIdBundle().contains(payConventionId)) {
            throw new OpenGammaRuntimeException("Got 2 types of fixed leg convention: " + payConvention.getExternalIdBundle() + " " + payConventionId);
          }
        } else {
          throw new OpenGammaRuntimeException("Unexpected swap convention type: " + payConvention);
        }
        if (receiveConvention instanceof VanillaIborLegConvention) {  // float leg
          if (floatLegConvention == null) {
            floatLegConvention = (VanillaIborLegConvention) receiveConvention;
          } else if (!floatLegConvention.getExternalIdBundle().contains(receiveConventionId)) {
            throw new OpenGammaRuntimeException("Got 2 types of float leg convention: " + receiveConvention.getExternalIdBundle() + " " + receiveConventionId);
          }
        } else if (receiveConvention instanceof SwapFixedLegConvention) {
          if (fixLegConvention == null) {
            fixLegConvention = (SwapFixedLegConvention) receiveConvention;
          } else if (!fixLegConvention.getExternalIdBundle().contains(receiveConventionId)) {
            throw new OpenGammaRuntimeException("Got 2 types of fixed leg convention: " + receiveConvention.getExternalIdBundle() + " " + receiveConventionId);
          }
        } else {
          throw new OpenGammaRuntimeException("Unexpected swap convention type: " + receiveConvention);
        }
      } else {
        throw new OpenGammaRuntimeException("Can't handle node type " + node.getCurveNode().getClass().getSimpleName() + " at node " + node);
      }
      k++;
    }

    ArgumentChecker.notNull(cashConvention, "Cash convention");
    ArgumentChecker.notNull(floatLegConvention, "Floating leg convention");
    ArgumentChecker.notNull(fixLegConvention, "Fixed leg convention");
    liborConvention = conventionSource.getConvention(IborIndexConvention.class, floatLegConvention.getIborIndexConvention());
    ArgumentChecker.notNull(liborConvention, floatLegConvention.getIborIndexConvention().toString());

    final ISDACompliantYieldCurve yieldCurve = ISDACompliantYieldCurveBuild.build(spotDate, spotDate, instruments, tenors, marketDataForCurve, cashConvention.getDayCount(),
        fixLegConvention.getDayCount(), fixLegConvention.getPaymentTenor().getPeriod(), ACT_365, liborConvention.getBusinessDayConvention());

    final ValueProperties properties = desiredValue.getConstraints().copy()
        .with(ISDAFunctionConstants.ISDA_CURVE_DATE, spotDate.toString())
        .get();

    final ValueSpecification spec = new ValueSpecification(ValueRequirementNames.YIELD_CURVE, target.toSpecification(), properties);
    return Collections.singleton(new ComputedValue(spec, yieldCurve));
  }

  @Override
  public ComputationTargetType getTargetType() {
    return ComputationTargetType.NULL;
  }

  @Override
  public Set<ValueSpecification> getResults(final FunctionCompilationContext context, final ComputationTarget target) {
    final ValueProperties properties = createValueProperties()
        .with(ValuePropertyNames.CURVE, _curveName)
        .with(ISDAFunctionConstants.ISDA_IMPLEMENTATION, ISDAFunctionConstants.ISDA_IMPLEMENTATION_NEW)
        .with(ValuePropertyNames.CURVE_CALCULATION_METHOD, ISDAFunctionConstants.ISDA_METHOD_NAME)
        .withAny(ISDAFunctionConstants.ISDA_CURVE_DATE)
        .get();
    return Collections.singleton(new ValueSpecification(ValueRequirementNames.YIELD_CURVE,
                                                        target.toSpecification(),
                                                        properties));
  }

  @Override
  public Set<ValueRequirement> getRequirements(final FunctionCompilationContext compilationContext, final ComputationTarget target, final ValueRequirement desiredValue) {
    final Set<ValueRequirement> requirements = new HashSet<>();
    final ValueProperties properties = ValueProperties.builder()
        .with(CURVE, _curveName)
        .get();
    requirements.add(new ValueRequirement(CURVE_DEFINITION, ComputationTargetSpecification.NULL, properties));
    requirements.add(new ValueRequirement(CURVE_MARKET_DATA, ComputationTargetSpecification.NULL, properties));
    requirements.add(new ValueRequirement(CURVE_SPECIFICATION, ComputationTargetSpecification.NULL, properties));
    return requirements;
  }

}
TOP

Related Classes of com.opengamma.financial.analytics.model.curve.ISDACompliantCurveFunction

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.