@Test(enabled = false)
 /** Tests the clean, dirty and yield vs external hard-coded values. */
 public void priceYieldExternalValues1() {
   final double m1 = 1000000; // Notional of the external figures.
   final ZonedDateTime pricingDate20110817 = DateUtils.getUTCDate(2011, 8, 16); // Spot 18-Aug-2011
   final InflationIssuerProviderDiscount market =
       MulticurveProviderDiscountDataSets.createMarket1(pricingDate20110817);
   final double cleanRealPrice = 1.00;
   final BondCapitalIndexedSecurity<Coupon> bond_110817 =
       BOND_SECURITY_TIPS_1_DEFINITION.toDerivative(pricingDate20110817, US_CPI);
   final double referenceIndexExpected = 225.83129;
   final MultiCurrencyAmount netAmountSettle =
       bond_110817.getSettlement().accept(NADIC, market.getInflationProvider());
   final double referenceIndexComputed =
       netAmountSettle.getAmount(bond_110817.getCurrency()).getAmount()
           * BOND_SECURITY_TIPS_1_DEFINITION.getIndexStartValue()
           / bond_110817.getSettlement().getNotional();
   assertEquals(
       "Inflation Capital Indexed bond: index",
       referenceIndexExpected,
       referenceIndexComputed,
       1.0E-5);
   final double indexRatioExpected = 1.13782;
   final MultiCurrencyAmount indexRatioCalculated =
       bond_110817.getSettlement().accept(NADIC, market.getInflationProvider());
   assertEquals(
       "Inflation Capital Indexed bond: indexRatio",
       indexRatioExpected,
       indexRatioCalculated.getAmount(PRICE_INDEX_USCPI.getCurrency()).getAmount()
           / NOTIONAL_TIPS_1,
       1.0E-5);
   final double yieldExpected = 1.999644 / 100.0;
   final double dirtyRealPriceComputed =
       METHOD_BOND_INFLATION.dirtyRealPriceFromCleanRealPrice(bond_110817, cleanRealPrice);
   final double yieldComputed =
       METHOD_BOND_INFLATION.yieldRealFromDirtyRealPrice(bond_110817, dirtyRealPriceComputed);
   assertEquals("Inflation Capital Indexed bond: yield ", yieldExpected, yieldComputed, 1.0E-8);
   final double accruedExpected = 2102.49;
   final double accruedRealExpected = accruedExpected / m1 / indexRatioExpected;
   final double accruedReal = bond_110817.getAccruedInterest();
   assertEquals(
       "Inflation Capital Indexed bond: accrued",
       accruedRealExpected,
       accruedReal / NOTIONAL_TIPS_1,
       1.0E-8);
   final double netAmountExpected = 1139922.49; // For 1m; uses the rounding rules.
   final double netAmount2 = indexRatioExpected * m1 * cleanRealPrice + accruedExpected;
   assertEquals(
       "Inflation Capital Indexed bond: net amount", netAmountExpected, netAmount2, 1.0E-2);
   final MultiCurrencyAmount netAmount =
       METHOD_BOND_INFLATION.netAmount(bond_110817, market, cleanRealPrice);
   assertEquals(
       "Inflation Capital Indexed bond: net amount",
       netAmountExpected,
       netAmount.getAmount(PRICE_INDEX_USCPI.getCurrency()).getAmount() * m1 / NOTIONAL_TIPS_1,
       2.0E+0); // The difference is due to rounding.
 }
  /** Test the present value parameter curves sensitivity. */
  public void presentValueParameterCurveSensitivity() {

    final MultipleCurrencyParameterSensitivity pvicsFD =
        PS_PV_FDC.calculateSensitivity(
            BOND_SECURITY_GILT_1.getCoupon(), MARKET.getInflationProvider());
    final MultipleCurrencyParameterSensitivity pvicsExact =
        PSC.calculateSensitivity(
            BOND_SECURITY_GILT_1.getCoupon(), MARKET.getInflationProvider(), MARKET.getAllNames());

    AssertSensitivityObjects.assertEquals(
        "Bond capital indexed security: presentValueParameterCurveSensitivity ",
        pvicsExact,
        pvicsFD,
        TOLERANCE_PV_DELTA);
  }
  /** Test the present value curves sensitivity. */
  public void presentValueCurveSensitivityCAIN() {
    MulticurveProviderInterface multicurveDecorated =
        new MulticurveProviderDiscountingDecoratedIssuer(
            MARKET.getIssuerProvider(),
            BOND_SECURITY_CAIN.getCurrency(),
            BOND_SECURITY_CAIN.getIssuerEntity());
    InflationProviderInterface creditDiscounting =
        new InflationProviderDecoratedMulticurve(
            MARKET.getInflationProvider(), multicurveDecorated);
    final MultipleCurrencyInflationSensitivity sensitivityNominal =
        BOND_SECURITY_CAIN.getNominal().accept(PVCSDC, creditDiscounting);
    final MultipleCurrencyInflationSensitivity sensitivityCoupon =
        BOND_SECURITY_CAIN.getCoupon().accept(PVCSDC, creditDiscounting);
    final MultipleCurrencyInflationSensitivity pvcisCalculated =
        sensitivityNominal.plus(sensitivityCoupon);

    final MultipleCurrencyInflationSensitivity pvcisMethod =
        METHOD_BOND_INFLATION.presentValueCurveSensitivity(BOND_SECURITY_CAIN, MARKET);

    AssertSensitivityObjects.assertEquals(
        "Bond capital indexed security: presentValueCurveSensitivity ",
        pvcisCalculated,
        pvcisMethod,
        TOLERANCE_PV_DELTA);
  }
/**
 * Tests the present value and its sensitivities for zero-coupon cap/floor with reference index on
 * the first of the month.
 */
public class CapFloorInflationZeroCouponMonthlyBlackSmileMethodTest {
  private static final InflationIssuerProviderDiscount MARKET =
      MulticurveProviderDiscountDataSets.createMarket1();
  private static final IndexPrice[] PRICE_INDEXES =
      MARKET.getPriceIndexes().toArray(new IndexPrice[MARKET.getPriceIndexes().size()]);
  private static final IndexPrice PRICE_INDEX_EUR = PRICE_INDEXES[0];
  private static final Calendar CALENDAR_EUR = MulticurveProviderDiscountDataSets.getEURCalendar();
  private static final BusinessDayConvention BUSINESS_DAY =
      BusinessDayConventionFactory.INSTANCE.getBusinessDayConvention("Modified Following");
  private static final ZonedDateTime START_DATE = DateUtils.getUTCDate(2008, 8, 18);
  private static final int MATURITY = 10;
  private static final Period COUPON_TENOR = Period.ofYears(MATURITY);
  private static final ZonedDateTime PAYMENT_DATE =
      ScheduleCalculator.getAdjustedDate(START_DATE, COUPON_TENOR, BUSINESS_DAY, CALENDAR_EUR);
  private static final double NOTIONAL = 98765432;
  private static final int MONTH_LAG = 3;
  private static final double INDEX_1MAY_2008 =
      108.23; // 3 m before Aug: May / 1 May index = May index: 108.23

  private static final double STRIKE = .02;
  private static final boolean IS_CAP = true;
  private static final ZonedDateTime LAST_KNOWN_FIXING_DATE = DateUtils.getUTCDate(2008, 7, 01);

  private static final double SHIFT_FD = 1.0E-7;
  private static final double TOLERANCE_PV = 1.0E-2;
  private static final double TOLERANCE_PV_DELTA = 1.0E+2;

  private static final InterpolatedDoublesSurface BLACK_SURF =
      TestsDataSetsBlack.createBlackSurfaceExpiryStrike();
  private static final BlackSmileCapInflationZeroCouponParameters BLACK_PARAM =
      new BlackSmileCapInflationZeroCouponParameters(BLACK_SURF, PRICE_INDEX_EUR);
  private static final BlackSmileCapInflationZeroCouponProviderDiscount BLACK_INFLATION =
      new BlackSmileCapInflationZeroCouponProviderDiscount(
          MARKET.getInflationProvider(), BLACK_PARAM);

  private static final ZonedDateTime PRICING_DATE = DateUtils.getUTCDate(2011, 8, 3);
  private static final CouponInflationZeroCouponMonthlyDefinition ZERO_COUPON_DEFINITION =
      CouponInflationZeroCouponMonthlyDefinition.from(
          START_DATE,
          PAYMENT_DATE,
          NOTIONAL,
          PRICE_INDEX_EUR,
          INDEX_1MAY_2008,
          MONTH_LAG,
          MONTH_LAG,
          false);
  private static final CapFloorInflationZeroCouponMonthlyDefinition ZERO_COUPON_DEFINITION_CAP =
      CapFloorInflationZeroCouponMonthlyDefinition.from(
          ZERO_COUPON_DEFINITION, LAST_KNOWN_FIXING_DATE, MATURITY, STRIKE, IS_CAP);
  private static final CapFloorInflationZeroCouponMonthly ZERO_COUPON_CAP =
      ZERO_COUPON_DEFINITION_CAP.toDerivative(PRICING_DATE, "not used");

  private static final CapFloorInflationZeroCouponMonthlyBlackSmileMethod METHOD =
      CapFloorInflationZeroCouponMonthlyBlackSmileMethod.getInstance();
  private static final PresentValueBlackSmileInflationZeroCouponCalculator PVIC =
      PresentValueBlackSmileInflationZeroCouponCalculator.getInstance();
  private static final PresentValueCurveSensitivityBlackSmileInflationZeroCouponCalculator PVCSDC =
      PresentValueCurveSensitivityBlackSmileInflationZeroCouponCalculator.getInstance();
  private static final ParameterInflationSensitivityParameterCalculator<
          BlackSmileCapInflationZeroCouponProviderInterface>
      PSC = new ParameterInflationSensitivityParameterCalculator<>(PVCSDC);
  private static final ParameterSensitivityBlackSmileZeroCouponCapDiscountInterpolatedFDCalculator
      PS_PV_FDC =
          new ParameterSensitivityBlackSmileZeroCouponCapDiscountInterpolatedFDCalculator(
              PVIC, SHIFT_FD);

  /** The Black function used in the pricing. */
  private static final BlackPriceFunction BLACK_FUNCTION = new BlackPriceFunction();

  @Test
  /** Tests the present value. */
  public void presentValueNoNotional() {
    final MultipleCurrencyAmount pv = METHOD.presentValue(ZERO_COUPON_CAP, BLACK_INFLATION);
    final double timeToMaturity =
        ZERO_COUPON_CAP.getReferenceEndTime() - ZERO_COUPON_CAP.getLastKnownFixingTime();
    final double df =
        MARKET
            .getCurve(ZERO_COUPON_CAP.getCurrency())
            .getDiscountFactor(ZERO_COUPON_CAP.getPaymentTime());
    final double finalIndex =
        MARKET.getCurve(PRICE_INDEX_EUR).getPriceIndex(ZERO_COUPON_CAP.getReferenceEndTime());
    final double forward = finalIndex / INDEX_1MAY_2008;
    final EuropeanVanillaOption option =
        new EuropeanVanillaOption(
            Math.pow(1 + ZERO_COUPON_CAP.getStrike(), ZERO_COUPON_CAP.getMaturity()),
            timeToMaturity,
            ZERO_COUPON_CAP.isCap());
    final double volatility =
        BLACK_INFLATION
            .getBlackParameters()
            .getVolatility(ZERO_COUPON_CAP.getReferenceEndTime(), ZERO_COUPON_CAP.getStrike());
    final BlackFunctionData dataBlack = new BlackFunctionData(forward, 1.0, volatility);
    final Function1D<BlackFunctionData, Double> func = BLACK_FUNCTION.getPriceFunction(option);
    final double pvExpected =
        df
            * func.evaluate(dataBlack)
            * ZERO_COUPON_CAP.getNotional()
            * ZERO_COUPON_CAP.getPaymentYearFraction();
    assertEquals(
        "Zero-coupon inflation DiscountingMethod: Present value",
        pvExpected,
        pv.getAmount(ZERO_COUPON_CAP.getCurrency()),
        TOLERANCE_PV);
  }

  @Test
  /** Tests the present value: Method vs Calculator. */
  public void presentValueMethodVsCalculator() {
    final MultipleCurrencyAmount pvMethod = METHOD.presentValue(ZERO_COUPON_CAP, BLACK_INFLATION);
    final MultipleCurrencyAmount pvCalculator = ZERO_COUPON_CAP.accept(PVIC, BLACK_INFLATION);
    assertEquals("Zero-coupon inflation DiscountingMethod: Present value", pvMethod, pvCalculator);
  }

  @Test
  /** Test the present value curves sensitivity. */
  public void presentValueCurveSensitivity() {

    final MultipleCurrencyParameterSensitivity pvicsFD =
        PS_PV_FDC.calculateSensitivity(ZERO_COUPON_CAP, BLACK_INFLATION);
    final MultipleCurrencyParameterSensitivity pvicsExact =
        PSC.calculateSensitivity(ZERO_COUPON_CAP, BLACK_INFLATION, MARKET.getAllNames());

    AssertSensivityObjects.assertEquals(
        "Zero-coupon inflation DiscountingMethod: presentValueCurveSensitivity ",
        pvicsExact,
        pvicsFD,
        TOLERANCE_PV_DELTA);
  }

  @Test
  public void presentValueMarketSensitivityMethodVsCalculator() {
    final MultipleCurrencyInflationSensitivity pvcisMethod =
        METHOD.presentValueCurveSensitivity(ZERO_COUPON_CAP, BLACK_INFLATION);
    final MultipleCurrencyInflationSensitivity pvcisCalculator =
        ZERO_COUPON_CAP.accept(PVCSDC, BLACK_INFLATION);
    AssertSensivityObjects.assertEquals(
        "Zero-coupon inflation DiscountingMethod: presentValueMarketSensitivity",
        pvcisMethod,
        pvcisCalculator,
        TOLERANCE_PV_DELTA);
  }
}