/**
  * Computes the option security price curve sensitivity. The future price is computed without
  * convexity adjustment.
  *
  * @param security The future option security.
  * @param sabrData The SABR data bundle.
  * @return The security price curve sensitivity.
  */
 public PresentValueSensitivity priceCurveSensitivity(
     final InterestRateFutureOptionMarginSecurity security,
     final SABRInterestRateDataBundle sabrData) {
   // Forward sweep
   double priceFuture = METHOD_FUTURE.priceFromCurves(security.getUnderlyingFuture(), sabrData);
   double rateStrike = 1.0 - security.getStrike();
   EuropeanVanillaOption option =
       new EuropeanVanillaOption(rateStrike, security.getExpirationTime(), !security.isCall());
   double forward = 1 - priceFuture;
   double delay =
       security.getUnderlyingFuture().getLastTradingTime() - security.getExpirationTime();
   double[] volatilityAdjoint =
       sabrData
           .getSABRParameter()
           .getVolatilityAdjoint(security.getExpirationTime(), delay, rateStrike, forward);
   BlackFunctionData dataBlack = new BlackFunctionData(forward, 1.0, volatilityAdjoint[0]);
   double[] priceAdjoint = BLACK_FUNCTION.getPriceAdjoint(option, dataBlack);
   // Backward sweep
   double priceBar = 1.0;
   double volatilityBar = priceAdjoint[2] * priceBar;
   double forwardBar = priceAdjoint[1] * priceBar + volatilityAdjoint[1] * volatilityBar;
   double priceFutureBar = -forwardBar;
   PresentValueSensitivity priceFutureDerivative =
       METHOD_FUTURE.priceCurveSensitivity(security.getUnderlyingFuture(), sabrData);
   return priceFutureDerivative.multiply(priceFutureBar);
 }
 /**
  * Computes the option security price curve sensitivity. The future price is computed without
  * convexity adjustment.
  *
  * @param security The future option security.
  * @param sabrData The SABR data bundle.
  * @return The security price curve sensitivity.
  */
 public PresentValueSABRSensitivityDataBundle priceSABRSensitivity(
     final InterestRateFutureOptionMarginSecurity security,
     final SABRInterestRateDataBundle sabrData) {
   final PresentValueSABRSensitivityDataBundle sensi = new PresentValueSABRSensitivityDataBundle();
   // Forward sweep
   double priceFuture = METHOD_FUTURE.priceFromCurves(security.getUnderlyingFuture(), sabrData);
   double rateStrike = 1.0 - security.getStrike();
   EuropeanVanillaOption option =
       new EuropeanVanillaOption(rateStrike, security.getExpirationTime(), !security.isCall());
   double forward = 1 - priceFuture;
   double delay =
       security.getUnderlyingFuture().getLastTradingTime() - security.getExpirationTime();
   double[] volatilityAdjoint =
       sabrData
           .getSABRParameter()
           .getVolatilityAdjoint(security.getExpirationTime(), delay, rateStrike, forward);
   BlackFunctionData dataBlack = new BlackFunctionData(forward, 1.0, volatilityAdjoint[0]);
   double[] priceAdjoint = BLACK_FUNCTION.getPriceAdjoint(option, dataBlack);
   // Backward sweep
   double priceBar = 1.0;
   double volatilityBar = priceAdjoint[2] * priceBar;
   final DoublesPair expiryDelay = new DoublesPair(security.getExpirationTime(), delay);
   sensi.addAlpha(expiryDelay, volatilityAdjoint[3] * volatilityBar);
   sensi.addRho(expiryDelay, volatilityAdjoint[4] * volatilityBar);
   sensi.addNu(expiryDelay, volatilityAdjoint[5] * volatilityBar);
   return sensi;
 }
 @Test
 /** Test the option price from the future price. Mid-curve one year option. */
 public void priceFromFuturePriceMidCurve() {
   final double priceFuture = 0.9905;
   final double priceOption =
       METHOD.optionPriceFromFuturePrice(OPTION_EDU2, SABR_BUNDLE, priceFuture);
   final double delay = EDU2.getLastTradingTime() - EXPIRATION_TIME;
   final double volatility =
       SABR_PARAMETER.getVolatility(EXPIRATION_TIME, delay, 1 - STRIKE, 1 - priceFuture);
   final BlackPriceFunction blackFunction = new BlackPriceFunction();
   final BlackFunctionData dataBlack = new BlackFunctionData(1 - priceFuture, 1.0, volatility);
   final EuropeanVanillaOption option =
       new EuropeanVanillaOption(1 - STRIKE, EXPIRATION_TIME, !IS_CALL);
   final double priceOptionExpected = blackFunction.getPriceFunction(option).evaluate(dataBlack);
   assertEquals(
       "Future option with SABR volatilities: option price from future price",
       priceOptionExpected,
       priceOption);
 }
 @Test
 /** Test the option price from the future price. Standard option. */
 public void priceFromFuturePriceStandard() {
   final double expirationTime = ACT_ACT.getDayCountFraction(REFERENCE_DATE, LAST_TRADING_DATE);
   final InterestRateFutureOptionMarginSecurity optionEDU2Standard =
       new InterestRateFutureOptionMarginSecurity(EDU2, expirationTime, STRIKE, IS_CALL);
   final double priceFuture = 0.9905;
   final double priceOption =
       METHOD.optionPriceFromFuturePrice(optionEDU2Standard, SABR_BUNDLE, priceFuture);
   final double delay = 0.0;
   final double volatility =
       SABR_PARAMETER.getVolatility(expirationTime, delay, 1 - STRIKE, 1 - priceFuture);
   final BlackPriceFunction blackFunction = new BlackPriceFunction();
   final BlackFunctionData dataBlack = new BlackFunctionData(1 - priceFuture, 1.0, volatility);
   final EuropeanVanillaOption option =
       new EuropeanVanillaOption(1 - STRIKE, expirationTime, !IS_CALL);
   final double priceOptionExpected = blackFunction.getPriceFunction(option).evaluate(dataBlack);
   assertEquals(
       "Future option with SABR volatilities: option price from future price",
       priceOptionExpected,
       priceOption);
 }
 /**
  * Computes the option security price from future price.
  *
  * @param security The future option security.
  * @param sabrData The SABR data bundle.
  * @param priceFuture The price of the underlying future.
  * @return The security price.
  */
 public double optionPriceFromFuturePrice(
     final InterestRateFutureOptionMarginSecurity security,
     final SABRInterestRateDataBundle sabrData,
     final double priceFuture) {
   final double rateStrike = 1.0 - security.getStrike();
   final EuropeanVanillaOption option =
       new EuropeanVanillaOption(rateStrike, security.getExpirationTime(), !security.isCall());
   final double forward = 1 - priceFuture;
   final double delay =
       security.getUnderlyingFuture().getLastTradingTime() - security.getExpirationTime();
   final double volatility =
       sabrData
           .getSABRParameter()
           .getVolatility(new double[] {security.getExpirationTime(), delay, rateStrike, forward});
   final BlackFunctionData dataBlack = new BlackFunctionData(forward, 1.0, volatility);
   final double priceSecurity = BLACK_FUNCTION.getPriceFunction(option).evaluate(dataBlack);
   return priceSecurity;
 }