// TODO won't work if curves have different currencies protected static YieldCurveBundle getYieldCurves( final FunctionInputs inputs, final MultiCurveCalculationConfig curveConfig, final ConfigDBCurveCalculationConfigSource configSource) { final YieldCurveBundle curves = new YieldCurveBundle(); if (curveConfig.getExogenousConfigData() != null) { final LinkedHashMap<String, String[]> exogenousCurves = curveConfig.getExogenousConfigData(); for (final Map.Entry<String, String[]> entry : exogenousCurves.entrySet()) { final String exogenousConfigName = entry.getKey(); final MultiCurveCalculationConfig exogenousConfig = configSource.getConfig(exogenousConfigName); final UniqueIdentifiable exogenousId = exogenousConfig.getUniqueId(); final String exogenousCalculationMethod = exogenousConfig.getCalculationMethod(); for (final String curveName : entry.getValue()) { final ValueRequirement curveRequirement = getCurveRequirement( exogenousId, curveName, exogenousConfigName, exogenousCalculationMethod); final Object curveObject = inputs.getValue(curveRequirement); if (curveObject == null) { throw new OpenGammaRuntimeException("Could not get curve called " + curveName); } final YieldAndDiscountCurve curve = (YieldAndDiscountCurve) curveObject; curves.setCurve(curveName, curve); } curves.addAll(getYieldCurves(inputs, exogenousConfig, configSource)); } } final String[] curveNames = curveConfig.getYieldCurveNames(); final UniqueIdentifiable id = curveConfig.getUniqueId(); for (final String curveName : curveNames) { final ValueRequirement curveRequirement = getCurveRequirement( id, curveName, curveConfig.getCalculationConfigName(), curveConfig.getCalculationMethod()); final Object curveObject = inputs.getValue(curveRequirement); if (curveObject == null) { throw new OpenGammaRuntimeException("Could not get curve called " + curveName); } final YieldAndDiscountCurve curve = (YieldAndDiscountCurve) curveObject; curves.setCurve(curveName, curve); } return curves; }
@Test public void curveSensitivityFRA() { final YieldCurveBundle curves = TestsDataSetsSABR.createCurves1(); final double deltaShift = 1.0E-8; final double pv = FRA_METHOD.presentValue(FRA, curves).getAmount(); // 1. Forward curve sensitivity final String bumpedCurveName = "Bumped Curve"; final String[] bumpedCurvesForwardName = {FUNDING_CURVE_NAME, bumpedCurveName}; final ForwardRateAgreement fraBumpedForward = (ForwardRateAgreement) FRA_DEFINITION.toDerivative(REFERENCE_DATE, bumpedCurvesForwardName); final YieldAndDiscountCurve curveForward = curves.getCurve(FORWARD_CURVE_NAME); final double[] timeForward = new double[2]; timeForward[0] = FRA.getFixingPeriodStartTime(); timeForward[1] = FRA.getFixingPeriodEndTime(); final int nbForwardDate = timeForward.length; final double[] yieldsForward = new double[nbForwardDate + 1]; final double[] nodeTimesForward = new double[nbForwardDate + 1]; yieldsForward[0] = curveForward.getInterestRate(0.0); for (int i = 0; i < nbForwardDate; i++) { nodeTimesForward[i + 1] = timeForward[i]; yieldsForward[i + 1] = curveForward.getInterestRate(nodeTimesForward[i + 1]); } final YieldAndDiscountCurve tempCurveForward = YieldCurve.from( InterpolatedDoublesCurve.fromSorted( nodeTimesForward, yieldsForward, new LinearInterpolator1D())); final double[] sensiPvForwardFD = new double[nbForwardDate]; for (int i = 0; i < nbForwardDate; i++) { final YieldAndDiscountCurve bumpedCurveForward = tempCurveForward.withSingleShift(nodeTimesForward[i + 1], deltaShift); final YieldCurveBundle curvesBumpedForward = new YieldCurveBundle(); curvesBumpedForward.addAll(curves); curvesBumpedForward.setCurve("Bumped Curve", bumpedCurveForward); final double bumpedPv = FRA_METHOD.presentValue(fraBumpedForward, curvesBumpedForward).getAmount(); sensiPvForwardFD[i] = (bumpedPv - pv) / deltaShift; } final double[] nodeTimesForwardMethod = new double[] {FRA.getFixingPeriodStartTime(), FRA.getFixingPeriodEndTime()}; final double[] sensiForwardMethod = SensitivityFiniteDifference.curveSensitivity( fraBumpedForward, curves, pv, FORWARD_CURVE_NAME, bumpedCurveName, nodeTimesForwardMethod, deltaShift, FRA_METHOD); assertEquals( "Sensitivity finite difference method: number of node", 2, sensiForwardMethod.length); for (int loopnode = 0; loopnode < sensiForwardMethod.length; loopnode++) { assertEquals( "Sensitivity finite difference method: node sensitivity", sensiPvForwardFD[loopnode], sensiForwardMethod[loopnode]); } // 2. Funding curve sensitivity final String[] bumpedCurvesFundingName = {bumpedCurveName, FORWARD_CURVE_NAME}; final ForwardRateAgreement fraBumped = (ForwardRateAgreement) FRA_DEFINITION.toDerivative(REFERENCE_DATE, bumpedCurvesFundingName); final YieldAndDiscountCurve curveFunding = curves.getCurve(FUNDING_CURVE_NAME); final double[] yieldsFunding = new double[2]; final double[] nodeTimesFunding = new double[2]; yieldsFunding[0] = curveFunding.getInterestRate(0.0); nodeTimesFunding[1] = FRA.getPaymentTime(); yieldsFunding[1] = curveFunding.getInterestRate(nodeTimesFunding[1]); final YieldAndDiscountCurve tempCurveFunding = YieldCurve.from( InterpolatedDoublesCurve.fromSorted( nodeTimesFunding, yieldsFunding, new LinearInterpolator1D())); final YieldAndDiscountCurve bumpedCurve = tempCurveFunding.withSingleShift(nodeTimesFunding[1], deltaShift); final YieldCurveBundle curvesBumped = new YieldCurveBundle(); curvesBumped.addAll(curves); curvesBumped.replaceCurve("Bumped Curve", bumpedCurve); final double bumpedPvDsc = FRA_METHOD.presentValue(fraBumped, curvesBumped).getAmount(); final double[] resDsc = new double[1]; resDsc[0] = (bumpedPvDsc - pv) / deltaShift; final double[] nodeTimesFundingMethod = new double[] {FRA.getPaymentTime()}; final double[] sensiFundingMethod = SensitivityFiniteDifference.curveSensitivity( fraBumped, curves, pv, FUNDING_CURVE_NAME, bumpedCurveName, nodeTimesFundingMethod, deltaShift, FRA_METHOD); assertEquals( "Sensitivity finite difference method: number of node", 1, sensiFundingMethod.length); for (int loopnode = 0; loopnode < sensiFundingMethod.length; loopnode++) { assertEquals( "Sensitivity finite difference method: node sensitivity", resDsc[loopnode], sensiFundingMethod[loopnode]); } }