/** * Copyright (C) 2011 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.analytics.financial.interestrate; import java.util.ArrayList; import java.util.List; import org.apache.commons.lang.Validate; import com.opengamma.analytics.financial.interestrate.method.PricingMethod; import com.opengamma.analytics.financial.model.interestrate.curve.YieldAndDiscountAddZeroSpreadCurve; import com.opengamma.analytics.financial.model.interestrate.curve.YieldAndDiscountCurve; import com.opengamma.analytics.financial.model.interestrate.curve.YieldCurve; import com.opengamma.analytics.math.curve.FunctionalDoublesCurve; import com.opengamma.analytics.math.function.Function1D; import com.opengamma.util.tuple.DoublesPair; /** * @deprecated {@link YieldCurveBundle} is deprecated */ @Deprecated public abstract class FDCurveSensitivityCalculator { /** * Gives the sensitivity of the some metric of an IRD to a points on a one of the family of curves by finite difference * @param ird The Interest Rate Derivative * @param calculator This calculates the metric * @param curves The family of yield curves * @param curveName The name of the curve of interest * @param times The times along the curve. <b>Note</b> These should be in ascending order and be known sensitivity points * (or the result will be zero) * @param absTol If the absolute value of a sensitivities is below this value it is ignored * @return Sensitivities at a given points */ public static final List<DoublesPair> curveSensitvityFDCalculator(final InstrumentDerivative ird, final InstrumentDerivativeVisitorAdapter<YieldCurveBundle, Double> calculator, final YieldCurveBundle curves, final String curveName, final double[] times, final double absTol) { Validate.notNull(times, "null times"); Validate.notNull(ird, "null ird"); Validate.notNull(calculator, "null calculator"); Validate.notNull(curves, "null curves"); Validate.isTrue(times[0] >= 0.0, "t less than 0"); Validate.isTrue(curves.containsName(curveName), "curveName not in curves"); final List<DoublesPair> res = new ArrayList<>(); double oldT = times[0]; boolean first = true; for (final double t : times) { if (!first) { Validate.isTrue(t > oldT, "times not strictly assending"); } else { first = false; } final double sense = impFDCalculator(ird, calculator, curves, curveName, t); if (Math.abs(sense) > absTol) { res.add(DoublesPair.of(t, sense)); } oldT = t; } return res; } // public static final List<DoublesPair> curveSensitvityFDCalculator(final InstrumentDerivative ird, AbstractInstrumentDerivativeVisitor<YieldCurveBundle, Double> calculator, // final YieldCurveBundle curves, final String curveName, final Double[] times, final double absTol) { // return curveSensitvityFDCalculator(ird, calculator, curves, curveName, times, absTol); // } /** * Gives the sensitivity of the some metric of an IRD to a points on a one of the family of curves by finite difference * @param ird The Interest Rate Derivative * @param method This calculates the metric * @param curves The family of yield curves * @param curveName The name of the curve of interest * @param times The times along the curve. <b>Note</b> These should be in ascending order and be known sensitivity points * (or the result will be zero) * @param absTol If the absolute value of a sensitivities is below this value it is ignored * @return Sensitivities at a given points */ public static final List<DoublesPair> curveSensitvityFDCalculator(final InstrumentDerivative ird, final PricingMethod method, final YieldCurveBundle curves, final String curveName, final double[] times, final double absTol) { Validate.notNull(times, "null times"); Validate.notNull(ird, "null ird"); Validate.notNull(method, "null method"); Validate.notNull(curves, "null curves"); Validate.isTrue(times[0] >= 0.0, "t less than 0"); Validate.isTrue(curves.containsName(curveName), "curveName not in curves"); final List<DoublesPair> res = new ArrayList<>(); double oldT = times[0]; boolean first = true; for (final double t : times) { if (!first) { Validate.isTrue(t > oldT, "times not strictly assending"); } else { first = false; } final double sense = impFDCalculator(ird, method, curves, curveName, t); if (Math.abs(sense) > absTol) { res.add(DoublesPair.of(t, sense)); } oldT = t; } return res; } /** * Gives the sensitivity of the some metric of an IRD to a point on a one of the family of curves by finite difference * @param ird The Interest Rate Derivative * @param calculator This calculates the metric * @param curves The family of yield curves * @param curveName The name of the curve of interest * @param t The time along the curve. <b>Note</b> This should be a known sensitivity point or the result will be zero * @return Sensitivity at a given point */ public static final double curveSensitvityFDCalculator(final InstrumentDerivative ird, final InstrumentDerivativeVisitorAdapter<YieldCurveBundle, Double> calculator, final YieldCurveBundle curves, final String curveName, final double t) { Validate.notNull(ird, "null ird"); Validate.notNull(calculator, "null calculator"); Validate.notNull(curves, "null curves"); Validate.isTrue(t >= 0.0, "t less than 0"); Validate.isTrue(curves.containsName(curveName), "curveName not in curves"); return impFDCalculator(ird, calculator, curves, curveName, t); } private static double impFDCalculator(final InstrumentDerivative ird, final InstrumentDerivativeVisitorAdapter<YieldCurveBundle, Double> calculator, final YieldCurveBundle curves, final String curveName, final double t) { final double eps = 1e-6; final Function1D<Double, Double> blip = new Function1D<Double, Double>() { @Override public Double evaluate(final Double x) { return (Math.abs(x - t) < 3.0e-6 ? eps : 0.0); //100 second tolerance } }; final YieldAndDiscountCurve blipCurve = YieldCurve.from(new FunctionalDoublesCurve(blip)); final YieldAndDiscountCurve originalCurve = curves.getCurve(curveName); final YieldAndDiscountCurve upCurve = new YieldAndDiscountAddZeroSpreadCurve("UpCurve", false, originalCurve, blipCurve); final YieldAndDiscountCurve downCurve = new YieldAndDiscountAddZeroSpreadCurve("DownCurve", true, originalCurve, blipCurve); curves.replaceCurve(curveName, upCurve); final double up = ird.accept(calculator, curves); curves.replaceCurve(curveName, downCurve); final double down = ird.accept(calculator, curves); curves.replaceCurve(curveName, originalCurve); return (up - down) / 2 / eps; } private static double impFDCalculator(final InstrumentDerivative ird, final PricingMethod method, final YieldCurveBundle curves, final String curveName, final double t) { final double eps = 1e-6; final Function1D<Double, Double> blip = new Function1D<Double, Double>() { @Override public Double evaluate(final Double x) { return (Math.abs(x - t) < 3.0e-6 ? eps : 0.0); //100 second tolerance } }; final YieldAndDiscountCurve blipCurve = YieldCurve.from(new FunctionalDoublesCurve(blip)); final YieldAndDiscountCurve originalCurve = curves.getCurve(curveName); final YieldAndDiscountCurve upCurve = new YieldAndDiscountAddZeroSpreadCurve("UpCurve", false, originalCurve, blipCurve); final YieldAndDiscountCurve downCurve = new YieldAndDiscountAddZeroSpreadCurve("DownCurve", true, originalCurve, blipCurve); curves.replaceCurve(curveName, upCurve); final double up = method.presentValue(ird, curves).getAmount(); curves.replaceCurve(curveName, downCurve); final double down = method.presentValue(ird, curves).getAmount(); curves.replaceCurve(curveName, originalCurve); return (up - down) / 2 / eps; } }