/** * Copyright (C) 2011 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.analytics.financial.interestrate.method; import org.apache.commons.lang.Validate; import com.opengamma.analytics.financial.interestrate.InstrumentDerivative; import com.opengamma.analytics.financial.interestrate.YieldCurveBundle; import com.opengamma.analytics.financial.model.interestrate.curve.YieldAndDiscountCurve; import com.opengamma.analytics.financial.model.interestrate.curve.YieldCurve; import com.opengamma.analytics.math.curve.InterpolatedDoublesCurve; import com.opengamma.analytics.math.differentiation.FiniteDifferenceType; import com.opengamma.analytics.math.interpolation.LinearInterpolator1D; /** * Class used to compute interest rate instrument sensitivity by finite difference. * @deprecated {@link YieldCurveBundle} is deprecated */ @Deprecated public class SensitivityFiniteDifference { /** * Compute the present value rate sensitivity for a set of node time by finite difference. * @param instrument The instrument. * @param curves The yield curve bundle. The bumped curve will be added to the curve bundle. * @param pv The initial instrument present value. * @param curveToBumpName The name of the curve to bump. * @param curveBumpedName The name of the curve after bumped. The name should be used in the instrument construction. * @param nodeTimes The node times to be bumped. * @param deltaShift The bump size. * @param method The method to compute the present value sensitivity. * @param differenceType {@link FiniteDifferenceType#FORWARD}, {@link FiniteDifferenceType#BACKWARD}, or {@link FiniteDifferenceType#CENTRAL}. * Indicates how the finite difference is computed. Not null * @return The array of sensitivity with respect the to the given node times. */ public static double[] curveSensitivity(final InstrumentDerivative instrument, final YieldCurveBundle curves, final double pv, final String curveToBumpName, final String curveBumpedName, final double[] nodeTimes, final double deltaShift, final PricingMethod method, final FiniteDifferenceType differenceType) { Validate.notNull(instrument, "Instrument"); Validate.notNull(curves, "Curves"); Validate.notNull(method, "Method"); Validate.notNull(differenceType, "Difference type"); final int nbNode = nodeTimes.length; final double[] result = new double[nbNode]; final YieldAndDiscountCurve curveToBump = curves.getCurve(curveToBumpName); final double[] yields = new double[nbNode + 1]; final double[] nodeTimesExtended = new double[nbNode + 1]; System.arraycopy(nodeTimes, 0, nodeTimesExtended, 1, nbNode); yields[0] = curveToBump.getInterestRate(0.0); for (int loopnode = 0; loopnode < nbNode; loopnode++) { yields[loopnode + 1] = curveToBump.getInterestRate(nodeTimesExtended[loopnode + 1]); } final YieldAndDiscountCurve curveNode = YieldCurve.from(InterpolatedDoublesCurve.fromSorted(nodeTimesExtended, yields, new LinearInterpolator1D())); if (!curves.containsName(curveBumpedName)) { curves.setCurve(curveBumpedName, curveToBump); } switch (differenceType) { case FORWARD: for (int loopnode = 0; loopnode < nbNode; loopnode++) { final YieldAndDiscountCurve curveBumped = curveNode.withSingleShift(nodeTimesExtended[loopnode + 1], deltaShift); curves.replaceCurve(curveBumpedName, curveBumped); final double bumpedpv = method.presentValue(instrument, curves).getAmount(); result[loopnode] = (bumpedpv - pv) / deltaShift; } return result; case CENTRAL: for (int loopnode = 0; loopnode < nbNode; loopnode++) { final YieldAndDiscountCurve curveBumpedPlus = curveNode.withSingleShift(nodeTimesExtended[loopnode + 1], deltaShift); final YieldAndDiscountCurve curveBumpedMinus = curveNode.withSingleShift(nodeTimesExtended[loopnode + 1], -deltaShift); curves.replaceCurve(curveBumpedName, curveBumpedPlus); final double bumpedpvPlus = method.presentValue(instrument, curves).getAmount(); curves.replaceCurve(curveBumpedName, curveBumpedMinus); final double bumpedpvMinus = method.presentValue(instrument, curves).getAmount(); result[loopnode] = (bumpedpvPlus - bumpedpvMinus) / (2 * deltaShift); } return result; case BACKWARD: for (int loopnode = 0; loopnode < nbNode; loopnode++) { final YieldAndDiscountCurve curveBumped = curveNode.withSingleShift(nodeTimesExtended[loopnode + 1], -deltaShift); curves.replaceCurve(curveBumpedName, curveBumped); final double bumpedpv = method.presentValue(instrument, curves).getAmount(); result[loopnode] = (pv - bumpedpv) / deltaShift; } return result; default: throw new IllegalArgumentException("Can only handle forward, backward and central differencing"); } } /** * Compute the present value rate sensitivity for a set of node time by finite difference. The computation is done in an non-symmetrical forward way. * @param instrument The instrument. * @param curves The yield curve bundle. * @param pv The initial instrument present value. * @param curveToBumpName The name of the curve to bump. * @param curveBumpedName The name of the curve after bumped. The name should be used in the instrument construction. * @param nodeTimes The node times to be bumped. * @param deltaShift The bump size. * @param method The method to compute the present value sensitivity. * @return The array of sensitivity with respect the to the given node times. */ public static double[] curveSensitivity(final InstrumentDerivative instrument, final YieldCurveBundle curves, final double pv, final String curveToBumpName, final String curveBumpedName, final double[] nodeTimes, final double deltaShift, final PricingMethod method) { return curveSensitivity(instrument, curves, pv, curveToBumpName, curveBumpedName, nodeTimes, deltaShift, method, FiniteDifferenceType.FORWARD); } /** * Compute the present value rate sensitivity for a set of node time by finite difference. The computation is done in a symmetrical way (centered). * @param instrument The instrument. * @param curves The yield curve bundle. * @param curveToBumpName The name of the curve to bump. * @param curveBumpedName The name of the curve after bumped. The name should be used in the instrument construction. * @param nodeTimes The node times to be bumped. * @param deltaShift The bump size. * @param method The method to compute the present value sensitivity. * @return The array of sensitivity with respect the to the given node times. */ public static double[] curveSensitivity(final InstrumentDerivative instrument, final YieldCurveBundle curves, final String curveToBumpName, final String curveBumpedName, final double[] nodeTimes, final double deltaShift, final PricingMethod method) { return curveSensitivity(instrument, curves, 0.0, curveToBumpName, curveBumpedName, nodeTimes, deltaShift, method, FiniteDifferenceType.CENTRAL); } }