Package com.opengamma.analytics.financial.provider.sensitivity.issuer

Source Code of com.opengamma.analytics.financial.provider.sensitivity.issuer.SimpleParameterSensitivityHullWhiteIssuerDiscountInterpolatedFDCalculator

/**
* Copyright (C) 2012 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.analytics.financial.provider.sensitivity.issuer;

import java.util.Set;

import com.opengamma.analytics.financial.instrument.index.IborIndex;
import com.opengamma.analytics.financial.instrument.index.IndexON;
import com.opengamma.analytics.financial.interestrate.InstrumentDerivative;
import com.opengamma.analytics.financial.interestrate.InstrumentDerivativeVisitor;
import com.opengamma.analytics.financial.model.interestrate.curve.YieldAndDiscountCurve;
import com.opengamma.analytics.financial.model.interestrate.curve.YieldCurve;
import com.opengamma.analytics.financial.provider.description.interestrate.HullWhiteIssuerProviderDiscount;
import com.opengamma.analytics.financial.provider.description.interestrate.HullWhiteIssuerProviderInterface;
import com.opengamma.analytics.financial.provider.description.interestrate.IssuerProviderDiscount;
import com.opengamma.analytics.financial.provider.sensitivity.multicurve.SimpleParameterSensitivity;
import com.opengamma.analytics.math.curve.InterpolatedDoublesCurve;
import com.opengamma.analytics.math.matrix.DoubleMatrix1D;
import com.opengamma.util.ArgumentChecker;
import com.opengamma.util.money.Currency;
import com.opengamma.util.tuple.Pair;

/**
* For an instrument, computes the sensitivity of a value (often the par spread) to the parameters used in the curve.
* The computation is done by shifting each node point in each curve; the curves must be interpolated yield curves for discounting and forward curves.
* The return format is SimpleParameterSensitivity object.
* This is a very inefficient way to compute the sensitivities. It should be used only for tests purposes or when speed is irrelevant.
*/
public class SimpleParameterSensitivityHullWhiteIssuerDiscountInterpolatedFDCalculator {

  /**
   * The value calculator.
   */
  private final InstrumentDerivativeVisitor<HullWhiteIssuerProviderInterface, Double> _valueCalculator;
  /**
   * The shift used for finite difference.
   */
  private final double _shift;

  /**
   * Constructor
   * @param valueCalculator The value calculator.
   * @param shift The shift used for finite difference.
   */
  public SimpleParameterSensitivityHullWhiteIssuerDiscountInterpolatedFDCalculator(final InstrumentDerivativeVisitor<HullWhiteIssuerProviderInterface, Double> valueCalculator, final double shift) {
    ArgumentChecker.notNull(valueCalculator, "Calculator");
    _valueCalculator = valueCalculator;
    _shift = shift;
  }

  /**
   * Compute the sensitivity by finite difference on all points. The curves must be interpolated yield curves.
   * Only the discounting and forward curves sensitivity is computed.
   * @param instrument The instrument.
   * @param issuercurves The provider: all discounting, forward and issuer curves should be of the type YieldCurve with InterpolatedDoublesCurve.
   * @return The parameter sensitivity.
   */
  public SimpleParameterSensitivity calculateSensitivity(final InstrumentDerivative instrument, final HullWhiteIssuerProviderDiscount issuercurves) {
    SimpleParameterSensitivity result = new SimpleParameterSensitivity();
    final Double valueInit = instrument.accept(_valueCalculator, issuercurves);
    final Double valueInitMinus = -valueInit;
    // Discounting
    final Set<Currency> ccyDiscounting = issuercurves.getMulticurveProvider().getCurrencies();
    for (final Currency ccy : ccyDiscounting) {
      final YieldAndDiscountCurve curve = issuercurves.getMulticurveProvider().getCurve(ccy);
      ArgumentChecker.isTrue(curve instanceof YieldCurve, "Curve should be a YieldCurve");
      final YieldCurve curveYield = (YieldCurve) curve;
      ArgumentChecker.isTrue(curveYield.getCurve() instanceof InterpolatedDoublesCurve, "Yield curve should be based on InterpolatedDoublesCurve");
      final InterpolatedDoublesCurve curveInt = (InterpolatedDoublesCurve) curveYield.getCurve();
      final int nbNodePoint = curveInt.getXDataAsPrimitive().length;
      final double[] sensitivity = new double[nbNodePoint];
      for (int loopnode = 0; loopnode < nbNodePoint; loopnode++) {
        final double[] yieldBumped = curveInt.getYDataAsPrimitive().clone();
        yieldBumped[loopnode] += _shift;
        final YieldAndDiscountCurve dscBumped = new YieldCurve(curveInt.getName(), new InterpolatedDoublesCurve(curveInt.getXDataAsPrimitive(), yieldBumped, curveInt.getInterpolator(), true));
        final HullWhiteIssuerProviderDiscount marketDscBumped = new HullWhiteIssuerProviderDiscount(new IssuerProviderDiscount(issuercurves.getMulticurveProvider().withDiscountFactor(ccy, dscBumped),
            issuercurves.getIssuerProvider().getIssuerCurves()), issuercurves.getHullWhiteParameters(), issuercurves.getHullWhiteIssuerCurrency());
        final Double valueBumped = instrument.accept(_valueCalculator, marketDscBumped);
        final Double valueDiff = valueBumped + valueInitMinus;
        sensitivity[loopnode] = valueDiff / _shift;
      }
      final String name = issuercurves.getMulticurveProvider().getName(ccy);
      result = result.plus(name, new DoubleMatrix1D(sensitivity));
    }
    // Forward ON
    final Set<IndexON> indexON = issuercurves.getMulticurveProvider().getIndexesON();
    for (final IndexON index : indexON) {
      final YieldAndDiscountCurve curve = issuercurves.getMulticurveProvider().getCurve(index);
      ArgumentChecker.isTrue(curve instanceof YieldCurve, "Curve should be a YieldCurve");
      final YieldCurve curveYield = (YieldCurve) curve;
      ArgumentChecker.isTrue(curveYield.getCurve() instanceof InterpolatedDoublesCurve, "Yield curve should be based on InterpolatedDoublesCurve");
      final InterpolatedDoublesCurve curveInt = (InterpolatedDoublesCurve) curveYield.getCurve();
      final int nbNodePoint = curveInt.getXDataAsPrimitive().length;
      final double[] sensitivity = new double[nbNodePoint];
      for (int loopnode = 0; loopnode < nbNodePoint; loopnode++) {
        final double[] yieldBumped = curveInt.getYDataAsPrimitive().clone();
        yieldBumped[loopnode] += _shift;
        final YieldAndDiscountCurve fwdBumped = new YieldCurve(curveInt.getName(), new InterpolatedDoublesCurve(curveInt.getXDataAsPrimitive(), yieldBumped, curveInt.getInterpolator(), true));
        final HullWhiteIssuerProviderDiscount marketFwdBumped = new HullWhiteIssuerProviderDiscount(new IssuerProviderDiscount(issuercurves.getMulticurveProvider().withForward(index, fwdBumped),
            issuercurves.getIssuerProvider().getIssuerCurves()), issuercurves.getHullWhiteParameters(), issuercurves.getHullWhiteIssuerCurrency());
        final Double valueBumped = instrument.accept(_valueCalculator, marketFwdBumped);
        final Double valueDiff = valueBumped + valueInitMinus;
        sensitivity[loopnode] = valueDiff / _shift;
      }
      final String name = issuercurves.getMulticurveProvider().getName(index);
      result = result.plus(name, new DoubleMatrix1D(sensitivity));
    }
    // Forward Ibor - symmetrical
    final Set<IborIndex> indexForward = issuercurves.getMulticurveProvider().getIndexesIbor();
    for (final IborIndex index : indexForward) {
      final YieldAndDiscountCurve curve = issuercurves.getMulticurveProvider().getCurve(index);
      ArgumentChecker.isTrue(curve instanceof YieldCurve, "Curve should be a YieldCurve");
      final YieldCurve curveYield = (YieldCurve) curve;
      ArgumentChecker.isTrue(curveYield.getCurve() instanceof InterpolatedDoublesCurve, "Yield curve should be based on InterpolatedDoublesCurve");
      final InterpolatedDoublesCurve curveInt = (InterpolatedDoublesCurve) curveYield.getCurve();
      final int nbNodePoint = curveInt.getXDataAsPrimitive().length;
      final double[] sensitivity = new double[nbNodePoint];
      for (int loopnode = 0; loopnode < nbNodePoint; loopnode++) {
        final double[] yieldBumpedPlus = curveInt.getYDataAsPrimitive().clone();
        yieldBumpedPlus[loopnode] += _shift;
        final YieldAndDiscountCurve fwdBumpedPlus = new YieldCurve(curveInt.getName(), new InterpolatedDoublesCurve(curveInt.getXDataAsPrimitive(), yieldBumpedPlus, curveInt.getInterpolator(), true));
        final HullWhiteIssuerProviderDiscount marketFwdBumpedPlus = new HullWhiteIssuerProviderDiscount(new IssuerProviderDiscount(issuercurves.getMulticurveProvider().withForward(index,
            fwdBumpedPlus),
            issuercurves.getIssuerProvider().getIssuerCurves()), issuercurves.getHullWhiteParameters(), issuercurves.getHullWhiteIssuerCurrency());
        final Double valueBumpedPlus = instrument.accept(_valueCalculator, marketFwdBumpedPlus);
        final double[] yieldBumpedMinus = curveInt.getYDataAsPrimitive().clone();
        yieldBumpedMinus[loopnode] -= _shift;
        final YieldAndDiscountCurve fwdBumpedMinus = new YieldCurve(curveInt.getName(),
            new InterpolatedDoublesCurve(curveInt.getXDataAsPrimitive(), yieldBumpedMinus, curveInt.getInterpolator(), true));
        final HullWhiteIssuerProviderDiscount marketFwdBumpedMinus = new HullWhiteIssuerProviderDiscount(new IssuerProviderDiscount(issuercurves.getMulticurveProvider().withForward(index,
            fwdBumpedMinus),
            issuercurves.getIssuerProvider().getIssuerCurves()), issuercurves.getHullWhiteParameters(), issuercurves.getHullWhiteIssuerCurrency());
        final Double valueBumpedMinus = instrument.accept(_valueCalculator, marketFwdBumpedMinus);
        final Double valueDiff = valueBumpedPlus - valueBumpedMinus;
        sensitivity[loopnode] = valueDiff / (2 * _shift);
      }
      final String name = issuercurves.getMulticurveProvider().getName(index);
      result = result.plus(name, new DoubleMatrix1D(sensitivity));
    }
    // Discounting issuer
    final Set<Pair<String, Currency>> issuerCcies = issuercurves.getIssuerProvider().getIssuersCurrencies();
    for (final Pair<String, Currency> ic : issuerCcies) {
      final YieldAndDiscountCurve curve = issuercurves.getIssuerProvider().getCurve(ic);
      ArgumentChecker.isTrue(curve instanceof YieldCurve, "Curve should be a YieldCurve");
      final YieldCurve curveYield = (YieldCurve) curve;
      ArgumentChecker.isTrue(curveYield.getCurve() instanceof InterpolatedDoublesCurve, "Yield curve should be based on InterpolatedDoublesCurve");
      final InterpolatedDoublesCurve curveInt = (InterpolatedDoublesCurve) curveYield.getCurve();
      final int nbNodePoint = curveInt.getXDataAsPrimitive().length;
      final double[] sensitivity = new double[nbNodePoint];
      for (int loopnode = 0; loopnode < nbNodePoint; loopnode++) {
        final double[] yieldBumped = curveInt.getYDataAsPrimitive().clone();
        yieldBumped[loopnode] += _shift;
        final YieldAndDiscountCurve icBumped = new YieldCurve(curveInt.getName(), new InterpolatedDoublesCurve(curveInt.getXDataAsPrimitive(), yieldBumped, curveInt.getInterpolator(), true));
        final HullWhiteIssuerProviderDiscount providerIcBumped = new HullWhiteIssuerProviderDiscount(issuercurves.getIssuerProvider().withIssuerCurrency(ic, icBumped),
            issuercurves.getHullWhiteParameters(), issuercurves.getHullWhiteIssuerCurrency());
        final Double valueBumped = instrument.accept(_valueCalculator, providerIcBumped);
        final Double valueDiff = valueBumped + valueInitMinus;
        sensitivity[loopnode] = valueDiff / _shift;
      }
      final String name = issuercurves.getIssuerProvider().getName(ic);
      result = result.plus(name, new DoubleMatrix1D(sensitivity));
    }
    return result;
  }
}
TOP

Related Classes of com.opengamma.analytics.financial.provider.sensitivity.issuer.SimpleParameterSensitivityHullWhiteIssuerDiscountInterpolatedFDCalculator

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.