@Test
 public void testStartAndEndSame2() {
   final ZonedDateTime date = DateUtil.getUTCDate(2001, 2, 13);
   final ZonedDateTime[] dates = CALCULATOR.getSchedule(date, date, true, false);
   assertEquals(dates.length, 1);
   assertEquals(dates[0], date);
 }
 @Test
 public void testRecursive2() {
   ZonedDateTime startDate = DateUtil.getUTCDate(2000, 1, 1);
   ZonedDateTime endDate = DateUtil.getUTCDate(2000, 1, 30);
   ZonedDateTime[] forward = CALCULATOR.getSchedule(startDate, endDate, false, true);
   ZonedDateTime[] backward = CALCULATOR.getSchedule(startDate, endDate, true, true);
   assertEquals(forward.length, 1);
   assertEquals(backward.length, 1);
   assertEquals(forward[0], startDate);
   assertEquals(backward[0], endDate);
   startDate = DateUtil.getUTCDate(2002, 2, 1);
   endDate = DateUtil.getUTCDate(2002, 2, 9);
   forward = CALCULATOR.getSchedule(startDate, endDate, false, true);
   backward = CALCULATOR.getSchedule(startDate, endDate, true, true);
   assertEquals(forward.length, 1);
   assertEquals(backward.length, 1);
   assertEquals(forward[0], startDate);
   assertEquals(backward[0], endDate);
   startDate = DateUtil.getUTCDate(2000, 1, 1);
   endDate = DateUtil.getUTCDate(2002, 2, 9);
   final int months = 26;
   forward = CALCULATOR.getSchedule(startDate, endDate, false, true);
   backward = CALCULATOR.getSchedule(startDate, endDate, true, true);
   assertEquals(forward.length, months);
   assertEquals(backward.length, months);
   assertEquals(forward[0], startDate);
   assertEquals(backward[0], DateUtil.getUTCDate(2000, 1, 9));
   assertEquals(forward[months - 1], DateUtil.getUTCDate(2002, 2, 1));
   assertEquals(backward[months - 1], endDate);
   for (int i = 1; i < months; i++) {
     if (forward[i].getYear() == forward[i - 1].getYear()) {
       assertEquals(
           forward[i].getMonthOfYear().getValue() - forward[i - 1].getMonthOfYear().getValue(), 1);
       assertEquals(
           backward[i].getMonthOfYear().getValue() - backward[i - 1].getMonthOfYear().getValue(),
           1);
     } else {
       assertEquals(
           forward[i].getMonthOfYear().getValue() - forward[i - 1].getMonthOfYear().getValue(),
           -11);
       assertEquals(
           backward[i].getMonthOfYear().getValue() - backward[i - 1].getMonthOfYear().getValue(),
           -11);
     }
     assertEquals(forward[i].getDayOfMonth(), 1);
     assertEquals(backward[i].getDayOfMonth(), 9);
   }
 }
/** Tests related to the construction of interest rate future security. */
public class InterestRateFutureSecurityTest {
  // EURIBOR 3M Index
  private static final Period TENOR = Period.ofMonths(3);
  private static final int SETTLEMENT_DAYS = 2;
  private static final Calendar CALENDAR = new MondayToFridayCalendar("A");
  private static final DayCount DAY_COUNT_INDEX =
      DayCountFactory.INSTANCE.getDayCount("Actual/360");
  private static final BusinessDayConvention BUSINESS_DAY =
      BusinessDayConventionFactory.INSTANCE.getBusinessDayConvention("Modified Following");
  private static final boolean IS_EOM = true;
  private static final Currency CUR = Currency.EUR;
  private static final IborIndex IBOR_INDEX =
      new IborIndex(CUR, TENOR, SETTLEMENT_DAYS, CALENDAR, DAY_COUNT_INDEX, BUSINESS_DAY, IS_EOM);
  // Future
  private static final ZonedDateTime SPOT_LAST_TRADING_DATE = DateUtil.getUTCDate(2012, 9, 19);
  private static final ZonedDateTime LAST_TRADING_DATE =
      ScheduleCalculator.getAdjustedDate(SPOT_LAST_TRADING_DATE, CALENDAR, -SETTLEMENT_DAYS);
  private static final ZonedDateTime FIXING_END_DATE =
      ScheduleCalculator.getAdjustedDate(
          SPOT_LAST_TRADING_DATE, BUSINESS_DAY, CALENDAR, IS_EOM, TENOR);
  private static final double NOTIONAL = 1000000.0; // 1m
  private static final double FUTURE_FACTOR = 0.25;
  private static final String NAME = "ERU2";
  //  private static final InterestRateFutureSecurityDefinition ERU2 = new
  // InterestRateFutureSecurityDefinition(LAST_TRADING_DATE, IBOR_INDEX, NOTIONAL, FUTURE_FACTOR,
  // NAME);

  private static final LocalDate REFERENCE_DATE = LocalDate.of(2010, 8, 18);
  private static final DayCount ACT_ACT =
      DayCountFactory.INSTANCE.getDayCount("Actual/Actual ISDA");
  private static final ZonedDateTime REFERENCE_DATE_ZONED =
      ZonedDateTime.of(LocalDateTime.ofMidnight(REFERENCE_DATE), TimeZone.UTC);
  private static final double LAST_TRADING_TIME =
      ACT_ACT.getDayCountFraction(REFERENCE_DATE_ZONED, LAST_TRADING_DATE);
  private static final double FIXING_START_TIME =
      ACT_ACT.getDayCountFraction(REFERENCE_DATE_ZONED, SPOT_LAST_TRADING_DATE);
  private static final double FIXING_END_TIME =
      ACT_ACT.getDayCountFraction(REFERENCE_DATE_ZONED, FIXING_END_DATE);
  private static final double FIXING_ACCRUAL =
      DAY_COUNT_INDEX.getDayCountFraction(SPOT_LAST_TRADING_DATE, FIXING_END_DATE);
  private static final String DISCOUNTING_CURVE_NAME = "Funding";
  private static final String FORWARD_CURVE_NAME = "Forward";
  private static final InterestRateFutureSecurity ERU2 =
      new InterestRateFutureSecurity(
          LAST_TRADING_TIME,
          IBOR_INDEX,
          FIXING_START_TIME,
          FIXING_END_TIME,
          FIXING_ACCRUAL,
          NOTIONAL,
          FUTURE_FACTOR,
          NAME,
          DISCOUNTING_CURVE_NAME,
          FORWARD_CURVE_NAME);

  @Test(expectedExceptions = IllegalArgumentException.class)
  public void testNullIndex() {
    new InterestRateFutureSecurity(
        LAST_TRADING_TIME,
        null,
        FIXING_START_TIME,
        FIXING_END_TIME,
        FIXING_ACCRUAL,
        NOTIONAL,
        FUTURE_FACTOR,
        NAME,
        DISCOUNTING_CURVE_NAME,
        FORWARD_CURVE_NAME);
  }

  @Test(expectedExceptions = IllegalArgumentException.class)
  public void testNullName() {
    new InterestRateFutureSecurity(
        LAST_TRADING_TIME,
        IBOR_INDEX,
        FIXING_START_TIME,
        FIXING_END_TIME,
        FIXING_ACCRUAL,
        NOTIONAL,
        FUTURE_FACTOR,
        null,
        DISCOUNTING_CURVE_NAME,
        FORWARD_CURVE_NAME);
  }

  @Test(expectedExceptions = IllegalArgumentException.class)
  public void testNullDscCurve() {
    new InterestRateFutureSecurity(
        LAST_TRADING_TIME,
        IBOR_INDEX,
        FIXING_START_TIME,
        FIXING_END_TIME,
        FIXING_ACCRUAL,
        NOTIONAL,
        FUTURE_FACTOR,
        NAME,
        null,
        FORWARD_CURVE_NAME);
  }

  @Test(expectedExceptions = IllegalArgumentException.class)
  public void testNullForwardCurve() {
    new InterestRateFutureSecurity(
        LAST_TRADING_TIME,
        IBOR_INDEX,
        FIXING_START_TIME,
        FIXING_END_TIME,
        FIXING_ACCRUAL,
        NOTIONAL,
        FUTURE_FACTOR,
        NAME,
        DISCOUNTING_CURVE_NAME,
        null);
  }

  @Test
  public void getter() {
    assertEquals(LAST_TRADING_TIME, ERU2.getLastTradingTime());
    assertEquals(IBOR_INDEX, ERU2.getIborIndex());
    assertEquals(NOTIONAL, ERU2.getNotional());
    assertEquals(FUTURE_FACTOR, ERU2.getPaymentAccrualFactor());
    assertEquals(DISCOUNTING_CURVE_NAME, ERU2.getDiscountingCurveName());
    assertEquals(FORWARD_CURVE_NAME, ERU2.getForwardCurveName());
    assertEquals(NAME, ERU2.getName());
    assertEquals(FIXING_START_TIME, ERU2.getFixingPeriodStartTime());
    assertEquals(FIXING_END_TIME, ERU2.getFixingPeriodEndTime());
    assertEquals(FIXING_ACCRUAL, ERU2.getFixingPeriodAccrualFactor());
  }

  @Test
  public void equalHash() {
    assertTrue(ERU2.equals(ERU2));
    InterestRateFutureSecurity other =
        new InterestRateFutureSecurity(
            LAST_TRADING_TIME,
            IBOR_INDEX,
            FIXING_START_TIME,
            FIXING_END_TIME,
            FIXING_ACCRUAL,
            NOTIONAL,
            FUTURE_FACTOR,
            NAME,
            DISCOUNTING_CURVE_NAME,
            FORWARD_CURVE_NAME);
    assertTrue(ERU2.equals(other));
    assertTrue(ERU2.hashCode() == other.hashCode());
    assertEquals(ERU2.toString(), other.toString());
    InterestRateFutureSecurity modifiedFuture;
    modifiedFuture =
        new InterestRateFutureSecurity(
            LAST_TRADING_TIME - 0.01,
            IBOR_INDEX,
            FIXING_START_TIME,
            FIXING_END_TIME,
            FIXING_ACCRUAL,
            NOTIONAL,
            FUTURE_FACTOR,
            NAME,
            DISCOUNTING_CURVE_NAME,
            FORWARD_CURVE_NAME);
    assertFalse(ERU2.equals(modifiedFuture));
    modifiedFuture =
        new InterestRateFutureSecurity(
            LAST_TRADING_TIME,
            IBOR_INDEX,
            FIXING_START_TIME + 0.01,
            FIXING_END_TIME,
            FIXING_ACCRUAL,
            NOTIONAL,
            FUTURE_FACTOR,
            NAME,
            DISCOUNTING_CURVE_NAME,
            FORWARD_CURVE_NAME);
    assertFalse(ERU2.equals(modifiedFuture));
    modifiedFuture =
        new InterestRateFutureSecurity(
            LAST_TRADING_TIME,
            IBOR_INDEX,
            FIXING_START_TIME,
            FIXING_END_TIME + 0.01,
            FIXING_ACCRUAL,
            NOTIONAL,
            FUTURE_FACTOR,
            NAME,
            DISCOUNTING_CURVE_NAME,
            FORWARD_CURVE_NAME);
    assertFalse(ERU2.equals(modifiedFuture));
    modifiedFuture =
        new InterestRateFutureSecurity(
            LAST_TRADING_TIME,
            IBOR_INDEX,
            FIXING_START_TIME,
            FIXING_END_TIME,
            FIXING_ACCRUAL + 0.01,
            NOTIONAL,
            FUTURE_FACTOR,
            NAME,
            DISCOUNTING_CURVE_NAME,
            FORWARD_CURVE_NAME);
    assertFalse(ERU2.equals(modifiedFuture));
    modifiedFuture =
        new InterestRateFutureSecurity(
            LAST_TRADING_TIME,
            IBOR_INDEX,
            FIXING_START_TIME,
            FIXING_END_TIME,
            FIXING_ACCRUAL,
            NOTIONAL + 1.0,
            FUTURE_FACTOR,
            NAME,
            DISCOUNTING_CURVE_NAME,
            FORWARD_CURVE_NAME);
    assertFalse(ERU2.equals(modifiedFuture));
    modifiedFuture =
        new InterestRateFutureSecurity(
            LAST_TRADING_TIME,
            IBOR_INDEX,
            FIXING_START_TIME,
            FIXING_END_TIME,
            FIXING_ACCRUAL,
            NOTIONAL,
            FUTURE_FACTOR + 0.25,
            NAME,
            DISCOUNTING_CURVE_NAME,
            FORWARD_CURVE_NAME);
    assertFalse(ERU2.equals(modifiedFuture));
    modifiedFuture =
        new InterestRateFutureSecurity(
            LAST_TRADING_TIME,
            IBOR_INDEX,
            FIXING_START_TIME,
            FIXING_END_TIME,
            FIXING_ACCRUAL,
            NOTIONAL,
            FUTURE_FACTOR,
            NAME,
            DISCOUNTING_CURVE_NAME + "NO",
            FORWARD_CURVE_NAME);
    assertFalse(ERU2.equals(modifiedFuture));
    modifiedFuture =
        new InterestRateFutureSecurity(
            LAST_TRADING_TIME,
            IBOR_INDEX,
            FIXING_START_TIME,
            FIXING_END_TIME,
            FIXING_ACCRUAL,
            NOTIONAL,
            FUTURE_FACTOR,
            NAME,
            DISCOUNTING_CURVE_NAME,
            FORWARD_CURVE_NAME + "NO");
    assertFalse(ERU2.equals(modifiedFuture));
    modifiedFuture =
        new InterestRateFutureSecurity(
            LAST_TRADING_TIME,
            IBOR_INDEX,
            FIXING_START_TIME,
            FIXING_END_TIME,
            FIXING_ACCRUAL,
            NOTIONAL,
            FUTURE_FACTOR,
            NAME + NAME,
            DISCOUNTING_CURVE_NAME,
            FORWARD_CURVE_NAME);
    assertFalse(ERU2.equals(modifiedFuture));
    IborIndex otherIndex =
        new IborIndex(
            CUR, TENOR, SETTLEMENT_DAYS, CALENDAR, DAY_COUNT_INDEX, BUSINESS_DAY, !IS_EOM);
    modifiedFuture =
        new InterestRateFutureSecurity(
            LAST_TRADING_TIME,
            otherIndex,
            FIXING_START_TIME,
            FIXING_END_TIME,
            FIXING_ACCRUAL,
            NOTIONAL,
            FUTURE_FACTOR,
            NAME,
            DISCOUNTING_CURVE_NAME,
            FORWARD_CURVE_NAME);
    assertFalse(ERU2.equals(modifiedFuture));
    assertFalse(ERU2.equals(LAST_TRADING_DATE));
    assertFalse(ERU2.equals(null));
  }
}
/** Tests the method for interest rate future option with SABR volatility parameter surfaces. */
public class InterestRateFutureOptionMarginSecuritySABRMethodTest {
  // EURIBOR 3M Index
  private static final Period TENOR = Period.ofMonths(3);
  private static final int SETTLEMENT_DAYS = 2;
  private static final Calendar CALENDAR = new MondayToFridayCalendar("A");
  private static final DayCount DAY_COUNT_INDEX =
      DayCountFactory.INSTANCE.getDayCount("Actual/360");
  private static final BusinessDayConvention BUSINESS_DAY =
      BusinessDayConventionFactory.INSTANCE.getBusinessDayConvention("Modified Following");
  private static final boolean IS_EOM = true;
  private static final Currency CUR = Currency.USD;
  private static final IborIndex IBOR_INDEX =
      new IborIndex(CUR, TENOR, SETTLEMENT_DAYS, CALENDAR, DAY_COUNT_INDEX, BUSINESS_DAY, IS_EOM);
  // Future
  private static final ZonedDateTime SPOT_LAST_TRADING_DATE = DateUtil.getUTCDate(2012, 9, 19);
  private static final ZonedDateTime LAST_TRADING_DATE =
      ScheduleCalculator.getAdjustedDate(SPOT_LAST_TRADING_DATE, CALENDAR, -SETTLEMENT_DAYS);
  private static final double NOTIONAL = 1000000.0; // 1m
  private static final double FUTURE_FACTOR = 0.25;
  private static final String NAME = "EDU2";
  private static final InterestRateFutureSecurityDefinition EDU2_DEFINITION =
      new InterestRateFutureSecurityDefinition(
          LAST_TRADING_DATE, IBOR_INDEX, NOTIONAL, FUTURE_FACTOR, NAME);
  private static final ZonedDateTime REFERENCE_DATE = DateUtil.getUTCDate(2010, 8, 18);
  private static final String DISCOUNTING_CURVE_NAME = "Funding";
  private static final String FORWARD_CURVE_NAME = "Forward";
  private static final String[] CURVES = {DISCOUNTING_CURVE_NAME, FORWARD_CURVE_NAME};
  private static final InterestRateFutureSecurity EDU2 =
      EDU2_DEFINITION.toDerivative(REFERENCE_DATE, CURVES);
  // Option
  private static final ZonedDateTime EXPIRATION_DATE = DateUtil.getUTCDate(2011, 9, 16);
  private static final DayCount ACT_ACT =
      DayCountFactory.INSTANCE.getDayCount("Actual/Actual ISDA");
  private static final double EXPIRATION_TIME =
      ACT_ACT.getDayCountFraction(REFERENCE_DATE, EXPIRATION_DATE);
  private static final double STRIKE = 0.9850;
  private static final boolean IS_CALL = true;
  private static final InterestRateFutureOptionMarginSecurity OPTION_EDU2 =
      new InterestRateFutureOptionMarginSecurity(EDU2, EXPIRATION_TIME, STRIKE, IS_CALL);
  private static final InterestRateFutureOptionMarginSecuritySABRMethod METHOD =
      new InterestRateFutureOptionMarginSecuritySABRMethod();

  final YieldCurveBundle CURVES_BUNDLE = TestsDataSets.createCurves1();
  final SABRInterestRateParameters SABR_PARAMETER = TestsDataSets.createSABR1();
  final SABRInterestRateDataBundle SABR_BUNDLE =
      new SABRInterestRateDataBundle(SABR_PARAMETER, CURVES_BUNDLE);

  @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);
  }

  @Test
  /** Test the option price from the future price. Standard option. */
  public void priceStandard() {
    final double expirationTime = ACT_ACT.getDayCountFraction(REFERENCE_DATE, LAST_TRADING_DATE);
    final InterestRateFutureOptionMarginSecurity optionEDU2Standard =
        new InterestRateFutureOptionMarginSecurity(EDU2, expirationTime, STRIKE, IS_CALL);
    final double priceOption = METHOD.optionPrice(optionEDU2Standard, SABR_BUNDLE);
    final InterestRateFutureSecurityDiscountingMethod methodFuture =
        InterestRateFutureSecurityDiscountingMethod.getInstance();
    final double priceFuture = methodFuture.priceFromCurves(EDU2, CURVES_BUNDLE);
    final double priceOptionExpected =
        METHOD.optionPriceFromFuturePrice(optionEDU2Standard, SABR_BUNDLE, priceFuture);
    assertEquals(
        "Future option with SABR volatilities: option price", priceOptionExpected, priceOption);
  }
}
/**
 * Tests for the methods related to interest rate securities pricing with Hull-White model convexity
 * adjustment.
 */
public class InterestRateFutureSecurityHullWhiteMethodTest {
  // EURIBOR 3M Index
  private static final Period TENOR = Period.ofMonths(3);
  private static final int SETTLEMENT_DAYS = 2;
  private static final Calendar CALENDAR = new MondayToFridayCalendar("A");
  private static final DayCount DAY_COUNT_INDEX =
      DayCountFactory.INSTANCE.getDayCount("Actual/360");
  private static final BusinessDayConvention BUSINESS_DAY =
      BusinessDayConventionFactory.INSTANCE.getBusinessDayConvention("Modified Following");
  private static final boolean IS_EOM = true;
  private static final Currency CUR = Currency.EUR;
  private static final IborIndex IBOR_INDEX =
      new IborIndex(CUR, TENOR, SETTLEMENT_DAYS, CALENDAR, DAY_COUNT_INDEX, BUSINESS_DAY, IS_EOM);
  // Future
  private static final ZonedDateTime SPOT_LAST_TRADING_DATE = DateUtil.getUTCDate(2012, 9, 19);
  private static final ZonedDateTime LAST_TRADING_DATE =
      ScheduleCalculator.getAdjustedDate(SPOT_LAST_TRADING_DATE, CALENDAR, -SETTLEMENT_DAYS);
  private static final ZonedDateTime FIXING_END_DATE =
      ScheduleCalculator.getAdjustedDate(
          SPOT_LAST_TRADING_DATE, BUSINESS_DAY, CALENDAR, IS_EOM, TENOR);
  private static final double NOTIONAL = 1000000.0; // 1m
  private static final double FUTURE_FACTOR = 0.25;
  private static final String NAME = "ERU2";
  // Time version
  private static final LocalDate REFERENCE_DATE = LocalDate.of(2011, 5, 12);
  private static final DayCount ACT_ACT =
      DayCountFactory.INSTANCE.getDayCount("Actual/Actual ISDA");
  private static final ZonedDateTime REFERENCE_DATE_ZONED =
      ZonedDateTime.of(LocalDateTime.ofMidnight(REFERENCE_DATE), TimeZone.UTC);
  private static final double LAST_TRADING_TIME =
      ACT_ACT.getDayCountFraction(REFERENCE_DATE_ZONED, LAST_TRADING_DATE);
  private static final double FIXING_START_TIME =
      ACT_ACT.getDayCountFraction(REFERENCE_DATE_ZONED, SPOT_LAST_TRADING_DATE);
  private static final double FIXING_END_TIME =
      ACT_ACT.getDayCountFraction(REFERENCE_DATE_ZONED, FIXING_END_DATE);
  private static final double FIXING_ACCRUAL =
      DAY_COUNT_INDEX.getDayCountFraction(SPOT_LAST_TRADING_DATE, FIXING_END_DATE);
  private static final String DISCOUNTING_CURVE_NAME = "Funding";
  private static final String FORWARD_CURVE_NAME = "Forward";
  private static final InterestRateFutureSecurity ERU2 =
      new InterestRateFutureSecurity(
          LAST_TRADING_TIME,
          IBOR_INDEX,
          FIXING_START_TIME,
          FIXING_END_TIME,
          FIXING_ACCRUAL,
          NOTIONAL,
          FUTURE_FACTOR,
          NAME,
          DISCOUNTING_CURVE_NAME,
          FORWARD_CURVE_NAME);
  private static final double MEAN_REVERSION = 0.01;
  private static final double[] VOLATILITY = new double[] {0.01, 0.011, 0.012, 0.013, 0.014};
  private static final double[] VOLATILITY_TIME = new double[] {0.5, 1.0, 2.0, 5.0};
  private static final HullWhiteOneFactorPiecewiseConstantParameters MODEL_PARAMETERS =
      new HullWhiteOneFactorPiecewiseConstantParameters(
          MEAN_REVERSION, VOLATILITY, VOLATILITY_TIME);
  private static final InterestRateFutureSecurityHullWhiteMethod METHOD =
      new InterestRateFutureSecurityHullWhiteMethod(MODEL_PARAMETERS);
  private static final HullWhiteOneFactorPiecewiseConstantInterestRateModel MODEL =
      new HullWhiteOneFactorPiecewiseConstantInterestRateModel();

  @Test
  /** Test the constructors. */
  public void constructor() {
    final InterestRateFutureSecurityHullWhiteMethod methodParameters =
        new InterestRateFutureSecurityHullWhiteMethod(MEAN_REVERSION, VOLATILITY, VOLATILITY_TIME);
    assertTrue(METHOD.equals(methodParameters));
  }

  @Test
  /** Test the price computed from the curves */
  public void price() {
    final YieldCurveBundle curves = TestsDataSets.createCurves1();
    final double price = METHOD.price(ERU2, curves);
    final YieldAndDiscountCurve forwardCurve = curves.getCurve(FORWARD_CURVE_NAME);
    final double forward =
        (forwardCurve.getDiscountFactor(FIXING_START_TIME)
                    / forwardCurve.getDiscountFactor(FIXING_END_TIME)
                - 1)
            / FIXING_ACCRUAL;
    final double factor = MODEL.futureConvexityFactor(ERU2, MODEL_PARAMETERS);
    final double expectedPrice = 1.0 - factor * forward + (1 - factor) / FIXING_ACCRUAL;
    assertEquals("Future price from curves in Hull-White one factor model", expectedPrice, price);
  }

  @Test
  /** Compare the price with a price without convexity adjustment. */
  public void comparisonDiscounting() {
    final YieldCurveBundle curves = TestsDataSets.createCurves1();
    final InterestRateFutureSecurityDiscountingMethod methodDiscounting =
        InterestRateFutureSecurityDiscountingMethod.getInstance();
    final double priceDiscounting = methodDiscounting.priceFromCurves(ERU2, curves);
    final double priceHullWhite = METHOD.price(ERU2, curves);
    assertTrue(
        "Future price comparison with no convexity adjustment", priceDiscounting > priceHullWhite);
  }

  @Test
  public void equalHash() {
    assertTrue(METHOD.equals(METHOD));
    InterestRateFutureSecurityHullWhiteMethod other =
        new InterestRateFutureSecurityHullWhiteMethod(MODEL_PARAMETERS);
    assertTrue(METHOD.equals(other));
    assertTrue(METHOD.hashCode() == other.hashCode());
    InterestRateFutureSecurityHullWhiteMethod modifiedMethod;
    HullWhiteOneFactorPiecewiseConstantParameters modifiedParameter =
        new HullWhiteOneFactorPiecewiseConstantParameters(
            MEAN_REVERSION * 2, VOLATILITY, VOLATILITY_TIME);
    modifiedMethod = new InterestRateFutureSecurityHullWhiteMethod(modifiedParameter);
    assertFalse(METHOD.equals(modifiedMethod));
    assertFalse(METHOD.equals(CUR));
    assertFalse(METHOD.equals(null));
  }
}
 @Test
 public void testEndOfMonth2() {
   final ZonedDateTime startDate = DateUtil.getUTCDate(2009, 11, 30);
   final ZonedDateTime endDate = DateUtil.getUTCDate(2010, 8, 31);
   final ZonedDateTime[] fromStart =
       new ZonedDateTime[] {
         DateUtil.getUTCDate(2009, 11, 30),
         DateUtil.getUTCDate(2009, 12, 30),
         DateUtil.getUTCDate(2010, 1, 30),
         DateUtil.getUTCDate(2010, 2, 28),
         DateUtil.getUTCDate(2010, 3, 30),
         DateUtil.getUTCDate(2010, 4, 30),
         DateUtil.getUTCDate(2010, 5, 30),
         DateUtil.getUTCDate(2010, 6, 30),
         DateUtil.getUTCDate(2010, 7, 30),
         DateUtil.getUTCDate(2010, 8, 30)
       };
   final ZonedDateTime[] fromStartRecursive =
       new ZonedDateTime[] {
         DateUtil.getUTCDate(2009, 11, 30),
         DateUtil.getUTCDate(2009, 12, 30),
         DateUtil.getUTCDate(2010, 1, 30),
         DateUtil.getUTCDate(2010, 2, 28),
         DateUtil.getUTCDate(2010, 3, 28),
         DateUtil.getUTCDate(2010, 4, 28),
         DateUtil.getUTCDate(2010, 5, 28),
         DateUtil.getUTCDate(2010, 6, 28),
         DateUtil.getUTCDate(2010, 7, 28),
         DateUtil.getUTCDate(2010, 8, 28)
       };
   final ZonedDateTime[] fromEnd =
       new ZonedDateTime[] {
         DateUtil.getUTCDate(2009, 11, 30),
         DateUtil.getUTCDate(2009, 12, 31),
         DateUtil.getUTCDate(2010, 1, 31),
         DateUtil.getUTCDate(2010, 2, 28),
         DateUtil.getUTCDate(2010, 3, 31),
         DateUtil.getUTCDate(2010, 4, 30),
         DateUtil.getUTCDate(2010, 5, 31),
         DateUtil.getUTCDate(2010, 6, 30),
         DateUtil.getUTCDate(2010, 7, 31),
         DateUtil.getUTCDate(2010, 8, 31)
       };
   final ZonedDateTime[] fromEndRecursive =
       new ZonedDateTime[] {
         DateUtil.getUTCDate(2009, 12, 28),
         DateUtil.getUTCDate(2010, 1, 28),
         DateUtil.getUTCDate(2010, 2, 28),
         DateUtil.getUTCDate(2010, 3, 30),
         DateUtil.getUTCDate(2010, 4, 30),
         DateUtil.getUTCDate(2010, 5, 30),
         DateUtil.getUTCDate(2010, 6, 30),
         DateUtil.getUTCDate(2010, 7, 31),
         DateUtil.getUTCDate(2010, 8, 31)
       };
   assertArrayEquals(fromStart, CALCULATOR.getSchedule(startDate, endDate, false, false));
   assertArrayEquals(fromStartRecursive, CALCULATOR.getSchedule(startDate, endDate, false, true));
   assertArrayEquals(fromEnd, CALCULATOR.getSchedule(startDate, endDate, true, false));
   assertArrayEquals(fromEndRecursive, CALCULATOR.getSchedule(startDate, endDate, true, true));
 }
 @Test(expectedExceptions = IllegalArgumentException.class)
 public void testStartAfterEnd() {
   CALCULATOR.getSchedule(
       DateUtil.getUTCDate(2001, 1, 1), DateUtil.getUTCDate(2000, 1, 1), true, true);
 }
public class BondFixedDescriptionTest {

  // Semi-annual 2Y
  private static final Currency CUR = Currency.USD;
  private static final Period PAYMENT_TENOR = Period.ofMonths(6);
  private static final int PAYMENT_PER_YEAR = 2;
  private static final Calendar CALENDAR = new MondayToFridayCalendar("A");
  private static final DayCount DAY_COUNT =
      DayCountFactory.INSTANCE.getDayCount("Actual/Actual ICMA");
  private static final BusinessDayConvention BUSINESS_DAY =
      BusinessDayConventionFactory.INSTANCE.getBusinessDayConvention("Following");
  private static final boolean IS_EOM = false;
  private static final Period BOND_TENOR = Period.ofYears(2);
  private static final ZonedDateTime START_ACCRUAL_DATE = DateUtil.getUTCDate(2011, 7, 13);
  private static final ZonedDateTime MATURITY_DATE = START_ACCRUAL_DATE.plus(BOND_TENOR);
  private static final double RATE = 0.0325;
  private static final YieldConvention YIELD_CONVENTION =
      YieldConventionFactory.INSTANCE.getYieldConvention("STREET CONVENTION");
  private static final AnnuityCouponFixedDefinition COUPON_DEFINITION =
      AnnuityCouponFixedDefinition.fromAccrualUnadjusted(
          CUR,
          START_ACCRUAL_DATE,
          MATURITY_DATE,
          PAYMENT_TENOR,
          PAYMENT_PER_YEAR,
          CALENDAR,
          DAY_COUNT,
          BUSINESS_DAY,
          IS_EOM,
          1.0,
          RATE,
          false);
  private static final AnnuityPaymentFixedDefinition NOMINAL_DEFINITION =
      new AnnuityPaymentFixedDefinition(
          new PaymentFixedDefinition[] {new PaymentFixedDefinition(CUR, MATURITY_DATE, 1.0)});
  // to derivatives: common
  private static final String FUNDING_CURVE_NAME = "Funding";
  private static final String FORWARD_CURVE_NAME = "Forward";
  private static final String[] CURVES_NAME = {FUNDING_CURVE_NAME, FORWARD_CURVE_NAME};
  YieldCurveBundle CURVES = TestsDataSets.createCurves1();
  // to derivatives: first coupon
  private static final ZonedDateTime REFERENCE_DATE_1 = DateUtil.getUTCDate(2011, 8, 18);
  private static final AnnuityCouponFixed COUPON_1 =
      COUPON_DEFINITION.toDerivative(REFERENCE_DATE_1, CURVES_NAME);
  private static final AnnuityPaymentFixed NOMINAL_1 =
      NOMINAL_DEFINITION.toDerivative(REFERENCE_DATE_1, CURVES_NAME);
  private static final BondFixedDescription BOND_DESCRIPTION_1 =
      new BondFixedDescription(NOMINAL_1, COUPON_1, YIELD_CONVENTION);
  // to derivatives: second coupon
  private static final ZonedDateTime REFERENCE_DATE_2 = DateUtil.getUTCDate(2012, 2, 16);
  private static final AnnuityCouponFixed COUPON_2 =
      COUPON_DEFINITION.toDerivative(REFERENCE_DATE_2, CURVES_NAME);
  private static final AnnuityPaymentFixed NOMINAL_2 =
      NOMINAL_DEFINITION.toDerivative(REFERENCE_DATE_2, CURVES_NAME);
  private static final BondFixedDescription BOND_DESCRIPTION_2 =
      new BondFixedDescription(NOMINAL_2, COUPON_2, YIELD_CONVENTION);

  @Test(expectedExceptions = IllegalArgumentException.class)
  public void testNullNominal() {
    new BondFixedDescription(null, COUPON_1, YIELD_CONVENTION);
  }

  @Test(expectedExceptions = IllegalArgumentException.class)
  public void testNullCoupon() {
    new BondFixedDescription(NOMINAL_1, null, YIELD_CONVENTION);
  }

  @Test(expectedExceptions = IllegalArgumentException.class)
  public void testNullYield() {
    new BondFixedDescription(NOMINAL_1, COUPON_1, null);
  }

  @Test
  public void testGetters1() {
    assertEquals(NOMINAL_1, BOND_DESCRIPTION_1.getNominal());
    assertEquals(COUPON_1, BOND_DESCRIPTION_1.getCoupon());
  }

  @Test
  public void testGetters2() {
    assertEquals(NOMINAL_2, BOND_DESCRIPTION_2.getNominal());
    assertEquals(COUPON_2, BOND_DESCRIPTION_2.getCoupon());
  }
}
public class VasicekDataBundleTest {
  private static final YieldCurve SHORT_RATE = new YieldCurve(ConstantDoublesCurve.from(0.02));
  private static final double LONG_RATE = 0.05;
  private static final double SPEED = 0.1;
  private static final VolatilityCurve SIGMA = new VolatilityCurve(ConstantDoublesCurve.from(0.4));
  private static final ZonedDateTime DATE = DateUtil.getUTCDate(2010, 1, 1);
  private static final VasicekDataBundle DATA =
      new VasicekDataBundle(SHORT_RATE, SIGMA, DATE, LONG_RATE, SPEED);

  @Test(expectedExceptions = IllegalArgumentException.class)
  public void testNullShortRate() {
    new VasicekDataBundle(null, SIGMA, DATE, LONG_RATE, SPEED);
  }

  @Test(expectedExceptions = IllegalArgumentException.class)
  public void testNullVolatility() {
    new VasicekDataBundle(SHORT_RATE, null, DATE, LONG_RATE, SPEED);
  }

  @Test(expectedExceptions = IllegalArgumentException.class)
  public void testNullDate() {
    new VasicekDataBundle(SHORT_RATE, SIGMA, null, LONG_RATE, SPEED);
  }

  @Test(expectedExceptions = IllegalArgumentException.class)
  public void testZeroSpeed() {
    new VasicekDataBundle(SHORT_RATE, SIGMA, DATE, LONG_RATE, 0);
  }

  @Test
  public void testGetters() {
    final double t = Math.random();
    assertEquals(DATA.getShortRateCurve(), SHORT_RATE);
    assertEquals(DATA.getShortRate(t), SHORT_RATE.getInterestRate(t), 0);
    assertEquals(DATA.getLongTermInterestRate(), LONG_RATE, 0);
    assertEquals(DATA.getReversionSpeed(), SPEED, 0);
    assertEquals(DATA.getShortRateVolatilityCurve(), SIGMA);
    assertEquals(DATA.getShortRateVolatility(t), SIGMA.getVolatility(t), 0);
    assertEquals(DATA.getDate(), DATE);
  }

  @Test
  public void testHashCodeAndEquals() {
    VasicekDataBundle other = new VasicekDataBundle(SHORT_RATE, SIGMA, DATE, LONG_RATE, SPEED);
    assertEquals(other, DATA);
    assertEquals(other.hashCode(), DATA.hashCode());
    other =
        new VasicekDataBundle(
            new YieldCurve(ConstantDoublesCurve.from(SHORT_RATE.getInterestRate(0.) + 1)),
            SIGMA,
            DATE,
            LONG_RATE,
            SPEED);
    assertFalse(other.equals(DATA));
    other =
        new VasicekDataBundle(
            SHORT_RATE,
            new VolatilityCurve(ConstantDoublesCurve.from(SIGMA.getVolatility(0.) + 0.2)),
            DATE,
            LONG_RATE,
            SPEED);
    assertFalse(other.equals(DATA));
    other = new VasicekDataBundle(SHORT_RATE, SIGMA, DATE.plusDays(10), LONG_RATE, SPEED);
    assertFalse(other.equals(DATA));
    other = new VasicekDataBundle(SHORT_RATE, SIGMA, DATE, LONG_RATE + 1, SPEED);
    assertFalse(other.equals(DATA));
    other = new VasicekDataBundle(SHORT_RATE, SIGMA, DATE, LONG_RATE, SPEED + 1);
    assertFalse(other.equals(DATA));
  }
}