ArgumentChecker.notNull(future, "future");
ArgumentChecker.notNull(dataBundle, "data bundle");
ArgumentChecker.isTrue(dataBundle.getFundingCurve() instanceof YieldCurve, "Calculator expects a YieldCurve, have {}", dataBundle.getFundingCurve().getClass());
final YieldCurve discCrv = (YieldCurve) dataBundle.getFundingCurve();
final double settlement = future.accept(SETTLEMENT_TIME);
SimpleFutureDataBundle bumpedMarket = new SimpleFutureDataBundle(discCrv.withSingleShift(settlement, SHIFT), dataBundle.getMarketPrice(),
dataBundle.getSpotValue(), dataBundle.getDividendYield(), dataBundle.getCostOfCarry());
final double pvUp = future.accept(_presentValueCalculator, bumpedMarket);
bumpedMarket = new SimpleFutureDataBundle(discCrv.withSingleShift(settlement, -SHIFT), dataBundle.getMarketPrice(),
dataBundle.getSpotValue(), dataBundle.getDividendYield(), dataBundle.getCostOfCarry());
final double pvDown = future.accept(_presentValueCalculator, bumpedMarket);
final double sensitivity = (pvUp - pvDown) / (2.0 * SHIFT);
final NodeYieldSensitivityCalculator distributor = PresentValueNodeSensitivityCalculator.getDefaultInstance();
final List<Double> result = distributor.curveToNodeSensitivity(Arrays.asList(DoublesPair.of(settlement, sensitivity)), discCrv);