@Test
 public void toDerivativesStartMonthKnown() {
   final ZonedDateTime pricingDate = DateUtils.getUTCDate(2018, 6, 25);
   final DoubleTimeSeries<ZonedDateTime> priceIndexTS =
       ImmutableZonedDateTimeDoubleTimeSeries.ofUTC(
           new ZonedDateTime[] {
             DateUtils.getUTCDate(2017, 5, 1),
             DateUtils.getUTCDate(2017, 6, 1),
             DateUtils.getUTCDate(2018, 5, 1),
             DateUtils.getUTCDate(2018, 6, 1)
           },
           new double[] {127.23, 127.43, 128.23, 128.43});
   Coupon zeroCouponConverted =
       YoY_COUPON_DEFINITION.toDerivative(pricingDate, priceIndexTS, CURVE_NAMES);
   double paymentTime = ACT_ACT.getDayCountFraction(pricingDate, PAYMENT_DATE);
   CouponFixed zeroCoupon =
       new CouponFixed(
           CUR,
           paymentTime,
           DISCOUNTING_CURVE_NAME,
           1.0,
           NOTIONAL,
           (WEIGHT_END * 128.23 + (1 - WEIGHT_END) * 128.43)
                   / (WEIGHT_START * 127.23 + (1 - WEIGHT_START) * 127.43)
               - 1.0);
   assertEquals("Inflation zero-coupon: toDerivative", zeroCoupon, zeroCouponConverted);
 }
public class BondIborTransactionDefinitionTest {

  // Quarterly Libor6m 2Y
  private static final Currency CUR = Currency.USD;
  private static final Calendar CALENDAR = new MondayToFridayCalendar("A");
  private static final DayCount DAY_COUNT =
      DayCountFactory.INSTANCE.getDayCount("Actual/Actual ISDA");
  private static final BusinessDayConvention BUSINESS_DAY =
      BusinessDayConventionFactory.INSTANCE.getBusinessDayConvention("Following");
  private static final boolean IS_EOM = false;
  private static final Period IBOR_TENOR = Period.ofMonths(3);
  private static final DayCount IBOR_DAY_COUNT = DayCountFactory.INSTANCE.getDayCount("30/360");
  private static final int IBOR_SPOT_LAG = 2;
  private static final BusinessDayConvention IBOR_BUSINESS_DAY =
      BusinessDayConventionFactory.INSTANCE.getBusinessDayConvention("Modified Following");
  private static final boolean IBOR_IS_EOM = false;
  private static final IborIndex IBOR_INDEX =
      new IborIndex(
          CUR, IBOR_TENOR, IBOR_SPOT_LAG, CALENDAR, IBOR_DAY_COUNT, IBOR_BUSINESS_DAY, IBOR_IS_EOM);
  private static final Period BOND_TENOR = Period.ofYears(2);
  private static final int SETTLEMENT_DAYS = 3; // Standard for euro-bonds.
  private static final ZonedDateTime START_ACCRUAL_DATE = DateUtils.getUTCDate(2011, 7, 13);
  private static final ZonedDateTime MATURITY_DATE = START_ACCRUAL_DATE.plus(BOND_TENOR);
  private static final BondIborSecurityDefinition BOND_DESCRIPTION =
      BondIborSecurityDefinition.from(
          MATURITY_DATE,
          START_ACCRUAL_DATE,
          IBOR_INDEX,
          SETTLEMENT_DAYS,
          DAY_COUNT,
          BUSINESS_DAY,
          IS_EOM);
  // Transaction
  private static final double PRICE = 0.90;
  private static final ZonedDateTime SETTLEMENT_DATE = DateUtils.getUTCDate(2011, 8, 18);
  private static final double QUANTITY = 100000000; // 100m
  private static final BondIborTransactionDefinition BOND_TRANSACTION =
      new BondIborTransactionDefinition(BOND_DESCRIPTION, QUANTITY, SETTLEMENT_DATE, PRICE);

  @Test(expectedExceptions = IllegalArgumentException.class)
  public void testNullUnderlying() {
    new BondIborTransactionDefinition(null, QUANTITY, SETTLEMENT_DATE, PRICE);
  }

  @Test(expectedExceptions = IllegalArgumentException.class)
  public void testNullSettle() {
    new BondIborTransactionDefinition(BOND_DESCRIPTION, QUANTITY, null, PRICE);
  }

  @Test
  public void testGetters() {
    assertEquals(PRICE, BOND_TRANSACTION.getPrice());
    assertEquals(QUANTITY, BOND_TRANSACTION.getQuantity());
    assertEquals(SETTLEMENT_DATE, BOND_TRANSACTION.getSettlementDate());
    assertEquals(BOND_DESCRIPTION, BOND_TRANSACTION.getUnderlyingBond());
    assertEquals(DateUtils.getUTCDate(2011, 7, 13), BOND_TRANSACTION.getPreviousAccrualDate());
    assertEquals(DateUtils.getUTCDate(2011, 10, 13), BOND_TRANSACTION.getNextAccrualDate());
  }
}
 @Test
 public void testGetters() {
   assertEquals(PRICE, BOND_TRANSACTION.getPrice());
   assertEquals(QUANTITY, BOND_TRANSACTION.getQuantity());
   assertEquals(SETTLEMENT_DATE, BOND_TRANSACTION.getSettlementDate());
   assertEquals(BOND_DESCRIPTION, BOND_TRANSACTION.getUnderlyingBond());
   assertEquals(DateUtils.getUTCDate(2011, 7, 13), BOND_TRANSACTION.getPreviousAccrualDate());
   assertEquals(DateUtils.getUTCDate(2011, 10, 13), BOND_TRANSACTION.getNextAccrualDate());
 }
/** Tests related to the discounting method for bond security. */
public class BondSecurityFRDiscountingMethodTest {

  // Calculators
  private static final PresentValueCalculator PVC = PresentValueCalculator.getInstance();
  private static final BondSecurityDiscountingMethod METHOD =
      BondSecurityDiscountingMethod.getInstance();

  private static final double TOLERANCE_PRICE = 1.0E-8;

  private static final String REPO_TYPE = "General collateral";
  private static final Currency EUR = Currency.EUR;
  private static final Calendar TARGET = new MondayToFridayCalendar("TARGET");
  private static final DayCount DAY_COUNT_ACTACTICMA =
      DayCountFactory.INSTANCE.getDayCount("Actual/Actual ICMA");
  private static final BusinessDayConvention BUSINESS_DAY_FOL =
      BusinessDayConventionFactory.INSTANCE.getBusinessDayConvention("Following");
  private static final boolean IS_EOM_FIXED = false;

  // To derivatives
  private static final DayCount ACT_ACT =
      DayCountFactory.INSTANCE.getDayCount("Actual/Actual ISDA");
  private static final String CREDIT_CURVE_NAME = "Credit";
  private static final String REPO_CURVE_NAME = "Repo";
  private static final String FORWARD_CURVE_NAME = "Forward";
  private static final String[] CURVES_NAME = {
    CREDIT_CURVE_NAME, REPO_CURVE_NAME, FORWARD_CURVE_NAME
  };
  private static final YieldCurveBundle CURVES = TestsDataSetsSABR.createCurvesBond1();

  // FRTR 4 1/2 04/25/41 - ISIN:  FR0010773192
  private static final String ISSUER_FR = "FRANCE (GOVT OF)";
  private static final YieldConvention YIELD_CONVENTION_FRANCE =
      SimpleYieldConvention.FRANCE_COMPOUND_METHOD;
  private static final int SETTLEMENT_DAYS_FR = 3;
  private static final Period PAYMENT_TENOR_FR = Period.ofMonths(12);
  //  private static final int COUPON_PER_YEAR_FR = 1;
  private static final ZonedDateTime BOND_START_FR = DateUtils.getUTCDate(2009, 4, 25);
  private static final ZonedDateTime BOND_MATURITY_FR = DateUtils.getUTCDate(2041, 4, 25);
  private static final ZonedDateTime BOND_FIRSTCPN_FR = DateUtils.getUTCDate(2010, 4, 25);
  private static final double RATE_FR = 0.0450;
  private static final BondFixedSecurityDefinition BOND_FR_SECURITY_DEFINITION =
      BondFixedSecurityDefinition.from(
          EUR,
          BOND_START_FR,
          BOND_FIRSTCPN_FR,
          BOND_MATURITY_FR,
          PAYMENT_TENOR_FR,
          RATE_FR,
          SETTLEMENT_DAYS_FR,
          TARGET,
          DAY_COUNT_ACTACTICMA,
          BUSINESS_DAY_FOL,
          YIELD_CONVENTION_FRANCE,
          IS_EOM_FIXED,
          ISSUER_FR);
}
 @Test
 /** Tests the toDerivative method. */
 public void toDerivativeFixingOnStartNotYetFixed() {
   final ZonedDateTime referenceDate = SPOT_DATE;
   final DoubleTimeSeries<ZonedDateTime> fixingTS =
       ImmutableZonedDateTimeDoubleTimeSeries.ofUTC(
           new ZonedDateTime[] {
             DateUtils.getUTCDate(2011, 9, 7), DateUtils.getUTCDate(2011, 9, 8)
           },
           new double[] {0.01, 0.01});
   final Payment cpnConverted =
       ON_COMPOUNDED_COUPON_DEFINITION.toDerivative(referenceDate, fixingTS);
   final double paymentTime =
       EUR_DAY_COUNT.getDayCountFraction(referenceDate, EUR_PAYMENT_DATE, EUR_CALENDAR);
   final double[] FIXING_PERIOD_START_TIMES =
       new double[ON_COMPOUNDED_COUPON_DEFINITION.getFixingPeriodDates().length - 1];
   final double[] FIXING_PERIOD_END_TIMES =
       new double[ON_COMPOUNDED_COUPON_DEFINITION.getFixingPeriodDates().length - 1];
   final double[] FIXING_PERIOD_ACCRUAL_FACTOR =
       new double[ON_COMPOUNDED_COUPON_DEFINITION.getFixingPeriodDates().length - 1];
   final double[] FIXING_PERIOD_ACCRUAL_FACTOR_ACT_ACT =
       new double[ON_COMPOUNDED_COUPON_DEFINITION.getFixingPeriodDates().length - 1];
   for (int i = 0; i < ON_COMPOUNDED_COUPON_DEFINITION.getFixingPeriodDates().length - 1; i++) {
     FIXING_PERIOD_START_TIMES[i] =
         EUR_DAY_COUNT.getDayCountFraction(
             referenceDate,
             ON_COMPOUNDED_COUPON_DEFINITION.getFixingPeriodDates()[i],
             EUR_CALENDAR);
     FIXING_PERIOD_END_TIMES[i] =
         EUR_DAY_COUNT.getDayCountFraction(
             referenceDate,
             ON_COMPOUNDED_COUPON_DEFINITION.getFixingPeriodDates()[i + 1],
             EUR_CALENDAR);
     FIXING_PERIOD_ACCRUAL_FACTOR[i] =
         EUR_DAY_COUNT.getDayCountFraction(
             ON_COMPOUNDED_COUPON_DEFINITION.getFixingPeriodDates()[i],
             ON_COMPOUNDED_COUPON_DEFINITION.getFixingPeriodDates()[i + 1],
             EUR_CALENDAR);
     FIXING_PERIOD_ACCRUAL_FACTOR_ACT_ACT[i] =
         TimeCalculator.getTimeBetween(
             ON_COMPOUNDED_COUPON_DEFINITION.getFixingPeriodDates()[i],
             ON_COMPOUNDED_COUPON_DEFINITION.getFixingPeriodDates()[i + 1]);
   }
   final CouponONCompounded cpnExpected =
       new CouponONCompounded(
           EUR_CUR,
           paymentTime,
           EUR_PAYMENT_YEAR_FRACTION,
           NOTIONAL,
           EUR_OIS,
           FIXING_PERIOD_START_TIMES,
           FIXING_PERIOD_END_TIMES,
           FIXING_PERIOD_ACCRUAL_FACTOR,
           NOTIONAL);
   assertEquals("CouponONCompounded definition: toDerivative", cpnExpected, cpnConverted);
 }
 @Test
 public void toDerivativesStartMonthNotknown() {
   final ZonedDateTime pricingDate = DateUtils.getUTCDate(2011, 7, 29);
   final DoubleTimeSeries<ZonedDateTime> priceIndexTS =
       ImmutableZonedDateTimeDoubleTimeSeries.ofUTC(
           new ZonedDateTime[] {
             DateUtils.getUTCDate(2017, 5, 1),
             DateUtils.getUTCDate(2017, 6, 1),
             DateUtils.getUTCDate(2018, 5, 1),
             DateUtils.getUTCDate(2018, 6, 1)
           },
           new double[] {127.23, 127.43, 128.23, 128.43});
   Coupon yearOnYearCouponConverted =
       YoY_COUPON_DEFINITION.toDerivative(pricingDate, priceIndexTS, CURVE_NAMES);
   double paymentTime = ACT_ACT.getDayCountFraction(pricingDate, PAYMENT_DATE);
   final double referenceStartTime0 =
       ACT_ACT.getDayCountFraction(pricingDate, REFERENCE_START_DATE[0]);
   final double referenceEndTime0 =
       ACT_ACT.getDayCountFraction(pricingDate, REFERENCE_END_DATE[0]);
   final double referenceStartTime1 =
       ACT_ACT.getDayCountFraction(pricingDate, REFERENCE_START_DATE[1]);
   final double referenceEndTime1 =
       ACT_ACT.getDayCountFraction(pricingDate, REFERENCE_END_DATE[1]);
   final double naturalPaymentStartPaymentTime =
       ACT_ACT.getDayCountFraction(pricingDate, ACCRUAL_START_DATE);
   final double naturalPaymentEndPaymentTime =
       ACT_ACT.getDayCountFraction(pricingDate, ACCRUAL_END_DATE);
   final double[] referenceStartTime = new double[2];
   final double[] referenceEndTime = new double[2];
   referenceStartTime[0] = referenceStartTime0;
   referenceStartTime[1] = referenceStartTime1;
   referenceEndTime[0] = referenceEndTime0;
   referenceEndTime[1] = referenceEndTime1;
   CouponInflationYearOnYearInterpolation yearOnYearCoupon =
       new CouponInflationYearOnYearInterpolation(
           CUR,
           paymentTime,
           1.0,
           NOTIONAL,
           PRICE_INDEX,
           referenceStartTime,
           naturalPaymentStartPaymentTime,
           referenceEndTime,
           naturalPaymentEndPaymentTime,
           false,
           WEIGHT_START,
           WEIGHT_END);
   assertEquals(
       "Inflation zero-coupon: toDerivative", yearOnYearCoupon, yearOnYearCouponConverted);
 }
 @Test
 public void toDerivativesNoData() {
   final ZonedDateTime pricingDate = DateUtils.getUTCDate(2011, 7, 29);
   final Coupon zeroCouponConverted = YoY_CAP_DEFINITION.toDerivative(pricingDate);
   // lastKnownFixingTime could be negatif so we don't use the dayfraction
   final double lastKnownFixingTime =
       TimeCalculator.getTimeBetween(pricingDate, LAST_KNOWN_FIXING_DATE);
   final double paymentTime = ACT_ACT.getDayCountFraction(pricingDate, PAYMENT_DATE);
   final double referenceStartTime =
       ACT_ACT.getDayCountFraction(pricingDate, REFERENCE_START_DATE);
   final double referenceEndTime = ACT_ACT.getDayCountFraction(pricingDate, REFERENCE_END_DATE);
   final double naturalPaymentStartPaymentTime =
       ACT_ACT.getDayCountFraction(pricingDate, ACCRUAL_START_DATE);
   final double naturalPaymentEndPaymentTime =
       ACT_ACT.getDayCountFraction(pricingDate, ACCRUAL_END_DATE);
   final CapFloorInflationYearOnYearMonthly zeroCoupon =
       new CapFloorInflationYearOnYearMonthly(
           CUR,
           paymentTime,
           1.0,
           NOTIONAL,
           PRICE_INDEX,
           lastKnownFixingTime,
           referenceStartTime,
           naturalPaymentStartPaymentTime,
           referenceEndTime,
           naturalPaymentEndPaymentTime,
           STRIKE,
           IS_CAP);
   assertEquals("Inflation zero-coupon: toDerivative", zeroCouponConverted, zeroCoupon);
 }
 @Test
 public void testStartAndEndSame2() {
   final ZonedDateTime date = DateUtils.getUTCDate(2000, 1, 1);
   final ZonedDateTime[] dates = CALCULATOR.getSchedule(date, date);
   assertEquals(dates.length, 1);
   assertEquals(dates[0], date);
 }
 @Test
 public void test2() {
   ZonedDateTime startDate = DateUtils.getUTCDate(2000, 1, 1);
   ZonedDateTime endDate = DateUtils.getUTCDate(2000, 12, 30);
   ZonedDateTime[] forward = CALCULATOR.getSchedule(startDate, endDate, false, true);
   assertEquals(forward.length, 1);
   assertEquals(forward[0], startDate);
   assertArrayEquals(forward, CALCULATOR.getSchedule(startDate, endDate, true, true));
   assertArrayEquals(forward, CALCULATOR.getSchedule(startDate, endDate, false, false));
   assertArrayEquals(forward, CALCULATOR.getSchedule(startDate, endDate, true, false));
   startDate = DateUtils.getUTCDate(2000, 1, 2);
   endDate = DateUtils.getUTCDate(2000, 12, 30);
   forward = CALCULATOR.getSchedule(startDate, endDate, false, true);
   assertEquals(forward.length, 0);
   assertArrayEquals(forward, CALCULATOR.getSchedule(startDate, endDate, true, true));
   assertArrayEquals(forward, CALCULATOR.getSchedule(startDate, endDate, false, false));
   assertArrayEquals(forward, CALCULATOR.getSchedule(startDate, endDate, true, false));
   startDate = DateUtils.getUTCDate(2002, 2, 2);
   endDate = DateUtils.getUTCDate(2003, 2, 9);
   forward = CALCULATOR.getSchedule(startDate, endDate, false, true);
   assertEquals(forward.length, 1);
   assertEquals(forward[0], DateUtils.getUTCDate(2003, 1, 1));
   assertArrayEquals(forward, CALCULATOR.getSchedule(startDate, endDate, true, true));
   assertArrayEquals(forward, CALCULATOR.getSchedule(startDate, endDate, false, false));
   assertArrayEquals(forward, CALCULATOR.getSchedule(startDate, endDate, true, false));
   startDate = DateUtils.getUTCDate(2000, 1, 1);
   endDate = DateUtils.getUTCDate(2010, 2, 9);
   final int months = 11;
   forward = CALCULATOR.getSchedule(startDate, endDate, false, true);
   assertEquals(forward.length, months);
   assertEquals(forward[0], startDate);
   assertArrayEquals(forward, CALCULATOR.getSchedule(startDate, endDate, true, true));
   assertArrayEquals(forward, CALCULATOR.getSchedule(startDate, endDate, false, false));
   assertArrayEquals(forward, CALCULATOR.getSchedule(startDate, endDate, true, false));
   final ZonedDateTime lastDate = DateUtils.getUTCDate(2010, 1, 1);
   assertEquals(forward[months - 1], lastDate);
   for (int i = 1; i < months; i++) {
     if (forward[i].getYear() == forward[i - 1].getYear()) {
       assertEquals(forward[i].getYear() - forward[i - 1].getYear(), 1);
       assertEquals(forward[i].getMonthOfYear().getValue(), 1);
       assertEquals(forward[i].getDayOfMonth(), 1);
     }
   }
   assertArrayEquals(forward, CALCULATOR.getSchedule(startDate, endDate, true, true));
   assertArrayEquals(forward, CALCULATOR.getSchedule(startDate, endDate, false, false));
   assertArrayEquals(forward, CALCULATOR.getSchedule(startDate, endDate, true, false));
 }
/** Test. */
@Test(groups = TestGroup.UNIT)
public class ForwardStartOptionModelTest {
  private static final ZonedDateTime DATE = DateUtils.getUTCDate(2010, 7, 1);
  private static final double R = 0.08;
  private static final YieldCurve CURVE = YieldCurve.from(ConstantDoublesCurve.from(R));
  private static final VolatilitySurface SURFACE =
      new VolatilitySurface(ConstantDoublesSurface.from(0.3));
  private static final double B = 0.04;
  private static final double SPOT = 60;
  private static final double PERCENT = 0.1;
  private static final ZonedDateTime START = DateUtils.getDateOffsetWithYearFraction(DATE, 0.25);
  private static final ZonedDateTime EXPIRY = DateUtils.getDateOffsetWithYearFraction(DATE, 1);
  private static final StandardOptionDataBundle DATA =
      new StandardOptionDataBundle(CURVE, B, SURFACE, SPOT, DATE);
  private static final ForwardStartOptionDefinition FORWARD =
      new ForwardStartOptionDefinition(
          new Expiry(EXPIRY), true, new Expiry(START), PERCENT, Moneyness.OTM);
  private static final ForwardStartOptionDefinition NOW =
      new ForwardStartOptionDefinition(
          new Expiry(EXPIRY), true, new Expiry(DATE), PERCENT, Moneyness.OTM);
  private static final ForwardStartOptionDefinition END =
      new ForwardStartOptionDefinition(
          new Expiry(EXPIRY), true, new Expiry(EXPIRY), PERCENT, Moneyness.OTM);
  private static final EuropeanVanillaOptionDefinition VANILLA =
      new EuropeanVanillaOptionDefinition(SPOT * (1 + PERCENT), new Expiry(EXPIRY), true);
  private static final AnalyticOptionModel<ForwardStartOptionDefinition, StandardOptionDataBundle>
      MODEL = new ForwardStartOptionModel();
  private static final AnalyticOptionModel<OptionDefinition, StandardOptionDataBundle> BSM =
      new BlackScholesMertonModel();

  @Test(expectedExceptions = IllegalArgumentException.class)
  public void testNullDefinition() {
    MODEL.getPricingFunction(null);
  }

  @Test(expectedExceptions = IllegalArgumentException.class)
  public void testNullData() {
    MODEL.getPricingFunction(FORWARD).evaluate((StandardOptionDataBundle) null);
  }

  @Test
  public void test() {
    assertEquals(MODEL.getPricingFunction(END).evaluate(DATA), 0, 0);
    assertEquals(
        MODEL
            .getPricingFunction(FORWARD)
            .evaluate(
                DATA.withVolatilitySurface(
                    new VolatilitySurface(ConstantDoublesSurface.from(1e-9)))),
        0,
        0);
    assertEquals(
        MODEL.getPricingFunction(NOW).evaluate(DATA),
        BSM.getPricingFunction(VANILLA).evaluate(DATA),
        1e-4);
    assertEquals(MODEL.getPricingFunction(FORWARD).evaluate(DATA), 4.4064, 1e-4);
  }
}
/** Test. */
@Test(groups = TestGroup.UNIT)
public class BlackOptionDataBundleTest {
  private static final double R = 0.05;
  private static final YieldAndDiscountCurve CURVE = YieldCurve.from(ConstantDoublesCurve.from(R));
  private static final VolatilitySurface SURFACE =
      new VolatilitySurface(ConstantDoublesSurface.from(0.35));
  private static final double F = 100;
  private static final ZonedDateTime DATE = DateUtils.getUTCDate(2010, 5, 1);
  private static final BlackOptionDataBundle DATA =
      new BlackOptionDataBundle(F, CURVE, SURFACE, DATE);

  @Test
  public void test() {
    assertEquals(DATA.getDate(), DATE);
    assertEquals(DATA.getForward(), F, 0);
    assertEquals(DATA.getVolatilitySurface(), SURFACE);
    assertEquals(DATA.getInterestRateCurve(), CURVE);
    final double t = Math.random();
    assertEquals(DATA.getDiscountFactor(t), Math.exp(-R * t), 0);
    BlackOptionDataBundle other = new BlackOptionDataBundle(F, CURVE, SURFACE, DATE);
    assertEquals(other, DATA);
    assertEquals(other.hashCode(), DATA.hashCode());
    other = new BlackOptionDataBundle(DATA);
    assertEquals(other, DATA);
    assertEquals(other.hashCode(), DATA.hashCode());
    other = new BlackOptionDataBundle(F + 1, CURVE, SURFACE, DATE);
    assertFalse(other.equals(DATA));
    other =
        new BlackOptionDataBundle(
            F, YieldCurve.from(ConstantDoublesCurve.from(0.06)), SURFACE, DATE);
    assertFalse(other.equals(DATA));
    other =
        new BlackOptionDataBundle(
            F, CURVE, new VolatilitySurface(ConstantDoublesSurface.from(0.6)), DATE);
    assertFalse(other.equals(DATA));
    other = new BlackOptionDataBundle(F, CURVE, SURFACE, DATE.plusDays(1));
    assertFalse(other.equals(DATA));
  }

  @Test
  public void testBuilders() {
    final ZonedDateTime newDate = DATE.plusDays(1);
    assertEquals(DATA.withDate(newDate), new BlackOptionDataBundle(F, CURVE, SURFACE, newDate));
    final double newForward = F + 1;
    assertEquals(
        DATA.withForward(newForward), new BlackOptionDataBundle(newForward, CURVE, SURFACE, DATE));
    final YieldCurve newCurve = YieldCurve.from(ConstantDoublesCurve.from(0.05));
    assertEquals(
        DATA.withInterestRateCurve(newCurve),
        new BlackOptionDataBundle(F, newCurve, SURFACE, DATE));
    final VolatilitySurface newSurface = new VolatilitySurface(ConstantDoublesSurface.from(0.9));
    assertEquals(
        DATA.withVolatilitySurface(newSurface),
        new BlackOptionDataBundle(F, CURVE, newSurface, DATE));
  }
}
 @Override
 public BondIborSecurity toDerivative(final ZonedDateTime date) {
   ArgumentChecker.notNull(date, "date");
   final ZonedDateTime spot =
       ScheduleCalculator.getAdjustedDate(date, getSettlementDays(), getCalendar());
   return toDerivative(
       date,
       ImmutableZonedDateTimeDoubleTimeSeries.of(DateUtils.getUTCDate(1800, 1, 1), 0.0),
       spot);
 }
 @Test
 public void toDerivativesStartMonthNotknown() {
   final ZonedDateTime pricingDate = DateUtils.getUTCDate(2011, 7, 29);
   final DoubleTimeSeries<ZonedDateTime> priceIndexTS =
       ImmutableZonedDateTimeDoubleTimeSeries.ofUTC(
           new ZonedDateTime[] {
             DateUtils.getUTCDate(2017, 5, 1),
             DateUtils.getUTCDate(2017, 6, 1),
             DateUtils.getUTCDate(2018, 5, 1),
             DateUtils.getUTCDate(2018, 6, 1)
           },
           new double[] {127.23, 127.43, 128.23, 128.43});
   final Coupon zeroCouponConverted = YoY_CAP_DEFINITION.toDerivative(pricingDate, priceIndexTS);
   // lastKnownFixingTime could be negatif so we don't use the dayfraction
   final double lastKnownFixingTime =
       TimeCalculator.getTimeBetween(pricingDate, LAST_KNOWN_FIXING_DATE);
   final double paymentTime = ACT_ACT.getDayCountFraction(pricingDate, PAYMENT_DATE);
   final double referenceStartTime =
       ACT_ACT.getDayCountFraction(pricingDate, REFERENCE_START_DATE);
   final double referenceEndTime = ACT_ACT.getDayCountFraction(pricingDate, REFERENCE_END_DATE);
   final double naturalPaymentStartPaymentTime =
       ACT_ACT.getDayCountFraction(pricingDate, ACCRUAL_START_DATE);
   final double naturalPaymentEndPaymentTime =
       ACT_ACT.getDayCountFraction(pricingDate, ACCRUAL_END_DATE);
   final CapFloorInflationYearOnYearMonthly zeroCoupon =
       new CapFloorInflationYearOnYearMonthly(
           CUR,
           paymentTime,
           1.0,
           NOTIONAL,
           PRICE_INDEX,
           lastKnownFixingTime,
           referenceStartTime,
           naturalPaymentStartPaymentTime,
           referenceEndTime,
           naturalPaymentEndPaymentTime,
           STRIKE,
           IS_CAP);
   assertEquals("Inflation zero-coupon: toDerivative", zeroCoupon, zeroCouponConverted);
 }
public class ProductOptionModelTest {
  private static final double S1 = 100;
  private static final double S2 = 105;
  private static final YieldAndDiscountCurve R = new YieldCurve(ConstantDoublesCurve.from(0.07));
  private static final double B1 = 0.02;
  private static final double B2 = 0.05;
  private static final ZonedDateTime DATE = DateUtils.getUTCDate(2010, 7, 1);
  private static final ProductOptionModel MODEL = new ProductOptionModel();
  private static final Expiry EXPIRY1 =
      new Expiry(DateUtils.getDateOffsetWithYearFraction(DATE, 0.1));
  private static final Expiry EXPIRY2 =
      new Expiry(DateUtils.getDateOffsetWithYearFraction(DATE, 0.5));
  private static final double EPS = 1e-4;

  @Test(expectedExceptions = IllegalArgumentException.class)
  public void testNullDefinition() {
    MODEL.getPricingFunction(null);
  }

  @Test(expectedExceptions = IllegalArgumentException.class)
  public void testNullData() {
    MODEL
        .getPricingFunction(new ProductOptionDefinition(0.1, EXPIRY1, true))
        .evaluate((StandardTwoAssetOptionDataBundle) null);
  }

  @Test
  public void test() {
    ProductOptionDefinition option = new ProductOptionDefinition(15000, EXPIRY1, true);
    StandardTwoAssetOptionDataBundle data =
        new StandardTwoAssetOptionDataBundle(
            R,
            B1,
            B2,
            new VolatilitySurface(ConstantDoublesSurface.from(0.2)),
            new VolatilitySurface(ConstantDoublesSurface.from(0.3)),
            S1,
            S2,
            -0.5,
            DATE);
    assertEquals(MODEL.getPricingFunction(option).evaluate(data), 0.0028, EPS);
    data =
        data.withFirstVolatilitySurface(new VolatilitySurface(ConstantDoublesSurface.from(0.3)))
            .withCorrelation(0);
    assertEquals(MODEL.getPricingFunction(option).evaluate(data), 2.4026, EPS);
    option = new ProductOptionDefinition(15000, EXPIRY2, true);
    assertEquals(MODEL.getPricingFunction(option).evaluate(data), 266.1594, EPS);
  }
}
public class FXVannaVolgaVolatilityCurveDataBundleTest {
  private static final double DELTA = 0.1;
  private static final double RR = 0.01;
  private static final double ATM = 0.2;
  private static final double VWB = 0.05;
  private static final ZonedDateTime DATE = DateUtils.getUTCDate(2010, 7, 1);
  private static final FXVannaVolgaVolatilityCurveDataBundle DATA =
      new FXVannaVolgaVolatilityCurveDataBundle(DELTA, RR, ATM, VWB, DATE);

  @Test(expectedExceptions = IllegalArgumentException.class)
  public void testNullMaturity() {
    new FXVannaVolgaVolatilityCurveDataBundle(DELTA, RR, ATM, VWB, null);
  }

  @Test(expectedExceptions = IllegalArgumentException.class)
  public void testNegativeATMVol() {
    new FXVannaVolgaVolatilityCurveDataBundle(DELTA, RR, -ATM, VWB, DATE);
  }

  @Test
  public void testGetters() {
    assertEquals(ATM, DATA.getAtTheMoney(), 0);
    assertEquals(DELTA, DATA.getDelta(), 0);
    assertEquals(DATE, DATA.getMaturity());
    assertEquals(RR, DATA.getRiskReversal(), 0);
    assertEquals(VWB, DATA.getVegaWeightedButterfly(), 0);
  }

  @Test
  public void testEqualsAndHashCode() {
    FXVannaVolgaVolatilityCurveDataBundle other =
        new FXVannaVolgaVolatilityCurveDataBundle(DELTA, RR, ATM, VWB, DATE);
    assertEquals(DATA, other);
    assertEquals(DATA.hashCode(), other.hashCode());
    other = new FXVannaVolgaVolatilityCurveDataBundle(-DELTA, RR, ATM, VWB, DATE);
    assertFalse(other.equals(DATA));
    other = new FXVannaVolgaVolatilityCurveDataBundle(DELTA, -RR, ATM, VWB, DATE);
    assertFalse(other.equals(DATA));
    other = new FXVannaVolgaVolatilityCurveDataBundle(DELTA, RR, ATM + 1, VWB, DATE);
    assertFalse(other.equals(DATA));
    other = new FXVannaVolgaVolatilityCurveDataBundle(DELTA, RR, ATM, -VWB, DATE);
    assertFalse(other.equals(DATA));
    other =
        new FXVannaVolgaVolatilityCurveDataBundle(
            DELTA, RR, ATM, VWB, DateUtils.getDateOffsetWithYearFraction(DATE, 1));
    assertFalse(other.equals(DATA));
  }
}
 @Test
 public void test() {
   GapOptionDefinition other = new GapOptionDefinition(STRIKE, EXPIRY, true, PAYOFF_STRIKE);
   assertEquals(other, CALL);
   assertEquals(other.hashCode(), CALL.hashCode());
   other = new GapOptionDefinition(STRIKE + 1, EXPIRY, true, PAYOFF_STRIKE);
   assertFalse(other.equals(CALL));
   other =
       new GapOptionDefinition(
           STRIKE, new Expiry(DateUtils.getUTCDate(2010, 3, 1)), true, PAYOFF_STRIKE);
   assertFalse(other.equals(CALL));
   other = new GapOptionDefinition(STRIKE, EXPIRY, false, PAYOFF_STRIKE);
   assertFalse(other.equals(CALL));
   other = new GapOptionDefinition(STRIKE, EXPIRY, true, PAYOFF_STRIKE + 1);
   assertFalse(other.equals(CALL));
 }
 @Test
 /** Tests the toDerivative method. */
 public void toDerivativeFixingLast() {
   final ZonedDateTime referenceDate = DateUtils.getUTCDate(2011, 9, 16);
   final double fixingRate = 0.01;
   final DoubleTimeSeries<ZonedDateTime> fixingTS =
       ImmutableZonedDateTimeDoubleTimeSeries.ofUTC(
           new ZonedDateTime[] {
             DateUtils.getUTCDate(2011, 9, 7),
             DateUtils.getUTCDate(2011, 9, 8),
             DateUtils.getUTCDate(2011, 9, 9),
             DateUtils.getUTCDate(2011, 9, 12),
             DateUtils.getUTCDate(2011, 9, 13),
             DateUtils.getUTCDate(2011, 9, 14),
             DateUtils.getUTCDate(2011, 9, 15)
           },
           new double[] {
             fixingRate, fixingRate, fixingRate, fixingRate, fixingRate, fixingRate, fixingRate
           });
   final Payment cpnConverted =
       ON_COMPOUNDED_COUPON_DEFINITION.toDerivative(referenceDate, fixingTS);
   final double paymentTime =
       EUR_DAY_COUNT.getDayCountFraction(referenceDate, EUR_PAYMENT_DATE, EUR_CALENDAR);
   final double notionalAccrued =
       NOTIONAL
           * Math.pow(
               1 + fixingRate, ON_COMPOUNDED_COUPON_DEFINITION.getFixingPeriodAccrualFactors()[0])
           * Math.pow(
               1 + fixingRate, ON_COMPOUNDED_COUPON_DEFINITION.getFixingPeriodAccrualFactors()[1])
           * Math.pow(
               1 + fixingRate, ON_COMPOUNDED_COUPON_DEFINITION.getFixingPeriodAccrualFactors()[2])
           * Math.pow(
               1 + fixingRate, ON_COMPOUNDED_COUPON_DEFINITION.getFixingPeriodAccrualFactors()[3])
           * Math.pow(
               1 + fixingRate, ON_COMPOUNDED_COUPON_DEFINITION.getFixingPeriodAccrualFactors()[4]);
   final CouponFixed cpnExpected =
       new CouponFixed(
           EUR_CUR,
           paymentTime,
           EUR_PAYMENT_YEAR_FRACTION,
           NOTIONAL,
           (notionalAccrued / NOTIONAL - 1.0) / EUR_PAYMENT_YEAR_FRACTION);
   assertEquals("CouponONCompounded definition: toDerivative", cpnExpected, cpnConverted);
 }
/** Test. */
@Test(groups = TestGroup.UNIT)
public class LogOptionModelTest {
  private static final AnalyticOptionModel<LogOptionDefinition, StandardOptionDataBundle> MODEL =
      new LogOptionModel();
  private static final Set<Greek> REQUIRED_GREEKS = Collections.singleton(Greek.FAIR_PRICE);
  private static final ZonedDateTime DATE = DateUtils.getUTCDate(2009, 1, 1);
  private static final Expiry EXPIRY =
      new Expiry(DateUtils.getDateOffsetWithYearFraction(DATE, 0.75));
  private static final YieldAndDiscountCurve CURVE =
      YieldCurve.from(ConstantDoublesCurve.from(0.08));
  private static final double B = 0.04;
  private static final double SPOT = 100;
  private static final double EPS = 1e-4;

  @Test
  public void test() {
    LogOptionDefinition definition = getDefinition(70);
    assertPriceEquals(definition, 0.2, 0.3510);
    assertPriceEquals(definition, 0.3, 0.3422);
    assertPriceEquals(definition, 0.4, 0.3379);
    assertPriceEquals(definition, 0.5, 0.3365);
    assertPriceEquals(definition, 0.6, 0.3362);
    definition = getDefinition(130);
    assertPriceEquals(definition, 0.2, 0.0056);
    assertPriceEquals(definition, 0.3, 0.0195);
    assertPriceEquals(definition, 0.4, 0.0363);
    assertPriceEquals(definition, 0.5, 0.0532);
    assertPriceEquals(definition, 0.6, 0.0691);
  }

  private void assertPriceEquals(
      final LogOptionDefinition definition, final double sigma, final double price) {
    final StandardOptionDataBundle bundle = getBundle(sigma);
    final GreekResultCollection actual = MODEL.getGreeks(definition, bundle, REQUIRED_GREEKS);
    assertEquals(actual.get(Greek.FAIR_PRICE), price, EPS);
  }

  private StandardOptionDataBundle getBundle(final double sigma) {
    return new StandardOptionDataBundle(
        CURVE, B, new VolatilitySurface(ConstantDoublesSurface.from(sigma)), SPOT, DATE);
  }

  private LogOptionDefinition getDefinition(final double strike) {
    return new LogOptionDefinition(strike, EXPIRY);
  }
}
public class RelativeOutperformanceOptionModelTest {
  private static final double S1 = 130;
  private static final double S2 = 100;
  private static final YieldAndDiscountCurve R = YieldCurve.from(ConstantDoublesCurve.from(0.07));
  private static final double B1 = 0.05;
  private static final double B2 = 0.03;
  private static final VolatilitySurface SIGMA1 =
      new VolatilitySurface(ConstantDoublesSurface.from(0.3));
  private static final VolatilitySurface SIGMA2 =
      new VolatilitySurface(ConstantDoublesSurface.from(0.4));
  private static final ZonedDateTime DATE = DateUtils.getUTCDate(2010, 7, 1);
  private static final RelativeOutperformanceOptionModel MODEL =
      new RelativeOutperformanceOptionModel();
  private static final Expiry EXPIRY =
      new Expiry(DateUtils.getDateOffsetWithYearFraction(DATE, 0.25));
  private static final double EPS = 1e-4;

  @Test(expectedExceptions = IllegalArgumentException.class)
  public void testNullDefinition() {
    MODEL.getPricingFunction(null);
  }

  @Test(expectedExceptions = IllegalArgumentException.class)
  public void testNullData() {
    MODEL
        .getPricingFunction(new RelativeOutperformanceOptionDefinition(0.1, EXPIRY, true))
        .evaluate((StandardTwoAssetOptionDataBundle) null);
  }

  @Test
  public void test() {
    RelativeOutperformanceOptionDefinition option =
        new RelativeOutperformanceOptionDefinition(0.1, EXPIRY, true);
    StandardTwoAssetOptionDataBundle data =
        new StandardTwoAssetOptionDataBundle(R, B1, B2, SIGMA1, SIGMA2, S1, S2, -0.5, DATE);
    assertEquals(MODEL.getPricingFunction(option).evaluate(data), 1.2582, EPS);
    option = new RelativeOutperformanceOptionDefinition(0.5, EXPIRY, true);
    data = data.withCorrelation(0);
    assertEquals(MODEL.getPricingFunction(option).evaluate(data), 0.8449, EPS);
    option = new RelativeOutperformanceOptionDefinition(1, EXPIRY, true);
    data = data.withCorrelation(0.5);
    assertEquals(MODEL.getPricingFunction(option).evaluate(data), 0.3382, EPS);
  }
}
Пример #20
0
 static {
   final int n = NO_STUB1.length;
   SHORT_START_STUB1 = Arrays.copyOf(NO_STUB1, n);
   LONG_START_STUB1 = Arrays.copyOf(NO_STUB1, n);
   SHORT_END_STUB1 = Arrays.copyOf(NO_STUB1, n);
   LONG_END_STUB1 = Arrays.copyOf(NO_STUB1, n);
   SHORT_START_STUB3 = Arrays.copyOf(NO_STUB3, n);
   LONG_START_STUB3 = Arrays.copyOf(NO_STUB3, n);
   SHORT_END_STUB3 = Arrays.copyOf(NO_STUB3, n);
   LONG_END_STUB3 = Arrays.copyOf(NO_STUB3, n);
   SHORT_START_STUB1[0] = DateUtils.getUTCDate(2008, 1, 30);
   LONG_START_STUB1[0] = DateUtils.getUTCDate(2007, 12, 1);
   SHORT_END_STUB1[n - 1] = DateUtils.getUTCDate(2011, 9, 4);
   LONG_END_STUB1[n - 1] = DateUtils.getUTCDate(2011, 11, 3);
   SHORT_START_STUB3[0] = DateUtils.getUTCDate(2008, 2, 27);
   LONG_START_STUB3[0] = DateUtils.getUTCDate(2008, 1, 27);
   SHORT_END_STUB3[n - 1] = DateUtils.getUTCDate(2011, 9, 4);
   LONG_END_STUB3[n - 1] = DateUtils.getUTCDate(2011, 11, 4);
   NO_STUB2 = new LocalDate[n];
   SHORT_START_STUB2 = new LocalDate[n];
   LONG_START_STUB2 = new LocalDate[n];
   SHORT_END_STUB2 = new LocalDate[n];
   LONG_END_STUB2 = new LocalDate[n];
   NO_STUB4 = new LocalDate[n];
   SHORT_START_STUB4 = new LocalDate[n];
   LONG_START_STUB4 = new LocalDate[n];
   SHORT_END_STUB4 = new LocalDate[n];
   LONG_END_STUB4 = new LocalDate[n];
   for (int i = 0; i < n; i++) {
     NO_STUB2[i] = NO_STUB1[i].toLocalDate();
     SHORT_START_STUB4[i] = SHORT_START_STUB3[i].toLocalDate();
     LONG_START_STUB4[i] = LONG_START_STUB3[i].toLocalDate();
     SHORT_END_STUB4[i] = SHORT_END_STUB3[i].toLocalDate();
     LONG_END_STUB4[i] = LONG_END_STUB3[i].toLocalDate();
     NO_STUB4[i] = NO_STUB3[i].toLocalDate();
     SHORT_START_STUB2[i] = SHORT_START_STUB1[i].toLocalDate();
     LONG_START_STUB2[i] = LONG_START_STUB1[i].toLocalDate();
     SHORT_END_STUB2[i] = SHORT_END_STUB1[i].toLocalDate();
     LONG_END_STUB2[i] = LONG_END_STUB1[i].toLocalDate();
   }
 }
 @Test(expectedExceptions = IllegalArgumentException.class)
 /** Tests the toDerivative method: after payment date */
 public void toDerivativeAfterPayment() {
   final ZonedDateTime referenceDate = DateUtils.getUTCDate(2011, 9, 20);
   final double fixingRate = 0.01;
   final DoubleTimeSeries<ZonedDateTime> fixingTS =
       ImmutableZonedDateTimeDoubleTimeSeries.ofUTC(
           new ZonedDateTime[] {
             DateUtils.getUTCDate(2011, 9, 7),
             DateUtils.getUTCDate(2011, 9, 8),
             DateUtils.getUTCDate(2011, 9, 9),
             DateUtils.getUTCDate(2011, 9, 12),
             DateUtils.getUTCDate(2011, 9, 13),
             DateUtils.getUTCDate(2011, 9, 14),
             DateUtils.getUTCDate(2011, 9, 15)
           },
           new double[] {
             fixingRate, fixingRate, fixingRate, fixingRate, fixingRate, fixingRate, fixingRate
           });
   ON_COMPOUNDED_COUPON_DEFINITION.toDerivative(referenceDate, fixingTS);
 }
 @Test
 /** Tests toDerivative. */
 public void toDerivativeBetweenSettleMaturity() {
   final ZonedDateTime referenceDate = DateUtils.getUTCDate(2011, 12, 20);
   final DepositZero converted = DEPOSIT_DEFINITION.toDerivative(referenceDate);
   final double startTime = 0;
   final double endTime = TimeCalculator.getTimeBetween(referenceDate, END_DATE);
   final DepositZero expected =
       new DepositZero(
           EUR,
           startTime,
           endTime,
           0.0,
           NOTIONAL,
           DEPOSIT_AF,
           RATE,
           DEPOSIT_DEFINITION.getInterestAmount());
   assertEquals("DepositZeroDefinition: toDerivative", expected, converted);
 }
 @SuppressWarnings("deprecation")
 @Test
 /** Tests toDerivative. */
 public void toDerivativeBetweenTradeAndSettleDeprecated() {
   final ZonedDateTime referenceDate = DateUtils.getUTCDate(2011, 12, 13);
   final DepositZero converted = DEPOSIT_DEFINITION.toDerivative(referenceDate, CURVE_NAME);
   final double startTime = TimeCalculator.getTimeBetween(referenceDate, SPOT_DATE);
   final double endTime = TimeCalculator.getTimeBetween(referenceDate, END_DATE);
   final DepositZero expected =
       new DepositZero(
           EUR,
           startTime,
           endTime,
           NOTIONAL,
           NOTIONAL,
           DEPOSIT_AF,
           RATE,
           DEPOSIT_DEFINITION.getInterestAmount(),
           CURVE_NAME);
   assertEquals("DepositZeroDefinition: toDerivative", expected, converted);
 }
 @Test
 public void toDerivativesNoData() {
   final ZonedDateTime pricingDate = DateUtils.getUTCDate(2011, 7, 29);
   Coupon yearOnYearCouponConverted = YoY_COUPON_DEFINITION.toDerivative(pricingDate, CURVE_NAMES);
   double paymentTime = ACT_ACT.getDayCountFraction(pricingDate, PAYMENT_DATE);
   final double referenceStartTime0 =
       ACT_ACT.getDayCountFraction(pricingDate, REFERENCE_START_DATE[0]);
   final double referenceEndTime0 =
       ACT_ACT.getDayCountFraction(pricingDate, REFERENCE_END_DATE[0]);
   final double referenceStartTime1 =
       ACT_ACT.getDayCountFraction(pricingDate, REFERENCE_START_DATE[1]);
   final double referenceEndTime1 =
       ACT_ACT.getDayCountFraction(pricingDate, REFERENCE_END_DATE[1]);
   final double naturalPaymentStartPaymentTime =
       ACT_ACT.getDayCountFraction(pricingDate, ACCRUAL_START_DATE);
   final double naturalPaymentEndPaymentTime =
       ACT_ACT.getDayCountFraction(pricingDate, ACCRUAL_END_DATE);
   final double[] referenceStartTime = new double[2];
   final double[] referenceEndTime = new double[2];
   referenceStartTime[0] = referenceStartTime0;
   referenceStartTime[1] = referenceStartTime1;
   referenceEndTime[0] = referenceEndTime0;
   referenceEndTime[1] = referenceEndTime1;
   CouponInflationYearOnYearInterpolation yearOnYearCoupon =
       new CouponInflationYearOnYearInterpolation(
           CUR,
           paymentTime,
           1.0,
           NOTIONAL,
           PRICE_INDEX,
           referenceStartTime,
           naturalPaymentStartPaymentTime,
           referenceEndTime,
           naturalPaymentEndPaymentTime,
           false,
           WEIGHT_START,
           WEIGHT_END);
   assertEquals(
       "Inflation year on year coupon: toDerivative", yearOnYearCouponConverted, yearOnYearCoupon);
 }
 @Test
 public void priceAfterFixing() {
   final ZonedDateTime referenceDate = DateUtils.getUTCDate(2012, 3, 7);
   final ZonedDateTime[] dateFixing =
       new ZonedDateTime[] {
         DateUtils.getUTCDate(2012, 3, 1),
         DateUtils.getUTCDate(2012, 3, 2),
         DateUtils.getUTCDate(2012, 3, 5),
         DateUtils.getUTCDate(2012, 3, 6),
         DateUtils.getUTCDate(2012, 3, 7)
       };
   final double[] rateFixing = new double[] {0.0010, 0.0011, 0.0012, 0.0013, 0.0014};
   final DoubleTimeSeries<ZonedDateTime> fixingTS =
       ImmutableZonedDateTimeDoubleTimeSeries.ofUTC(dateFixing, rateFixing);
   final FederalFundsFutureSecurity futureSecurity =
       FUTURE_SECURITY_DEFINITION.toDerivative(referenceDate, fixingTS, CURVE_NAMES);
   double interest = futureSecurity.getAccruedInterest();
   final YieldAndDiscountCurve oisCurve = CURVES.getCurve(CURVE_NAMES[0]);
   final double[] ratePeriod = new double[futureSecurity.getFixingPeriodAccrualFactor().length];
   for (int loopfix = 0;
       loopfix < futureSecurity.getFixingPeriodAccrualFactor().length;
       loopfix++) {
     ratePeriod[loopfix] =
         (oisCurve.getDiscountFactor(futureSecurity.getFixingPeriodTime()[loopfix])
                     / oisCurve.getDiscountFactor(
                         futureSecurity.getFixingPeriodTime()[loopfix + 1])
                 - 1.0)
             / futureSecurity.getFixingPeriodAccrualFactor()[loopfix];
     interest +=
         (oisCurve.getDiscountFactor(futureSecurity.getFixingPeriodTime()[loopfix])
                 / oisCurve.getDiscountFactor(futureSecurity.getFixingPeriodTime()[loopfix + 1])
             - 1.0);
   }
   final double rate = interest / FUTURE_SECURITY_DEFINITION.getFixingTotalAccrualFactor();
   final double priceExpected = 1.0 - rate;
   final double priceComputed = METHOD_SECURITY.price(futureSecurity, CURVES);
   assertEquals(
       "Federal Funds Future Security: price", priceExpected, priceComputed, TOLERANCE_PRICE);
 }
public class FloatingStrikeLookbackOptionDefinitionTest {
  private static final ZonedDateTime DATE = DateUtils.getUTCDate(2010, 6, 1);
  private static final Expiry EXPIRY = new Expiry(DATE);
  private static final FloatingStrikeLookbackOptionDefinition CALL =
      new FloatingStrikeLookbackOptionDefinition(EXPIRY, true);
  private static final FloatingStrikeLookbackOptionDefinition PUT =
      new FloatingStrikeLookbackOptionDefinition(EXPIRY, false);
  private static final double SPOT = 100;
  private static final double DIFF = 10;
  private static final DoubleTimeSeries<?> HIGH_TS =
      new FastArrayIntDoubleTimeSeries(
          DateTimeNumericEncoding.DATE_DDMMYYYY,
          new int[] {20100529, 20100530, 20100531},
          new double[] {SPOT, SPOT + DIFF, SPOT});
  private static final DoubleTimeSeries<?> LOW_TS =
      new FastArrayIntDoubleTimeSeries(
          DateTimeNumericEncoding.DATE_DDMMYYYY,
          new int[] {20100529, 20100530, 20100531},
          new double[] {SPOT, SPOT - DIFF, SPOT});
  private static final StandardOptionWithSpotTimeSeriesDataBundle HIGH_DATA =
      new StandardOptionWithSpotTimeSeriesDataBundle(
          new YieldCurve(ConstantDoublesCurve.from(0.1)),
          0.05,
          new VolatilitySurface(ConstantDoublesSurface.from(0.2)),
          SPOT,
          DateUtils.getUTCDate(2010, 6, 1),
          HIGH_TS);
  private static final StandardOptionWithSpotTimeSeriesDataBundle LOW_DATA =
      new StandardOptionWithSpotTimeSeriesDataBundle(
          new YieldCurve(ConstantDoublesCurve.from(0.1)),
          0.05,
          new VolatilitySurface(ConstantDoublesSurface.from(0.2)),
          SPOT,
          DateUtils.getUTCDate(2010, 6, 1),
          LOW_TS);

  @Test(expectedExceptions = IllegalArgumentException.class)
  public void testNullDataBundle() {
    CALL.getPayoffFunction().getPayoff(null, null);
  }

  @Test(expectedExceptions = IllegalArgumentException.class)
  public void testNullTS() {
    CALL.getPayoffFunction().getPayoff(HIGH_DATA.withSpotTimeSeries(null), null);
  }

  @Test
  public void testExercise() {
    assertFalse(CALL.getExerciseFunction().shouldExercise(HIGH_DATA, null));
    assertFalse(CALL.getExerciseFunction().shouldExercise(LOW_DATA, null));
    assertFalse(PUT.getExerciseFunction().shouldExercise(HIGH_DATA, null));
    assertFalse(PUT.getExerciseFunction().shouldExercise(LOW_DATA, null));
  }

  @Test
  public void testPayoff() {
    final double eps = 1e-15;
    OptionPayoffFunction<StandardOptionWithSpotTimeSeriesDataBundle> payoff =
        CALL.getPayoffFunction();
    assertEquals(payoff.getPayoff(LOW_DATA, 0.), DIFF, eps);
    assertEquals(payoff.getPayoff(HIGH_DATA, 0.), 0, eps);
    payoff = PUT.getPayoffFunction();
    assertEquals(payoff.getPayoff(LOW_DATA, 0.), 0, eps);
    assertEquals(payoff.getPayoff(HIGH_DATA, 0.), DIFF, eps);
  }

  @Test
  public void testEqualsAndHashCode() {
    final OptionDefinition call1 = new FloatingStrikeLookbackOptionDefinition(EXPIRY, true);
    final OptionDefinition put1 = new FloatingStrikeLookbackOptionDefinition(EXPIRY, false);
    final OptionDefinition call2 =
        new FloatingStrikeLookbackOptionDefinition(
            new Expiry(DateUtils.getDateOffsetWithYearFraction(DATE, 3)), true);
    final OptionDefinition put2 =
        new FloatingStrikeLookbackOptionDefinition(
            new Expiry(DateUtils.getDateOffsetWithYearFraction(DATE, 3)), false);
    assertFalse(CALL.equals(PUT));
    assertEquals(call1, CALL);
    assertEquals(put1, PUT);
    assertEquals(call1.hashCode(), CALL.hashCode());
    assertEquals(put1.hashCode(), PUT.hashCode());
    assertFalse(call2.equals(CALL));
    assertFalse(put2.equals(PUT));
  }
}
public class AsymmetricPowerOptionModelTest {
  private static final double B = 0.02;
  private static final double SPOT = 10;
  private static final double STRIKE = 100;
  private static final ZonedDateTime DATE = DateUtils.getUTCDate(2009, 1, 1);
  private static final Expiry EXPIRY =
      new Expiry(DateUtils.getDateOffsetWithYearFraction(DATE, 0.5));
  private static final YieldAndDiscountCurve CURVE =
      new YieldCurve(ConstantDoublesCurve.from(0.08));
  private static final VolatilitySurface SURFACE =
      new VolatilitySurface(ConstantDoublesSurface.from(0.1));
  private static final StandardOptionDataBundle BUNDLE =
      new StandardOptionDataBundle(CURVE, B, SURFACE, SPOT, DATE);
  private static final AnalyticOptionModel<
          AsymmetricPowerOptionDefinition, StandardOptionDataBundle>
      MODEL = new AsymmetricPowerOptionModel();
  private static final AnalyticOptionModel<OptionDefinition, StandardOptionDataBundle> BS_MODEL =
      new BlackScholesMertonModel();
  private static final Set<Greek> REQUIRED_GREEKS = Collections.singleton(Greek.FAIR_PRICE);
  private static final double EPS = 1e-4;

  @Test(expectedExceptions = IllegalArgumentException.class)
  public void testNullDefinition() {
    MODEL.getPricingFunction(null);
  }

  @Test(expectedExceptions = IllegalArgumentException.class)
  public void testNullData() {
    MODEL
        .getPricingFunction(new AsymmetricPowerOptionDefinition(STRIKE, EXPIRY, 1, true))
        .evaluate((StandardOptionDataBundle) null);
  }

  @Test
  public void test() {
    assertEquals(getPrice(1.9, true), 0.3102, EPS);
    assertEquals(getPrice(1.95, true), 1.9320, EPS);
    assertEquals(getPrice(2., true), 6.7862, EPS);
    assertEquals(getPrice(2.05, true), 15.8587, EPS);
    assertEquals(getPrice(2.1, true), 28.4341, EPS);
    assertEquals(getPrice(1.9, false), 18.2738, EPS);
    assertEquals(getPrice(1.95, false), 10.2890, EPS);
    assertEquals(getPrice(2., false), 4.3539, EPS);
    assertEquals(getPrice(2.05, false), 1.3089, EPS);
    assertEquals(getPrice(2.1, false), 0.2745, EPS);

    for (int i = 0; i < 5; i++) {
      final double power = 1.9 + 0.05 * i;
      assertEquals(getPrice(power, true), getBSPrice(power, true), EPS);
      assertEquals(getPrice(power, false), getBSPrice(power, false), EPS);
    }
  }

  private double getPrice(final double power, final boolean isCall) {
    return MODEL
        .getGreeks(getDefinition(power, isCall), BUNDLE, REQUIRED_GREEKS)
        .get(Greek.FAIR_PRICE);
  }

  private double getBSPrice(final double power, final boolean isCall) {
    final StandardOptionDataBundle bsBundle = getModifiedDataBundle(BUNDLE, power);
    return BS_MODEL
        .getGreeks(getDefinition(power, isCall), bsBundle, REQUIRED_GREEKS)
        .get(Greek.FAIR_PRICE);
  }

  private AsymmetricPowerOptionDefinition getDefinition(final double power, final boolean isCall) {
    return new AsymmetricPowerOptionDefinition(STRIKE, EXPIRY, power, isCall);
  }

  private StandardOptionDataBundle getModifiedDataBundle(
      final StandardOptionDataBundle data, final double p) {
    final double t = DateUtils.getDifferenceInYears(DATE, EXPIRY);
    final double spot = Math.pow(data.getSpot(), p);
    double sigma = data.getVolatility(t, STRIKE);
    final double b = p * (data.getCostOfCarry() + (p - 1) * sigma * sigma * 0.5);
    sigma *= p;
    return new StandardOptionDataBundle(
        CURVE, b, new VolatilitySurface(ConstantDoublesSurface.from(sigma)), spot, DATE);
  }
}
/**
 * Tests related to the pricing of CMS coupons with Hull-White (extended Vasicek) model and
 * different numerical methods.
 */
public class CouponCMSHullWhiteMethodsTest {

  private static final Calendar TARGET = new MondayToFridayCalendar("TARGET");
  private static final GeneratorSwapFixedIborMaster GENERATOR_SWAP_MASTER =
      GeneratorSwapFixedIborMaster.getInstance();
  private static final GeneratorSwapFixedIbor GENERATOR_EUR1YEURIBOR6M =
      GENERATOR_SWAP_MASTER.getGenerator("EUR1YEURIBOR6M", TARGET);
  private static final Period TENOR_SWAP = Period.ofYears(10);
  private static final IndexSwap SWAP_EUR10Y = new IndexSwap(GENERATOR_EUR1YEURIBOR6M, TENOR_SWAP);

  private static final ZonedDateTime REFERENCE_DATE = DateUtils.getUTCDate(2012, 1, 17);

  // Coupon CMS: 6m fixing in advance (payment in arrears); ACT/360
  private static final Period TENOR_COUPON = Period.ofMonths(6);
  private static final Period TENOR_FIXING = Period.ofMonths(60);
  private static final DayCount ACT360 = DayCountFactory.INSTANCE.getDayCount("Actual/360");
  private static final ZonedDateTime FIXING_DATE =
      ScheduleCalculator.getAdjustedDate(
          REFERENCE_DATE,
          TENOR_FIXING,
          GENERATOR_EUR1YEURIBOR6M.getBusinessDayConvention(),
          TARGET,
          GENERATOR_EUR1YEURIBOR6M.isEndOfMonth());
  private static final ZonedDateTime START_DATE =
      ScheduleCalculator.getAdjustedDate(
          FIXING_DATE, GENERATOR_EUR1YEURIBOR6M.getSpotLag(), TARGET);
  private static final ZonedDateTime PAYMENT_DATE =
      ScheduleCalculator.getAdjustedDate(
          START_DATE,
          TENOR_COUPON,
          GENERATOR_EUR1YEURIBOR6M.getBusinessDayConvention(),
          TARGET,
          GENERATOR_EUR1YEURIBOR6M.isEndOfMonth());
  private static final double NOTIONAL = 100000000; // 100m
  private static final double ACCRUAL_FACTOR = ACT360.getDayCountFraction(START_DATE, PAYMENT_DATE);
  private static final CouponCMSDefinition CPN_CMS_DEFINITION =
      CouponCMSDefinition.from(
          PAYMENT_DATE, START_DATE, PAYMENT_DATE, ACCRUAL_FACTOR, NOTIONAL, SWAP_EUR10Y);

  private static final YieldCurveBundle CURVES = TestsDataSetsSABR.createCurves2();
  private static final String[] CURVE_NAMES = TestsDataSetsSABR.curves2Names();
  private static final HullWhiteOneFactorPiecewiseConstantParameters PARAMETERS_HW =
      TestsDataSetHullWhite.createHullWhiteParameters();
  private static final HullWhiteOneFactorPiecewiseConstantDataBundle BUNDLE_HW =
      new HullWhiteOneFactorPiecewiseConstantDataBundle(PARAMETERS_HW, CURVES);

  private static final CouponCMS CPN_CMS =
      (CouponCMS)
          CPN_CMS_DEFINITION.toDerivative(
              REFERENCE_DATE, new String[] {CURVE_NAMES[0], CURVE_NAMES[2]});

  private static final CouponCMSHullWhiteNumericalIntegrationMethod METHOD_NI =
      CouponCMSHullWhiteNumericalIntegrationMethod.getInstance();
  private static final CouponCMSHullWhiteApproximationMethod METHOD_APP =
      CouponCMSHullWhiteApproximationMethod.getInstance();
  private static final CouponCMSDiscountingMethod METHOD_DSC =
      CouponCMSDiscountingMethod.getInstance();
  private static final double TOLERANCE_PRICE = 1.0E-2;
  private static final double TOLERANCE_PRICE_APP = 5.0E+0;

  @Test
  public void presentValueNumericalIntegration() {
    CurrencyAmount pvNumericalIntegration = METHOD_NI.presentValue(CPN_CMS, BUNDLE_HW);
    double pvPrevious = 1124760.482; // From previous run
    assertEquals(
        "Coupon CMS - Hull-White - present value - numerical integration",
        pvPrevious,
        pvNumericalIntegration.getAmount(),
        TOLERANCE_PRICE);
    // Comparison with non-adjusted figures: to have the right order of magnitude
    CurrencyAmount pvDiscounting = METHOD_DSC.presentValue(CPN_CMS, BUNDLE_HW);
    assertEquals(
        "Coupon CMS - Hull-White - present value - numerical integration",
        1.0,
        pvDiscounting.getAmount() / pvNumericalIntegration.getAmount(),
        0.20);
  }

  @Test
  public void presentValueApproximation() {
    CurrencyAmount pvNumericalIntegration = METHOD_NI.presentValue(CPN_CMS, BUNDLE_HW);
    CurrencyAmount pvApproximation = METHOD_APP.presentValue(CPN_CMS, BUNDLE_HW);
    assertEquals(
        "Coupon CMS - Hull-White - present value - approximation",
        pvApproximation.getAmount(),
        pvNumericalIntegration.getAmount(),
        TOLERANCE_PRICE_APP);
  }
}
public class FederalFundsFutureSecurityDiscountingMethodTest {

  private static final ZonedDateTime REFERENCE_DATE = DateUtils.getUTCDate(2012, 1, 30);

  private static final Calendar NYC = new MondayToFridayCalendar("NYC");
  private static final IndexON INDEX_FEDFUND = IndexONMaster.getInstance().getIndex("FED FUND");
  private static final ZonedDateTime MARCH_1 = DateUtils.getUTCDate(2012, 3, 1);

  private static final FederalFundsFutureSecurityDefinition FUTURE_SECURITY_DEFINITION =
      FederalFundsFutureSecurityDefinition.fromFedFund(MARCH_1, INDEX_FEDFUND, NYC);

  private static final YieldCurveBundle CURVES = TestsDataSetsSABR.createCurves2();
  private static final String[] CURVE_NAMES = TestsDataSetsSABR.curves2Names();

  private static final FederalFundsFutureSecurity FUTURE_SECURITY =
      FUTURE_SECURITY_DEFINITION.toDerivative(REFERENCE_DATE, CURVE_NAMES);

  private static final FederalFundsFutureSecurityDiscountingMethod METHOD_SECURITY =
      FederalFundsFutureSecurityDiscountingMethod.getInstance();

  private static final double TOLERANCE_PRICE = 1.0E-6;

  @Test
  public void priceBeforeFixing() {
    double interest = 0.0;
    final YieldAndDiscountCurve oisCurve = CURVES.getCurve(CURVE_NAMES[0]);
    final double[] ratePeriod =
        new double[FUTURE_SECURITY_DEFINITION.getFixingPeriodAccrualFactor().length];
    for (int loopfix = 0;
        loopfix < FUTURE_SECURITY_DEFINITION.getFixingPeriodAccrualFactor().length;
        loopfix++) {
      ratePeriod[loopfix] =
          (oisCurve.getDiscountFactor(FUTURE_SECURITY.getFixingPeriodTime()[loopfix])
                      / oisCurve.getDiscountFactor(
                          FUTURE_SECURITY.getFixingPeriodTime()[loopfix + 1])
                  - 1.0)
              / FUTURE_SECURITY_DEFINITION.getFixingPeriodAccrualFactor()[loopfix];
      interest +=
          (oisCurve.getDiscountFactor(FUTURE_SECURITY.getFixingPeriodTime()[loopfix])
                  / oisCurve.getDiscountFactor(FUTURE_SECURITY.getFixingPeriodTime()[loopfix + 1])
              - 1.0);
    }
    final double rate = interest / FUTURE_SECURITY_DEFINITION.getFixingTotalAccrualFactor();
    final double priceExpected = 1.0 - rate;
    final double priceComputed = METHOD_SECURITY.price(FUTURE_SECURITY, CURVES);
    assertEquals(
        "Federal Funds Future Security: price", priceExpected, priceComputed, TOLERANCE_PRICE);
  }

  @Test
  public void priceAfterFixing() {
    final ZonedDateTime referenceDate = DateUtils.getUTCDate(2012, 3, 7);
    final ZonedDateTime[] dateFixing =
        new ZonedDateTime[] {
          DateUtils.getUTCDate(2012, 3, 1),
          DateUtils.getUTCDate(2012, 3, 2),
          DateUtils.getUTCDate(2012, 3, 5),
          DateUtils.getUTCDate(2012, 3, 6),
          DateUtils.getUTCDate(2012, 3, 7)
        };
    final double[] rateFixing = new double[] {0.0010, 0.0011, 0.0012, 0.0013, 0.0014};
    final DoubleTimeSeries<ZonedDateTime> fixingTS =
        ImmutableZonedDateTimeDoubleTimeSeries.ofUTC(dateFixing, rateFixing);
    final FederalFundsFutureSecurity futureSecurity =
        FUTURE_SECURITY_DEFINITION.toDerivative(referenceDate, fixingTS, CURVE_NAMES);
    double interest = futureSecurity.getAccruedInterest();
    final YieldAndDiscountCurve oisCurve = CURVES.getCurve(CURVE_NAMES[0]);
    final double[] ratePeriod = new double[futureSecurity.getFixingPeriodAccrualFactor().length];
    for (int loopfix = 0;
        loopfix < futureSecurity.getFixingPeriodAccrualFactor().length;
        loopfix++) {
      ratePeriod[loopfix] =
          (oisCurve.getDiscountFactor(futureSecurity.getFixingPeriodTime()[loopfix])
                      / oisCurve.getDiscountFactor(
                          futureSecurity.getFixingPeriodTime()[loopfix + 1])
                  - 1.0)
              / futureSecurity.getFixingPeriodAccrualFactor()[loopfix];
      interest +=
          (oisCurve.getDiscountFactor(futureSecurity.getFixingPeriodTime()[loopfix])
                  / oisCurve.getDiscountFactor(futureSecurity.getFixingPeriodTime()[loopfix + 1])
              - 1.0);
    }
    final double rate = interest / FUTURE_SECURITY_DEFINITION.getFixingTotalAccrualFactor();
    final double priceExpected = 1.0 - rate;
    final double priceComputed = METHOD_SECURITY.price(futureSecurity, CURVES);
    assertEquals(
        "Federal Funds Future Security: price", priceExpected, priceComputed, TOLERANCE_PRICE);
  }
}
/** Tests on the construction of interest rate future option with up-front payment. */
public class InterestRateFutureOptionMarginSecurityTest {
  // 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, DAY_COUNT_INDEX, BUSINESS_DAY, IS_EOM);
  // Future
  private static final ZonedDateTime SPOT_LAST_TRADING_DATE = DateUtils.getUTCDate(2012, 9, 19);
  private static final ZonedDateTime LAST_TRADING_DATE =
      ScheduleCalculator.getAdjustedDate(SPOT_LAST_TRADING_DATE, -SETTLEMENT_DAYS, CALENDAR);
  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 double STRIKE = 0.9850;
  private static final InterestRateFutureSecurityDefinition EDU2_DEFINITION =
      new InterestRateFutureSecurityDefinition(
          LAST_TRADING_DATE, IBOR_INDEX, NOTIONAL, FUTURE_FACTOR, NAME, CALENDAR);
  private static final ZonedDateTime REFERENCE_DATE = DateUtils.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 = DateUtils.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 boolean IS_CALL = true;
  private static final InterestRateFutureOptionPremiumSecurity OPTION_EDU2 =
      new InterestRateFutureOptionPremiumSecurity(EDU2, EXPIRATION_TIME, STRIKE, IS_CALL);

  @Test(expectedExceptions = IllegalArgumentException.class)
  public void testNullUnderlying() {
    new InterestRateFutureOptionPremiumSecurity(null, EXPIRATION_TIME, STRIKE, IS_CALL);
  }

  @Test
  public void getter() {
    assertEquals(EDU2, OPTION_EDU2.getUnderlyingFuture());
    assertEquals(EXPIRATION_TIME, OPTION_EDU2.getExpirationTime());
    assertEquals(STRIKE, OPTION_EDU2.getStrike());
    assertEquals(IS_CALL, OPTION_EDU2.isCall());
    assertEquals(DISCOUNTING_CURVE_NAME, OPTION_EDU2.getDiscountingCurveName());
    assertEquals(FORWARD_CURVE_NAME, OPTION_EDU2.getForwardCurveName());
  }

  @Test
  /** Tests the equal and hash code methods. */
  public void equalHash() {
    final InterestRateFutureOptionPremiumSecurity newOption =
        new InterestRateFutureOptionPremiumSecurity(EDU2, EXPIRATION_TIME, STRIKE, IS_CALL);
    assertTrue(OPTION_EDU2.equals(newOption));
    assertEquals(OPTION_EDU2.hashCode(), newOption.hashCode());
    InterestRateFutureOptionPremiumSecurity modifiedOption;
    modifiedOption =
        new InterestRateFutureOptionPremiumSecurity(EDU2, EXPIRATION_TIME - 0.01, STRIKE, IS_CALL);
    assertFalse(OPTION_EDU2.equals(modifiedOption));
    modifiedOption =
        new InterestRateFutureOptionPremiumSecurity(EDU2, EXPIRATION_TIME, STRIKE + 0.01, IS_CALL);
    assertFalse(OPTION_EDU2.equals(modifiedOption));
    modifiedOption =
        new InterestRateFutureOptionPremiumSecurity(EDU2, EXPIRATION_TIME, STRIKE, !IS_CALL);
    assertFalse(OPTION_EDU2.equals(modifiedOption));
  }
}