/** Tests applying a relative index shift to a surface. */
 @Test
 public void indexSurfaceRelative() {
   NodalDoublesSurface surface =
       new NodalDoublesSurface(
           new double[] {1.1, 1.2, 1.2, 1.3, 1.3, 1.3},
           new double[] {10, 10, 20, 10, 20, 30},
           new double[] {1, 2, 3, 4, 5, 6});
   List<Double> shiftList = Lists.newArrayList(0d, 0.1, 0.2);
   VolatilitySurfaceIndexShifts shifts =
       new VolatilitySurfaceIndexShifts(ScenarioShiftType.RELATIVE, shiftList);
   ValueProperties properties = ValueProperties.with(ValuePropertyNames.FUNCTION, "bar").get();
   ValueSpecification spec =
       new ValueSpecification("foo", ComputationTargetSpecification.NULL, properties);
   VolatilitySurface shiftedSurface =
       shifts.execute(new VolatilitySurface(surface), spec, new FunctionExecutionContext());
   assertEquals(1.0, shiftedSurface.getVolatility(1.1, 10), DELTA);
   assertEquals(2.2, shiftedSurface.getVolatility(1.2, 10), DELTA);
   assertEquals(3.3, shiftedSurface.getVolatility(1.2, 20), DELTA);
   assertEquals(4.8, shiftedSurface.getVolatility(1.3, 10), DELTA);
   assertEquals(6.0, shiftedSurface.getVolatility(1.3, 20), DELTA);
   assertEquals(7.2, shiftedSurface.getVolatility(1.3, 30), DELTA);
 }
 /**
  * Tests applying an index shift to a surface where there are fewer shifts specified than expiries
  * in the surface.
  */
 @Test
 public void indexSurfaceFewerShiftsThanExpiries() {
   NodalDoublesSurface surface =
       new NodalDoublesSurface(
           new double[] {1.1, 1.2, 1.2, 1.3, 1.3, 1.3},
           new double[] {0.1, 0.1, 0.2, 0.1, 0.2, 0.3},
           new double[] {1, 2, 3, 4, 5, 6});
   List<Double> shiftList = Lists.newArrayList(0d, 0.1);
   VolatilitySurfaceIndexShifts shifts =
       new VolatilitySurfaceIndexShifts(ScenarioShiftType.ABSOLUTE, shiftList);
   ValueProperties properties = ValueProperties.with(ValuePropertyNames.FUNCTION, "bar").get();
   ValueSpecification spec =
       new ValueSpecification("foo", ComputationTargetSpecification.NULL, properties);
   VolatilitySurface shiftedSurface =
       shifts.execute(new VolatilitySurface(surface), spec, new FunctionExecutionContext());
   assertEquals(1.0, shiftedSurface.getVolatility(1.1, 0.1), DELTA);
   assertEquals(2.1, shiftedSurface.getVolatility(1.2, 0.1), DELTA);
   assertEquals(3.1, shiftedSurface.getVolatility(1.2, 0.2), DELTA);
   assertEquals(4.0, shiftedSurface.getVolatility(1.3, 0.1), DELTA);
   assertEquals(5.0, shiftedSurface.getVolatility(1.3, 0.2), DELTA);
   assertEquals(6.0, shiftedSurface.getVolatility(1.3, 0.3), DELTA);
 }
 @Override
 public Set<ComputedValue> execute(
     final FunctionExecutionContext executionContext,
     final FunctionInputs inputs,
     final ComputationTarget target,
     final Set<ValueRequirement> desiredValues) {
   final Clock snapshotClock = executionContext.getValuationClock();
   final ZonedDateTime now = ZonedDateTime.now(snapshotClock);
   final SecuritySource securitySource =
       OpenGammaExecutionContext.getSecuritySource(executionContext);
   final SwaptionSecurity security = (SwaptionSecurity) target.getSecurity();
   final ValueRequirement desiredValue = desiredValues.iterator().next();
   final Currency currency = FinancialSecurityUtils.getCurrency(security);
   final String surfaceName = desiredValue.getConstraint(ValuePropertyNames.SURFACE);
   final String curveCalculationConfigName =
       desiredValue.getConstraint(ValuePropertyNames.CURVE_CALCULATION_CONFIG);
   final ConfigSource configSource = OpenGammaExecutionContext.getConfigSource(executionContext);
   final ConfigDBCurveCalculationConfigSource curveCalculationConfigSource =
       new ConfigDBCurveCalculationConfigSource(configSource);
   final MultiCurveCalculationConfig curveCalculationConfig =
       curveCalculationConfigSource.getConfig(curveCalculationConfigName);
   if (curveCalculationConfig == null) {
     throw new OpenGammaRuntimeException(
         "Could not find curve calculation configuration named " + curveCalculationConfigName);
   }
   String[] curveNames = curveCalculationConfig.getYieldCurveNames(); // TODO
   if (curveNames.length == 1) {
     curveNames = new String[] {curveNames[0], curveNames[0]};
   }
   final String[] fullCurveNames = new String[curveNames.length];
   for (int i = 0; i < curveNames.length; i++) {
     fullCurveNames[i] = curveNames[i] + "_" + currency.getCode();
   }
   final YieldCurveBundle curves =
       YieldCurveFunctionUtils.getYieldCurves(inputs, curveCalculationConfig);
   final Object volatilitySurfaceObject =
       inputs.getValue(getVolatilityRequirement(surfaceName, currency));
   if (volatilitySurfaceObject == null) {
     throw new OpenGammaRuntimeException("Could not get volatility surface");
   }
   final VolatilitySurface volatilitySurface = (VolatilitySurface) volatilitySurfaceObject;
   if (!(volatilitySurface.getSurface() instanceof InterpolatedDoublesSurface)) {
     throw new OpenGammaRuntimeException(
         "Expecting an InterpolatedDoublesSurface; got "
             + volatilitySurface.getSurface().getClass());
   }
   final InstrumentDefinition<?> definition = security.accept(_visitor);
   final HistoricalTimeSeriesBundle timeSeries =
       HistoricalTimeSeriesFunctionUtils.getHistoricalTimeSeriesInputs(executionContext, inputs);
   final InstrumentDerivative swaption =
       _definitionConverter.convert(security, definition, now, fullCurveNames, timeSeries);
   final ValueProperties properties =
       getResultProperties(currency.getCode(), curveCalculationConfigName, surfaceName);
   final ValueSpecification spec =
       new ValueSpecification(_valueRequirementName, target.toSpecification(), properties);
   final BlackFlatSwaptionParameters parameters =
       new BlackFlatSwaptionParameters(
           volatilitySurface.getSurface(),
           SwaptionUtils.getSwapGenerator(security, definition, securitySource));
   final YieldCurveWithBlackSwaptionBundle data =
       new YieldCurveWithBlackSwaptionBundle(parameters, curves);
   return getResult(swaption, data, spec);
 }
 @Override
 public Set<ComputedValue> execute(
     final FunctionExecutionContext executionContext,
     final FunctionInputs inputs,
     final ComputationTarget target,
     final Set<ValueRequirement> desiredValues) {
   final Clock snapshotClock = executionContext.getValuationClock();
   final ZonedDateTime now = snapshotClock.zonedDateTime();
   final SecuritySource securitySource =
       OpenGammaExecutionContext.getSecuritySource(executionContext);
   final SwaptionSecurity security = (SwaptionSecurity) target.getSecurity();
   final ValueRequirement desiredValue = desiredValues.iterator().next();
   final Currency currency = FinancialSecurityUtils.getCurrency(security);
   final String forwardCurveName =
       desiredValue.getConstraint(YieldCurveFunction.PROPERTY_FORWARD_CURVE);
   final String fundingCurveName =
       desiredValue.getConstraint(YieldCurveFunction.PROPERTY_FUNDING_CURVE);
   final String curveCalculationMethod =
       desiredValue.getConstraint(ValuePropertyNames.CURVE_CALCULATION_METHOD);
   final String surfaceName = desiredValue.getConstraint(ValuePropertyNames.SURFACE);
   final Object forwardCurveObject =
       inputs.getValue(
           YieldCurveFunction.getCurveRequirement(
               currency,
               forwardCurveName,
               forwardCurveName,
               fundingCurveName,
               curveCalculationMethod));
   if (forwardCurveObject == null) {
     throw new OpenGammaRuntimeException("Could not get forward curve");
   }
   final Object fundingCurveObject =
       inputs.getValue(
           YieldCurveFunction.getCurveRequirement(
               currency,
               fundingCurveName,
               forwardCurveName,
               fundingCurveName,
               curveCalculationMethod));
   if (fundingCurveObject == null) {
     throw new OpenGammaRuntimeException("Could not get funding curve");
   }
   final Object volatilitySurfaceObject =
       inputs.getValue(getVolatilityRequirement(surfaceName, currency));
   if (volatilitySurfaceObject == null) {
     throw new OpenGammaRuntimeException("Could not get volatility surface");
   }
   final VolatilitySurface volatilitySurface = (VolatilitySurface) volatilitySurfaceObject;
   if (!(volatilitySurface.getSurface() instanceof InterpolatedDoublesSurface)) {
     throw new OpenGammaRuntimeException(
         "Expecting an InterpolatedDoublesSurface; got "
             + volatilitySurface.getSurface().getClass());
   }
   final YieldAndDiscountCurve forwardCurve = (YieldAndDiscountCurve) forwardCurveObject;
   final YieldAndDiscountCurve fundingCurve = (YieldAndDiscountCurve) fundingCurveObject;
   final InstrumentDefinition<?> definition = security.accept(_visitor);
   final InstrumentDerivative swaption =
       definition.toDerivative(now, new String[] {fundingCurveName, forwardCurveName});
   final ValueProperties properties =
       getResultProperties(
           currency.getCode(),
           forwardCurveName,
           fundingCurveName,
           curveCalculationMethod,
           surfaceName);
   final ValueSpecification spec =
       new ValueSpecification(_valueRequirementName, target.toSpecification(), properties);
   final YieldCurveBundle curves =
       new YieldCurveBundle(
           new String[] {fundingCurveName, forwardCurveName},
           new YieldAndDiscountCurve[] {fundingCurve, forwardCurve});
   final BlackSwaptionParameters parameters =
       new BlackSwaptionParameters(
           volatilitySurface.getSurface(),
           SwaptionUtils.getSwapGenerator(security, definition, securitySource));
   final YieldCurveWithBlackSwaptionBundle data =
       new YieldCurveWithBlackSwaptionBundle(parameters, curves);
   return getResult(swaption, data, spec);
 }