@Test(expectedExceptions = IllegalArgumentException.class) public void testOneNullPayment() { final CouponIborDefinition[] coupons = new CouponIborDefinition[PAYMENT_DATES.length]; // First coupon uses settlement date CouponFixedDefinition coupon = new CouponFixedDefinition( CUR, PAYMENT_DATES[0], SETTLEMENT_DATE, PAYMENT_DATES[0], DAY_COUNT.getDayCountFraction(SETTLEMENT_DATE, PAYMENT_DATES[0]), NOTIONAL, 0.0); ZonedDateTime fixingDate = ScheduleCalculator.getAdjustedDate( SETTLEMENT_DATE, BUSINESS_DAY, CALENDAR, -SETTLEMENT_DAYS); coupons[0] = null; for (int loopcpn = 1; loopcpn < PAYMENT_DATES.length; loopcpn++) { coupon = new CouponFixedDefinition( CUR, PAYMENT_DATES[loopcpn], PAYMENT_DATES[loopcpn - 1], PAYMENT_DATES[loopcpn], DAY_COUNT.getDayCountFraction(PAYMENT_DATES[loopcpn - 1], PAYMENT_DATES[loopcpn]), NOTIONAL, 0.0); fixingDate = ScheduleCalculator.getAdjustedDate( PAYMENT_DATES[loopcpn - 1], BUSINESS_DAY, CALENDAR, -SETTLEMENT_DAYS); coupons[loopcpn] = CouponIborDefinition.from(coupon, fixingDate, INDEX); } new AnnuityCouponIborDefinition(coupons); }
/** * Cap/floor CMS builder. The fixing date is computed from the start accrual date with the Ibor * index spot lag. The underlying swap is computed from that date and the CMS index. * * @param paymentDate Coupon payment date. * @param accrualStartDate Start date of the accrual period. * @param accrualEndDate End date of the accrual period. * @param accrualFactor Accrual factor of the accrual period. * @param notional Coupon notional. * @param cmsIndex The CMS index associated to the cap/floor. * @param strike The strike * @param isCap The cap (true) /floor (false) flag. * @return The CMS cap/floor. */ public static CapFloorCMSDefinition from( final ZonedDateTime paymentDate, final ZonedDateTime accrualStartDate, final ZonedDateTime accrualEndDate, final double accrualFactor, final double notional, final CMSIndex cmsIndex, final double strike, final boolean isCap) { ZonedDateTime fixingDate = ScheduleCalculator.getAdjustedDate( accrualStartDate, cmsIndex.getIborIndex().getBusinessDayConvention(), cmsIndex.getIborIndex().getCalendar(), -cmsIndex.getIborIndex().getSettlementDays()); // Implementation comment: the underlying swap is used for forward. The notional, rate and payer // flag are irrelevant. final SwapFixedIborDefinition underlyingSwap = SwapFixedIborDefinition.from(accrualStartDate, cmsIndex, 1.0, 1.0, true); return from( paymentDate, accrualStartDate, accrualEndDate, accrualFactor, notional, fixingDate, underlyingSwap, cmsIndex, strike, isCap); }
@Test public void test() { final CouponIborDefinition[] coupons = new CouponIborDefinition[PAYMENT_DATES.length]; final double sign = IS_PAYER ? -1.0 : 1.0; // First coupon uses settlement date CouponFixedDefinition coupon = new CouponFixedDefinition( CUR, PAYMENT_DATES[0], SETTLEMENT_DATE, PAYMENT_DATES[0], DAY_COUNT.getDayCountFraction(SETTLEMENT_DATE, PAYMENT_DATES[0]), sign * NOTIONAL, 0.0); ZonedDateTime fixingDate = ScheduleCalculator.getAdjustedDate( SETTLEMENT_DATE, BUSINESS_DAY, CALENDAR, -SETTLEMENT_DAYS); coupons[0] = CouponIborDefinition.from(coupon, fixingDate, INDEX); for (int loopcpn = 1; loopcpn < PAYMENT_DATES.length; loopcpn++) { coupon = new CouponFixedDefinition( CUR, PAYMENT_DATES[loopcpn], PAYMENT_DATES[loopcpn - 1], PAYMENT_DATES[loopcpn], DAY_COUNT.getDayCountFraction(PAYMENT_DATES[loopcpn - 1], PAYMENT_DATES[loopcpn]), sign * NOTIONAL, 0.0); fixingDate = ScheduleCalculator.getAdjustedDate( PAYMENT_DATES[loopcpn - 1], BUSINESS_DAY, CALENDAR, -SETTLEMENT_DAYS); coupons[loopcpn] = CouponIborDefinition.from(coupon, fixingDate, INDEX); } final AnnuityCouponIborDefinition iborAnnuity = new AnnuityCouponIborDefinition(coupons); // assertEquals(iborAnnuity.getPayments(), coupons); assertEquals(iborAnnuity.isPayer(), IS_PAYER); for (int loopcpn = 0; loopcpn < PAYMENT_DATES.length; loopcpn++) { assertEquals(iborAnnuity.getNthPayment(loopcpn), coupons[loopcpn]); assertEquals(iborAnnuity.getPayments()[loopcpn], coupons[loopcpn]); } final AnnuityCouponIborDefinition iborAnnuity2 = AnnuityCouponIborDefinition.from(SETTLEMENT_DATE, ANNUITY_TENOR, NOTIONAL, INDEX, IS_PAYER); assertEquals(iborAnnuity, iborAnnuity2); }
public class AnnuityCouponIborDefinitionTest { // Libor3m private static final Period INDEX_TENOR = Period.ofMonths(3); private static final PeriodFrequency INDEX_FREQUENCY = PeriodFrequency.QUARTERLY; private static final int SETTLEMENT_DAYS = 2; private static final Calendar CALENDAR = new MondayToFridayCalendar("A"); private static final DayCount DAY_COUNT = 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 INDEX = new IborIndex(CUR, INDEX_TENOR, SETTLEMENT_DAYS, CALENDAR, DAY_COUNT, BUSINESS_DAY, IS_EOM); // Annuity description private static final Period ANNUITY_TENOR = Period.ofYears(2); private static final ZonedDateTime SETTLEMENT_DATE = DateUtils.getUTCDate(2011, 3, 17); private static final boolean IS_PAYER = true; private static final double NOTIONAL = 1000000; private static final ZonedDateTime MATURITY_DATE = ScheduleCalculator.getAdjustedDate( SETTLEMENT_DATE, BUSINESS_DAY, CALENDAR, IS_EOM, ANNUITY_TENOR); private static final ZonedDateTime[] PAYMENT_DATES_UNADJUSTED = ScheduleCalculator.getUnadjustedDateSchedule(SETTLEMENT_DATE, MATURITY_DATE, INDEX_FREQUENCY); private static final ZonedDateTime[] PAYMENT_DATES = ScheduleCalculator.getAdjustedDateSchedule(PAYMENT_DATES_UNADJUSTED, BUSINESS_DAY, CALENDAR); private static final AnnuityCouponIborDefinition IBOR_ANNUITY = AnnuityCouponIborDefinition.from(SETTLEMENT_DATE, ANNUITY_TENOR, NOTIONAL, INDEX, IS_PAYER); private static final ZonedDateTime REFERENCE_DATE = DateUtils.getUTCDate(2011, 3, 15); // For conversion to derivative private static final double FIXING_RATE = 0.05; private static final DoubleTimeSeries<ZonedDateTime> FIXING_TS; static { FIXING_TS = new ArrayZonedDateTimeDoubleTimeSeries( new ZonedDateTime[] {REFERENCE_DATE}, new double[] {FIXING_RATE}); } @Test(expectedExceptions = IllegalArgumentException.class) public void testNullConversionDate() { IBOR_ANNUITY.toDerivative(null, FIXING_TS, new String[] {"L", "K"}); } @Test public void test() { final CouponIborDefinition[] coupons = new CouponIborDefinition[PAYMENT_DATES.length]; final double sign = IS_PAYER ? -1.0 : 1.0; // First coupon uses settlement date CouponFixedDefinition coupon = new CouponFixedDefinition( CUR, PAYMENT_DATES[0], SETTLEMENT_DATE, PAYMENT_DATES[0], DAY_COUNT.getDayCountFraction(SETTLEMENT_DATE, PAYMENT_DATES[0]), sign * NOTIONAL, 0.0); ZonedDateTime fixingDate = ScheduleCalculator.getAdjustedDate( SETTLEMENT_DATE, BUSINESS_DAY, CALENDAR, -SETTLEMENT_DAYS); coupons[0] = CouponIborDefinition.from(coupon, fixingDate, INDEX); for (int loopcpn = 1; loopcpn < PAYMENT_DATES.length; loopcpn++) { coupon = new CouponFixedDefinition( CUR, PAYMENT_DATES[loopcpn], PAYMENT_DATES[loopcpn - 1], PAYMENT_DATES[loopcpn], DAY_COUNT.getDayCountFraction(PAYMENT_DATES[loopcpn - 1], PAYMENT_DATES[loopcpn]), sign * NOTIONAL, 0.0); fixingDate = ScheduleCalculator.getAdjustedDate( PAYMENT_DATES[loopcpn - 1], BUSINESS_DAY, CALENDAR, -SETTLEMENT_DAYS); coupons[loopcpn] = CouponIborDefinition.from(coupon, fixingDate, INDEX); } final AnnuityCouponIborDefinition iborAnnuity = new AnnuityCouponIborDefinition(coupons); // assertEquals(iborAnnuity.getPayments(), coupons); assertEquals(iborAnnuity.isPayer(), IS_PAYER); for (int loopcpn = 0; loopcpn < PAYMENT_DATES.length; loopcpn++) { assertEquals(iborAnnuity.getNthPayment(loopcpn), coupons[loopcpn]); assertEquals(iborAnnuity.getPayments()[loopcpn], coupons[loopcpn]); } final AnnuityCouponIborDefinition iborAnnuity2 = AnnuityCouponIborDefinition.from(SETTLEMENT_DATE, ANNUITY_TENOR, NOTIONAL, INDEX, IS_PAYER); assertEquals(iborAnnuity, iborAnnuity2); } @Test(expectedExceptions = IllegalArgumentException.class) public void testNullPayments() { new AnnuityCouponIborDefinition(null); } @Test(expectedExceptions = IllegalArgumentException.class) public void testOneNullPayment() { final CouponIborDefinition[] coupons = new CouponIborDefinition[PAYMENT_DATES.length]; // First coupon uses settlement date CouponFixedDefinition coupon = new CouponFixedDefinition( CUR, PAYMENT_DATES[0], SETTLEMENT_DATE, PAYMENT_DATES[0], DAY_COUNT.getDayCountFraction(SETTLEMENT_DATE, PAYMENT_DATES[0]), NOTIONAL, 0.0); ZonedDateTime fixingDate = ScheduleCalculator.getAdjustedDate( SETTLEMENT_DATE, BUSINESS_DAY, CALENDAR, -SETTLEMENT_DAYS); coupons[0] = null; for (int loopcpn = 1; loopcpn < PAYMENT_DATES.length; loopcpn++) { coupon = new CouponFixedDefinition( CUR, PAYMENT_DATES[loopcpn], PAYMENT_DATES[loopcpn - 1], PAYMENT_DATES[loopcpn], DAY_COUNT.getDayCountFraction(PAYMENT_DATES[loopcpn - 1], PAYMENT_DATES[loopcpn]), NOTIONAL, 0.0); fixingDate = ScheduleCalculator.getAdjustedDate( PAYMENT_DATES[loopcpn - 1], BUSINESS_DAY, CALENDAR, -SETTLEMENT_DAYS); coupons[loopcpn] = CouponIborDefinition.from(coupon, fixingDate, INDEX); } new AnnuityCouponIborDefinition(coupons); } @Test public void testFrom() { final ZonedDateTime settleDate = DateUtils.getUTCDate(2014, 3, 20); final Period indexTenor = Period.ofMonths(3); final DayCount dayCount = DayCountFactory.INSTANCE.getDayCount("Actual/360"); final IborIndex index = new IborIndex(CUR, indexTenor, SETTLEMENT_DAYS, CALENDAR, dayCount, BUSINESS_DAY, IS_EOM); final AnnuityCouponIborDefinition iborAnnuity = AnnuityCouponIborDefinition.from(settleDate, Period.ofYears(1), NOTIONAL, index, IS_PAYER); final ZonedDateTime[] paymentDates = new ZonedDateTime[] { DateUtils.getUTCDate(2014, 6, 20), DateUtils.getUTCDate(2014, 9, 22), DateUtils.getUTCDate(2014, 12, 22), DateUtils.getUTCDate(2015, 03, 20) }; final ZonedDateTime[] fixingDates = new ZonedDateTime[] { DateUtils.getUTCDate(2014, 3, 18), DateUtils.getUTCDate(2014, 6, 18), DateUtils.getUTCDate(2014, 9, 18), DateUtils.getUTCDate(2014, 12, 18) }; final ZonedDateTime[] startPeriodDates = new ZonedDateTime[] { DateUtils.getUTCDate(2014, 3, 20), DateUtils.getUTCDate(2014, 6, 20), DateUtils.getUTCDate(2014, 9, 22), DateUtils.getUTCDate(2014, 12, 22) }; final ZonedDateTime[] endPeriodDates = new ZonedDateTime[] { DateUtils.getUTCDate(2014, 6, 20), DateUtils.getUTCDate(2014, 9, 22), DateUtils.getUTCDate(2014, 12, 22), DateUtils.getUTCDate(2015, 03, 23) }; for (int loopcpn = 0; loopcpn < iborAnnuity.getPayments().length; loopcpn++) { assertEquals(paymentDates[loopcpn], iborAnnuity.getNthPayment(loopcpn).getPaymentDate()); assertEquals(fixingDates[loopcpn], iborAnnuity.getNthPayment(loopcpn).getFixingDate()); assertEquals( startPeriodDates[loopcpn], iborAnnuity.getNthPayment(loopcpn).getFixingPeriodStartDate()); assertEquals( endPeriodDates[loopcpn], iborAnnuity.getNthPayment(loopcpn).getFixingPeriodEndDate()); } } @Test public void testEqualHash() { final CouponIborDefinition[] coupons = new CouponIborDefinition[PAYMENT_DATES.length]; // First coupon uses settlement date CouponFixedDefinition coupon = new CouponFixedDefinition( CUR, PAYMENT_DATES[0], SETTLEMENT_DATE, PAYMENT_DATES[0], DAY_COUNT.getDayCountFraction(SETTLEMENT_DATE, PAYMENT_DATES[0]), NOTIONAL, 0.0); ZonedDateTime fixingDate = ScheduleCalculator.getAdjustedDate( SETTLEMENT_DATE, BUSINESS_DAY, CALENDAR, -SETTLEMENT_DAYS); coupons[0] = CouponIborDefinition.from(coupon, fixingDate, INDEX); for (int loopcpn = 1; loopcpn < PAYMENT_DATES.length; loopcpn++) { coupon = new CouponFixedDefinition( CUR, PAYMENT_DATES[loopcpn], PAYMENT_DATES[loopcpn - 1], PAYMENT_DATES[loopcpn], DAY_COUNT.getDayCountFraction(PAYMENT_DATES[loopcpn - 1], PAYMENT_DATES[loopcpn]), NOTIONAL, 0.0); fixingDate = ScheduleCalculator.getAdjustedDate( PAYMENT_DATES[loopcpn - 1], BUSINESS_DAY, CALENDAR, -SETTLEMENT_DAYS); coupons[loopcpn] = CouponIborDefinition.from(coupon, fixingDate, INDEX); } final AnnuityCouponIborDefinition iborAnnuity = new AnnuityCouponIborDefinition(coupons); final AnnuityCouponIborDefinition iborAnnuity2 = new AnnuityCouponIborDefinition(coupons); assertEquals(iborAnnuity, iborAnnuity2); assertEquals(iborAnnuity.hashCode(), iborAnnuity2.hashCode()); AnnuityCouponIborDefinition modifiedIborAnnuity = AnnuityCouponIborDefinition.from(SETTLEMENT_DATE, ANNUITY_TENOR, NOTIONAL, INDEX, IS_PAYER); assertFalse(iborAnnuity.equals(modifiedIborAnnuity)); final CouponIborDefinition[] couponsModified = new CouponIborDefinition[PAYMENT_DATES.length]; CouponFixedDefinition couponModified = new CouponFixedDefinition( CUR, PAYMENT_DATES[0], SETTLEMENT_DATE, PAYMENT_DATES[0], DAY_COUNT.getDayCountFraction(SETTLEMENT_DATE, PAYMENT_DATES[0]), NOTIONAL, 0.0); fixingDate = ScheduleCalculator.getAdjustedDate( SETTLEMENT_DATE, BUSINESS_DAY, CALENDAR, -SETTLEMENT_DAYS); couponsModified[0] = CouponIborDefinition.from(couponModified, fixingDate, INDEX); for (int loopcpn = 1; loopcpn < PAYMENT_DATES.length; loopcpn++) { couponModified = new CouponFixedDefinition( CUR, PAYMENT_DATES[loopcpn], PAYMENT_DATES[loopcpn - 1], PAYMENT_DATES[loopcpn], DAY_COUNT.getDayCountFraction(PAYMENT_DATES[loopcpn - 1], PAYMENT_DATES[loopcpn]), NOTIONAL + 5.0, 0.0); fixingDate = ScheduleCalculator.getAdjustedDate( PAYMENT_DATES[loopcpn - 1], BUSINESS_DAY, CALENDAR, -SETTLEMENT_DAYS); couponsModified[loopcpn] = CouponIborDefinition.from(couponModified, fixingDate, INDEX); } modifiedIborAnnuity = new AnnuityCouponIborDefinition(couponsModified); assertFalse(iborAnnuity.equals(modifiedIborAnnuity)); } @Test public void testToDerivativeAfterFixing() { final String fundingCurve = "Funding"; final String forwardCurve = "Forward"; final String[] curves = {fundingCurve, forwardCurve}; final Payment[] couponIborConverted = new Payment[PAYMENT_DATES.length]; ZonedDateTime date = REFERENCE_DATE.plusMonths(1); for (int loopcpn = 0; loopcpn < PAYMENT_DATES.length; loopcpn++) { couponIborConverted[loopcpn] = IBOR_ANNUITY.getNthPayment(loopcpn).toDerivative(date, FIXING_TS, curves); } GenericAnnuity<Payment> referenceAnnuity = new GenericAnnuity<Payment>(couponIborConverted); GenericAnnuity<? extends Payment> convertedDefinition = IBOR_ANNUITY.toDerivative(date, FIXING_TS, curves); assertEquals(referenceAnnuity, convertedDefinition); assertTrue(convertedDefinition.getNthPayment(0) instanceof CouponFixed); assertEquals( ((CouponFixed) convertedDefinition.getNthPayment(0)).getFixedRate(), FIXING_RATE, 0); for (int i = 1; i < PAYMENT_DATES.length; i++) { assertTrue(convertedDefinition.getNthPayment(i) instanceof CouponIbor); } date = REFERENCE_DATE; for (int loopcpn = 0; loopcpn < PAYMENT_DATES.length; loopcpn++) { couponIborConverted[loopcpn] = IBOR_ANNUITY.getNthPayment(loopcpn).toDerivative(date, FIXING_TS, curves); } referenceAnnuity = new GenericAnnuity<Payment>(couponIborConverted); convertedDefinition = IBOR_ANNUITY.toDerivative(date, FIXING_TS, curves); assertEquals(referenceAnnuity, convertedDefinition); assertTrue(convertedDefinition.getNthPayment(0) instanceof CouponFixed); assertEquals( ((CouponFixed) convertedDefinition.getNthPayment(0)).getFixedRate(), FIXING_RATE, 0); for (int i = 1; i < PAYMENT_DATES.length; i++) { assertTrue(convertedDefinition.getNthPayment(i) instanceof CouponIbor); } } @Test public void testToDerivativeBeforeFixing() { final String fundingCurve = "Funding"; final String forwardCurve = "Forward"; final String[] curves = {fundingCurve, forwardCurve}; final Payment[] couponIborConverted = new Payment[PAYMENT_DATES.length]; final ZonedDateTime date = REFERENCE_DATE.minusDays(1); for (int loopcpn = 0; loopcpn < PAYMENT_DATES.length; loopcpn++) { couponIborConverted[loopcpn] = IBOR_ANNUITY.getNthPayment(loopcpn).toDerivative(date, FIXING_TS, curves); } final GenericAnnuity<Payment> referenceAnnuity = new GenericAnnuity<Payment>(couponIborConverted); final GenericAnnuity<? extends Payment> convertedDefinition = IBOR_ANNUITY.toDerivative(date, FIXING_TS, curves); assertEquals(referenceAnnuity, convertedDefinition); for (int i = 0; i < PAYMENT_DATES.length; i++) { assertTrue(convertedDefinition.getNthPayment(i) instanceof CouponIbor); } } @Test(expectedExceptions = IllegalArgumentException.class) public void testStaticConstructionNullSettlementDate1() { AnnuityCouponIborDefinition.from(null, ANNUITY_TENOR, NOTIONAL, INDEX, IS_PAYER); } @Test(expectedExceptions = IllegalArgumentException.class) public void testStaticConstructionNullSettlementDate2() { AnnuityCouponIborDefinition.from(null, MATURITY_DATE, NOTIONAL, INDEX, IS_PAYER); } @Test(expectedExceptions = IllegalArgumentException.class) public void testStaticConstructionNullSettlementDate3() { AnnuityCouponIborDefinition.fromAccrualUnadjusted( null, MATURITY_DATE, NOTIONAL, INDEX, IS_PAYER); } @Test(expectedExceptions = IllegalArgumentException.class) public void testStaticConstructionNullPeriod() { AnnuityCouponIborDefinition.from(SETTLEMENT_DATE, (Period) null, NOTIONAL, INDEX, IS_PAYER); } @Test(expectedExceptions = IllegalArgumentException.class) public void testStaticConstructionNullMaturityDate1() { AnnuityCouponIborDefinition.from( SETTLEMENT_DATE, (ZonedDateTime) null, NOTIONAL, INDEX, IS_PAYER); } @Test(expectedExceptions = IllegalArgumentException.class) public void testStaticConstructionNullMaturityDate2() { AnnuityCouponIborDefinition.fromAccrualUnadjusted( SETTLEMENT_DATE, null, NOTIONAL, INDEX, IS_PAYER); } @Test(expectedExceptions = IllegalArgumentException.class) public void testStaticConstructionNegativeNotional1() { AnnuityCouponIborDefinition.from(SETTLEMENT_DATE, ANNUITY_TENOR, -NOTIONAL, INDEX, IS_PAYER); } @Test(expectedExceptions = IllegalArgumentException.class) public void testStaticConstructionNegativeNotional2() { AnnuityCouponIborDefinition.from(SETTLEMENT_DATE, MATURITY_DATE, -NOTIONAL, INDEX, IS_PAYER); } @Test(expectedExceptions = IllegalArgumentException.class) public void testStaticConstructionNegativeNotional3() { AnnuityCouponIborDefinition.fromAccrualUnadjusted( SETTLEMENT_DATE, MATURITY_DATE, -NOTIONAL, INDEX, IS_PAYER); } @Test(expectedExceptions = IllegalArgumentException.class) public void testStaticConstructionNullIndex1() { AnnuityCouponIborDefinition.from(SETTLEMENT_DATE, ANNUITY_TENOR, NOTIONAL, null, IS_PAYER); } @Test(expectedExceptions = IllegalArgumentException.class) public void testStaticConstructionNullIndex2() { AnnuityCouponIborDefinition.from(SETTLEMENT_DATE, MATURITY_DATE, NOTIONAL, null, IS_PAYER); } @Test(expectedExceptions = IllegalArgumentException.class) public void testStaticConstructionNullIndex3() { AnnuityCouponIborDefinition.fromAccrualUnadjusted( SETTLEMENT_DATE, MATURITY_DATE, NOTIONAL, null, IS_PAYER); } @Test(expectedExceptions = IllegalArgumentException.class) public void testStaticConstructionNullAnnuity() { AnnuityCouponIborDefinition.from(null); } @Test public void testStaticConstruction() { AnnuityCouponIborDefinition definition1 = AnnuityCouponIborDefinition.from(SETTLEMENT_DATE, ANNUITY_TENOR, NOTIONAL, INDEX, IS_PAYER); AnnuityCouponIborDefinition definition2 = AnnuityCouponIborDefinition.from(SETTLEMENT_DATE, MATURITY_DATE, NOTIONAL, INDEX, IS_PAYER); assertEquals(definition1, definition2); assertEquals(IS_PAYER, definition1.isPayer()); definition2 = AnnuityCouponIborDefinition.from( SETTLEMENT_DATE, ANNUITY_TENOR, NOTIONAL, INDEX, !IS_PAYER); assertFalse(definition1.equals(definition2)); definition2 = AnnuityCouponIborDefinition.from( SETTLEMENT_DATE, MATURITY_DATE, NOTIONAL, INDEX, !IS_PAYER); assertFalse(definition1.equals(definition2)); definition1 = AnnuityCouponIborDefinition.fromAccrualUnadjusted( SETTLEMENT_DATE, MATURITY_DATE, NOTIONAL, INDEX, IS_PAYER); definition2 = AnnuityCouponIborDefinition.fromAccrualUnadjusted( SETTLEMENT_DATE, MATURITY_DATE, NOTIONAL, INDEX, !IS_PAYER); assertFalse(definition1.equals(definition2)); } @Test public void testNoSpread() { final AnnuityCouponIborDefinition definition = AnnuityCouponIborDefinition.from(SETTLEMENT_DATE, MATURITY_DATE, NOTIONAL, INDEX, IS_PAYER); final CouponIborDefinition[] noSpreadCoupons = definition.getPayments(); final int n = noSpreadCoupons.length; final double spread = 0.01; final CouponIborSpreadDefinition[] spreadCoupons = new CouponIborSpreadDefinition[n]; for (int i = 0; i < n; i++) { final CouponIborDefinition coupon = noSpreadCoupons[i]; spreadCoupons[i] = new CouponIborSpreadDefinition( coupon.getCurrency(), coupon.getPaymentDate(), coupon.getAccrualStartDate(), coupon.getAccrualEndDate(), coupon.getPaymentYearFraction(), coupon.getNotional(), coupon.getFixingDate(), coupon.getIndex(), spread); } assertEquals( definition, AnnuityCouponIborDefinition.from(new AnnuityCouponIborSpreadDefinition(spreadCoupons))); } }
@Test public void testEqualHash() { final CouponIborDefinition[] coupons = new CouponIborDefinition[PAYMENT_DATES.length]; // First coupon uses settlement date CouponFixedDefinition coupon = new CouponFixedDefinition( CUR, PAYMENT_DATES[0], SETTLEMENT_DATE, PAYMENT_DATES[0], DAY_COUNT.getDayCountFraction(SETTLEMENT_DATE, PAYMENT_DATES[0]), NOTIONAL, 0.0); ZonedDateTime fixingDate = ScheduleCalculator.getAdjustedDate( SETTLEMENT_DATE, BUSINESS_DAY, CALENDAR, -SETTLEMENT_DAYS); coupons[0] = CouponIborDefinition.from(coupon, fixingDate, INDEX); for (int loopcpn = 1; loopcpn < PAYMENT_DATES.length; loopcpn++) { coupon = new CouponFixedDefinition( CUR, PAYMENT_DATES[loopcpn], PAYMENT_DATES[loopcpn - 1], PAYMENT_DATES[loopcpn], DAY_COUNT.getDayCountFraction(PAYMENT_DATES[loopcpn - 1], PAYMENT_DATES[loopcpn]), NOTIONAL, 0.0); fixingDate = ScheduleCalculator.getAdjustedDate( PAYMENT_DATES[loopcpn - 1], BUSINESS_DAY, CALENDAR, -SETTLEMENT_DAYS); coupons[loopcpn] = CouponIborDefinition.from(coupon, fixingDate, INDEX); } final AnnuityCouponIborDefinition iborAnnuity = new AnnuityCouponIborDefinition(coupons); final AnnuityCouponIborDefinition iborAnnuity2 = new AnnuityCouponIborDefinition(coupons); assertEquals(iborAnnuity, iborAnnuity2); assertEquals(iborAnnuity.hashCode(), iborAnnuity2.hashCode()); AnnuityCouponIborDefinition modifiedIborAnnuity = AnnuityCouponIborDefinition.from(SETTLEMENT_DATE, ANNUITY_TENOR, NOTIONAL, INDEX, IS_PAYER); assertFalse(iborAnnuity.equals(modifiedIborAnnuity)); final CouponIborDefinition[] couponsModified = new CouponIborDefinition[PAYMENT_DATES.length]; CouponFixedDefinition couponModified = new CouponFixedDefinition( CUR, PAYMENT_DATES[0], SETTLEMENT_DATE, PAYMENT_DATES[0], DAY_COUNT.getDayCountFraction(SETTLEMENT_DATE, PAYMENT_DATES[0]), NOTIONAL, 0.0); fixingDate = ScheduleCalculator.getAdjustedDate( SETTLEMENT_DATE, BUSINESS_DAY, CALENDAR, -SETTLEMENT_DAYS); couponsModified[0] = CouponIborDefinition.from(couponModified, fixingDate, INDEX); for (int loopcpn = 1; loopcpn < PAYMENT_DATES.length; loopcpn++) { couponModified = new CouponFixedDefinition( CUR, PAYMENT_DATES[loopcpn], PAYMENT_DATES[loopcpn - 1], PAYMENT_DATES[loopcpn], DAY_COUNT.getDayCountFraction(PAYMENT_DATES[loopcpn - 1], PAYMENT_DATES[loopcpn]), NOTIONAL + 5.0, 0.0); fixingDate = ScheduleCalculator.getAdjustedDate( PAYMENT_DATES[loopcpn - 1], BUSINESS_DAY, CALENDAR, -SETTLEMENT_DAYS); couponsModified[loopcpn] = CouponIborDefinition.from(couponModified, fixingDate, INDEX); } modifiedIborAnnuity = new AnnuityCouponIborDefinition(couponsModified); assertFalse(iborAnnuity.equals(modifiedIborAnnuity)); }
/** 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 related to the pricing of physical delivery swaption in G2++ model. */ public class SwaptionPhysicalFixedIborG2ppMethodTest { // Swaption 5Yx5Y private static final Currency CUR = Currency.USD; private static final Calendar CALENDAR = new MondayToFridayCalendar("A"); private static final BusinessDayConvention BUSINESS_DAY = BusinessDayConventionFactory.INSTANCE.getBusinessDayConvention("Modified Following"); private static final boolean IS_EOM = true; private static final int SETTLEMENT_DAYS = 2; private static final Period IBOR_TENOR = Period.ofMonths(3); private static final DayCount IBOR_DAY_COUNT = DayCountFactory.INSTANCE.getDayCount("Actual/360"); private static final IborIndex IBOR_INDEX = new IborIndex( CUR, IBOR_TENOR, SETTLEMENT_DAYS, CALENDAR, IBOR_DAY_COUNT, BUSINESS_DAY, IS_EOM); private static final int SWAP_TENOR_YEAR = 5; private static final Period SWAP_TENOR = Period.ofYears(SWAP_TENOR_YEAR); private static final Period FIXED_PAYMENT_PERIOD = Period.ofMonths(6); private static final DayCount FIXED_DAY_COUNT = DayCountFactory.INSTANCE.getDayCount("30/360"); private static final CMSIndex CMS_INDEX = new CMSIndex(FIXED_PAYMENT_PERIOD, FIXED_DAY_COUNT, IBOR_INDEX, SWAP_TENOR); private static final ZonedDateTime EXPIRY_DATE = DateUtils.getUTCDate(2016, 7, 7); private static final ZonedDateTime SETTLEMENT_DATE = ScheduleCalculator.getAdjustedDate(EXPIRY_DATE, CALENDAR, SETTLEMENT_DAYS); private static final double NOTIONAL = 100000000; // 100m private static final double RATE = 0.0325; private static final boolean FIXED_IS_PAYER = true; private static final SwapFixedIborDefinition SWAP_PAYER_DEFINITION = SwapFixedIborDefinition.from(SETTLEMENT_DATE, CMS_INDEX, NOTIONAL, RATE, FIXED_IS_PAYER); private static final SwapFixedIborDefinition SWAP_RECEIVER_DEFINITION = SwapFixedIborDefinition.from(SETTLEMENT_DATE, CMS_INDEX, NOTIONAL, RATE, !FIXED_IS_PAYER); private static final boolean IS_LONG = true; private static final SwaptionPhysicalFixedIborDefinition SWAPTION_PAYER_LONG_DEFINITION = SwaptionPhysicalFixedIborDefinition.from(EXPIRY_DATE, SWAP_PAYER_DEFINITION, IS_LONG); private static final SwaptionPhysicalFixedIborDefinition SWAPTION_RECEIVER_LONG_DEFINITION = SwaptionPhysicalFixedIborDefinition.from(EXPIRY_DATE, SWAP_RECEIVER_DEFINITION, IS_LONG); private static final SwaptionPhysicalFixedIborDefinition SWAPTION_PAYER_SHORT_DEFINITION = SwaptionPhysicalFixedIborDefinition.from(EXPIRY_DATE, SWAP_PAYER_DEFINITION, !IS_LONG); private static final SwaptionPhysicalFixedIborDefinition SWAPTION_RECEIVER_SHORT_DEFINITION = SwaptionPhysicalFixedIborDefinition.from(EXPIRY_DATE, SWAP_RECEIVER_DEFINITION, !IS_LONG); // to derivatives private static final ZonedDateTime REFERENCE_DATE = DateUtils.getUTCDate(2011, 7, 7); 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}; private static final YieldCurveBundle CURVES = TestsDataSets.createCurves1(); private static final FixedCouponSwap<Coupon> SWAP_RECEIVER = SWAP_RECEIVER_DEFINITION.toDerivative(REFERENCE_DATE, CURVES_NAME); private static final SwaptionPhysicalFixedIbor SWAPTION_PAYER_LONG = SWAPTION_PAYER_LONG_DEFINITION.toDerivative(REFERENCE_DATE, CURVES_NAME); private static final SwaptionPhysicalFixedIbor SWAPTION_RECEIVER_LONG = SWAPTION_RECEIVER_LONG_DEFINITION.toDerivative(REFERENCE_DATE, CURVES_NAME); private static final SwaptionPhysicalFixedIbor SWAPTION_PAYER_SHORT = SWAPTION_PAYER_SHORT_DEFINITION.toDerivative(REFERENCE_DATE, CURVES_NAME); private static final SwaptionPhysicalFixedIbor SWAPTION_RECEIVER_SHORT = SWAPTION_RECEIVER_SHORT_DEFINITION.toDerivative(REFERENCE_DATE, CURVES_NAME); // Calculator private static final SwaptionPhysicalFixedIborG2ppApproximationMethod METHOD_G2PP_APPROXIMATION = new SwaptionPhysicalFixedIborG2ppApproximationMethod(); private static final SwaptionPhysicalFixedIborG2ppNumericalIntegrationMethod METHOD_G2PP_NI = new SwaptionPhysicalFixedIborG2ppNumericalIntegrationMethod(); private static final G2ppPiecewiseConstantParameters PARAMETERS_G2PP = G2ppTestsDataSet.createG2ppParameters(); private static final G2ppPiecewiseConstantDataBundle BUNDLE_G2PP = new G2ppPiecewiseConstantDataBundle(PARAMETERS_G2PP, CURVES); private static final PresentValueCalculator PVC = PresentValueCalculator.getInstance(); @Test(enabled = false) /** * Test the present value vs a external system. "enabled = false" for the standard testing: the * external system is using a TimeCalculator with ACT/365. */ public void presentValueExternal() { G2ppPiecewiseConstantParameters parametersCst = G2ppTestsDataSet.createG2ppCstParameters(); final YieldAndDiscountCurve curve5 = new YieldCurve(ConstantDoublesCurve.from(0.05)); final YieldCurveBundle curves = new YieldCurveBundle(); curves.setCurve(FUNDING_CURVE_NAME, curve5); curves.setCurve(FORWARD_CURVE_NAME, curve5); G2ppPiecewiseConstantDataBundle bundleCst = new G2ppPiecewiseConstantDataBundle(parametersCst, curves); CurrencyAmount pv = METHOD_G2PP_APPROXIMATION.presentValue(SWAPTION_PAYER_LONG, bundleCst); double pvExternal = 6885626.28245924; // ! TimeCalculator with ACT/365 assertEquals( "Swaption physical - G2++ - present value - external system", pvExternal, pv.getAmount(), 1E-2); } @Test(enabled = true) /** Test the present value vs a hard-coded value. */ public void presentValue() { CurrencyAmount pv = METHOD_G2PP_APPROXIMATION.presentValue(SWAPTION_PAYER_LONG, BUNDLE_G2PP); double pvExpected = 4893110.87; assertEquals( "Swaption physical - G2++ - present value - hard coded value", pvExpected, pv.getAmount(), 1E-2); } @Test /** Tests long/short parity. */ public void longShortParity() { CurrencyAmount pvPayerLong = METHOD_G2PP_APPROXIMATION.presentValue(SWAPTION_PAYER_LONG, BUNDLE_G2PP); CurrencyAmount pvPayerShort = METHOD_G2PP_APPROXIMATION.presentValue(SWAPTION_PAYER_SHORT, BUNDLE_G2PP); assertEquals( "Swaption physical - G2++ - present value - long/short parity", pvPayerLong.getAmount(), -pvPayerShort.getAmount(), 1E-2); CurrencyAmount pvReceiverLong = METHOD_G2PP_APPROXIMATION.presentValue(SWAPTION_RECEIVER_LONG, BUNDLE_G2PP); CurrencyAmount pvReceiverShort = METHOD_G2PP_APPROXIMATION.presentValue(SWAPTION_RECEIVER_SHORT, BUNDLE_G2PP); assertEquals( "Swaption physical - G2++ - present value - long/short parity", pvReceiverLong.getAmount(), -pvReceiverShort.getAmount(), 1E-2); } @Test /** Tests payer/receiver/swap parity. */ public void payerReceiverParity() { CurrencyAmount pvReceiverLong = METHOD_G2PP_APPROXIMATION.presentValue(SWAPTION_RECEIVER_LONG, BUNDLE_G2PP); CurrencyAmount pvPayerShort = METHOD_G2PP_APPROXIMATION.presentValue(SWAPTION_PAYER_SHORT, BUNDLE_G2PP); double pvSwap = PVC.visit(SWAP_RECEIVER, CURVES); assertEquals( "Swaption physical - G2++ - present value - payer/receiver/swap parity", pvReceiverLong.getAmount() + pvPayerShort.getAmount(), pvSwap, 1E-2); } @Test /** Test the present value by approximation vs by numerical integration. */ public void approximationNumericalIntegration() { CurrencyAmount pvApproximation = METHOD_G2PP_APPROXIMATION.presentValue(SWAPTION_PAYER_LONG, BUNDLE_G2PP); CurrencyAmount pvNI = METHOD_G2PP_NI.presentValue(SWAPTION_PAYER_LONG, BUNDLE_G2PP); assertEquals( "Swaption physical - G2++ - present value - approximation vs Numerical integration", pvApproximation.getAmount(), pvNI.getAmount(), 2.0E+3); } @Test(enabled = false) /** Tests of performance. "enabled = false" for the standard testing. */ public void performance() { long startTime, endTime; final int nbTest = 100; CurrencyAmount pvPayerLongApproximation = CurrencyAmount.of(CUR, 0.0); CurrencyAmount pvPayerLongNI = CurrencyAmount.of(CUR, 0.0); startTime = System.currentTimeMillis(); for (int looptest = 0; looptest < nbTest; looptest++) { pvPayerLongApproximation = METHOD_G2PP_APPROXIMATION.presentValue(SWAPTION_PAYER_LONG, BUNDLE_G2PP); } endTime = System.currentTimeMillis(); System.out.println( nbTest + " pv swaption G2++ approximation method: " + (endTime - startTime) + " ms"); // Performance note: G2++ price: 24-Aug-11: On Mac Pro 3.2 GHz Quad-Core Intel Xeon: 175 ms for // 10000 swaptions. startTime = System.currentTimeMillis(); for (int looptest = 0; looptest < nbTest; looptest++) { pvPayerLongNI = METHOD_G2PP_NI.presentValue(SWAPTION_PAYER_LONG, BUNDLE_G2PP); } endTime = System.currentTimeMillis(); System.out.println( nbTest + " pv swaption G2++ numerical integration method: " + (endTime - startTime) + " ms"); // Performance note: G2++ price: 24-Aug-11: On Mac Pro 3.2 GHz Quad-Core Intel Xeon: 1075 ms for // 100 swaptions. System.out.println("G2++ approximation - present value: " + pvPayerLongApproximation); System.out.println("G2++ numerical integration - present value: " + pvPayerLongNI); } }
/** 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); } }
/** * Class to test the present value and present value rate sensitivity of the cash-settled European * swaption in the SABR with extrapolation method. The SABR smile is extrapolated above a certain * cut-off strike. */ public class SwaptionCashFixedIborSABRExtrapolationRightMethodTest { // Swaption description private static final ZonedDateTime EXPIRY_DATE = DateUtils.getUTCDate(2014, 3, 18); private static final boolean IS_LONG = true; private static final int SETTLEMENT_DAYS = 2; // Swap 5Y description private static final Currency CUR = Currency.USD; private static final Calendar CALENDAR = new MondayToFridayCalendar("A"); private static final BusinessDayConvention BUSINESS_DAY = BusinessDayConventionFactory.INSTANCE.getBusinessDayConvention("Modified Following"); private static final boolean IS_EOM = true; private static final int ANNUITY_TENOR_YEAR = 5; private static final Period ANNUITY_TENOR = Period.ofYears(ANNUITY_TENOR_YEAR); private static final ZonedDateTime SETTLEMENT_DATE = ScheduleCalculator.getAdjustedDate(EXPIRY_DATE, SETTLEMENT_DAYS, CALENDAR); private static final double NOTIONAL = 100000000; // 100m // Fixed leg: Semi-annual bond private static final Period FIXED_PAYMENT_PERIOD = Period.ofMonths(6); private static final DayCount FIXED_DAY_COUNT = DayCountFactory.INSTANCE.getDayCount("30/360"); private static final double RATE = 0.04; private static final boolean FIXED_IS_PAYER = true; // Ibor leg: quarterly money private static final Period INDEX_TENOR = Period.ofMonths(3); private static final DayCount DAY_COUNT = DayCountFactory.INSTANCE.getDayCount("Actual/360"); private static final IborIndex IBOR_INDEX = new IborIndex(CUR, INDEX_TENOR, SETTLEMENT_DAYS, CALENDAR, DAY_COUNT, BUSINESS_DAY, IS_EOM); // Swaption construction private static final IndexSwap CMS_INDEX = new IndexSwap(FIXED_PAYMENT_PERIOD, FIXED_DAY_COUNT, IBOR_INDEX, ANNUITY_TENOR); private static final SwapFixedIborDefinition SWAP_DEFINITION_PAYER = SwapFixedIborDefinition.from(SETTLEMENT_DATE, CMS_INDEX, NOTIONAL, RATE, FIXED_IS_PAYER); private static final SwapFixedIborDefinition SWAP_DEFINITION_RECEIVER = SwapFixedIborDefinition.from(SETTLEMENT_DATE, CMS_INDEX, NOTIONAL, RATE, !FIXED_IS_PAYER); private static final SwaptionCashFixedIborDefinition SWAPTION_DEFINITION_LONG_PAYER = SwaptionCashFixedIborDefinition.from(EXPIRY_DATE, SWAP_DEFINITION_PAYER, IS_LONG); private static final SwaptionCashFixedIborDefinition SWAPTION_DEFINITION_LONG_RECEIVER = SwaptionCashFixedIborDefinition.from(EXPIRY_DATE, SWAP_DEFINITION_RECEIVER, IS_LONG); private static final SwaptionCashFixedIborDefinition SWAPTION_DEFINITION_SHORT_PAYER = SwaptionCashFixedIborDefinition.from(EXPIRY_DATE, SWAP_DEFINITION_PAYER, !IS_LONG); private static final SwaptionCashFixedIborDefinition SWAPTION_DEFINITION_SHORT_RECEIVER = SwaptionCashFixedIborDefinition.from(EXPIRY_DATE, SWAP_DEFINITION_RECEIVER, !IS_LONG); // to derivatives private static final ZonedDateTime REFERENCE_DATE = DateUtils.getUTCDate(2008, 8, 18); 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}; private static final SwaptionCashFixedIbor SWAPTION_LONG_PAYER = SWAPTION_DEFINITION_LONG_PAYER.toDerivative(REFERENCE_DATE, CURVES_NAME); private static final SwaptionCashFixedIbor SWAPTION_LONG_RECEIVER = SWAPTION_DEFINITION_LONG_RECEIVER.toDerivative(REFERENCE_DATE, CURVES_NAME); private static final SwaptionCashFixedIbor SWAPTION_SHORT_PAYER = SWAPTION_DEFINITION_SHORT_PAYER.toDerivative(REFERENCE_DATE, CURVES_NAME); private static final SwaptionCashFixedIbor SWAPTION_SHORT_RECEIVER = SWAPTION_DEFINITION_SHORT_RECEIVER.toDerivative(REFERENCE_DATE, CURVES_NAME); // Extrapolation private static final double CUT_OFF_STRIKE = 0.08; private static final double MU = 10.0; private static final SwaptionCashFixedIborSABRExtrapolationRightMethod METHOD_EXTRAPOLATION = new SwaptionCashFixedIborSABRExtrapolationRightMethod(CUT_OFF_STRIKE, MU); // Calculators private static final PresentValueSABRExtrapolationCalculator PVC = PresentValueSABRExtrapolationCalculator.getInstance(); /** Tests present value in the region where there is no extrapolation. Tests long/short parity. */ @Test public void testPresentValueNoExtra() { final YieldCurveBundle curves = TestsDataSetsSABR.createCurves1(); final SABRInterestRateParameters sabrParameter = TestsDataSetsSABR.createSABRExtrapolation1(CUT_OFF_STRIKE, MU); final SABRInterestRateDataBundle sabrBundle = new SABRInterestRateDataBundle(sabrParameter, curves); final SwaptionCashFixedIborSABRExtrapolationRightMethod method = new SwaptionCashFixedIborSABRExtrapolationRightMethod(CUT_OFF_STRIKE, MU); final double priceLongPayer = method.presentValue(SWAPTION_LONG_PAYER, sabrBundle); final double priceShortPayer = method.presentValue(SWAPTION_SHORT_PAYER, sabrBundle); final double priceLongReceiver = method.presentValue(SWAPTION_LONG_RECEIVER, sabrBundle); final double priceShortReceiver = method.presentValue(SWAPTION_SHORT_RECEIVER, sabrBundle); final double priceLongPayerNoExtra = PVC.visit(SWAPTION_LONG_PAYER, sabrBundle); final double priceShortPayerNoExtra = PVC.visit(SWAPTION_SHORT_PAYER, sabrBundle); final double priceLongReceiverNoExtra = PVC.visit(SWAPTION_LONG_RECEIVER, sabrBundle); final double priceShortReceiverNoExtra = PVC.visit(SWAPTION_SHORT_RECEIVER, sabrBundle); assertEquals( "Swaption cash SABR extrapolation: below cut-off strike", priceLongPayerNoExtra, priceLongPayer, 1E-2); assertEquals( "Swaption cash SABR extrapolation: below cut-off strike", priceShortPayerNoExtra, priceShortPayer, 1E-2); assertEquals( "Swaption cash SABR extrapolation: below cut-off strike", priceLongReceiverNoExtra, priceLongReceiver, 1E-2); assertEquals( "Swaption cash SABR extrapolation: below cut-off strike", priceShortReceiverNoExtra, priceShortReceiver, 1E-2); assertEquals( "Swaption cash SABR extrapolation: below cut-off strike long/short parity", priceLongPayer, -priceShortPayer, 1E-2); assertEquals( "Swaption cash SABR extrapolation: below cut-off strike long/short parity", priceLongReceiver, -priceShortReceiver, 1E-2); } /** * Tests present value in the region where there is extrapolation. Test a hard-coded value. Tests * long/short parity. Test payer/receiver/swap parity. */ @Test public void testPresentValueExtra() { final YieldCurveBundle curves = TestsDataSetsSABR.createCurves1(); final SABRInterestRateParameters sabrParameter = TestsDataSetsSABR.createSABR1(); final SABRInterestRateDataBundle sabrBundle = new SABRInterestRateDataBundle(sabrParameter, curves); final double highStrike = 0.10; final SwapFixedIborDefinition swapDefinitionPayerHighStrike = SwapFixedIborDefinition.from( SETTLEMENT_DATE, CMS_INDEX, NOTIONAL, highStrike, FIXED_IS_PAYER); final SwapFixedIborDefinition swapDefinitionReceiverHighStrike = SwapFixedIborDefinition.from( SETTLEMENT_DATE, CMS_INDEX, NOTIONAL, highStrike, !FIXED_IS_PAYER); final SwaptionCashFixedIborDefinition swaptionDefinitionLongPayerHighStrike = SwaptionCashFixedIborDefinition.from(EXPIRY_DATE, swapDefinitionPayerHighStrike, IS_LONG); final SwaptionCashFixedIborDefinition swaptionDefinitionShortPayerHighStrike = SwaptionCashFixedIborDefinition.from(EXPIRY_DATE, swapDefinitionPayerHighStrike, !IS_LONG); final SwaptionCashFixedIborDefinition swaptionDefinitionLongReceiverHighStrike = SwaptionCashFixedIborDefinition.from( EXPIRY_DATE, swapDefinitionReceiverHighStrike, IS_LONG); final SwaptionCashFixedIbor swaptionLongPayerHighStrike = swaptionDefinitionLongPayerHighStrike.toDerivative(REFERENCE_DATE, CURVES_NAME); final SwaptionCashFixedIbor swaptionShortPayerHighStrike = swaptionDefinitionShortPayerHighStrike.toDerivative(REFERENCE_DATE, CURVES_NAME); final SwaptionCashFixedIbor swaptionLongReceiverHighStrike = swaptionDefinitionLongReceiverHighStrike.toDerivative(REFERENCE_DATE, CURVES_NAME); final SwaptionCashFixedIborSABRExtrapolationRightMethod method = new SwaptionCashFixedIborSABRExtrapolationRightMethod(CUT_OFF_STRIKE, MU); final double priceLongPayer = method.presentValue(swaptionLongPayerHighStrike, sabrBundle); final double priceShortPayer = method.presentValue(swaptionShortPayerHighStrike, sabrBundle); final double priceLongReceiver = method.presentValue(swaptionLongReceiverHighStrike, sabrBundle); final double priceLongPayerExpected = 557829.033; // Value from previous run final double priceLongReceiverExpected = 20759354.082; // Value from previous run assertEquals( "Swaption cash SABR extrapolation: fixed value", priceLongPayerExpected, priceLongPayer, 1E-2); assertEquals( "Swaption cash SABR extrapolation: fixed value", priceLongReceiverExpected, priceLongReceiver, 1E-2); assertEquals( "Swaption cash SABR extrapolation: long/short parity", priceLongPayer, -priceShortPayer, 1E-2); } @Test /** * Test the present value sensitivity to rate for a swaption with strike above the cut-off strike. */ public void testPresentValueSensitivityExtra() { final YieldCurveBundle curves = TestsDataSetsSABR.createCurves1(); final SABRInterestRateParameters sabrParameter = TestsDataSetsSABR.createSABR1(); final SABRInterestRateDataBundle sabrBundle = new SABRInterestRateDataBundle(sabrParameter, curves); final double highStrike = 0.10; final SwapFixedIborDefinition swapDefinitionPayerHighStrike = SwapFixedIborDefinition.from( SETTLEMENT_DATE, CMS_INDEX, NOTIONAL, highStrike, FIXED_IS_PAYER); final SwaptionCashFixedIborDefinition swaptionDefinitionLongPayerHighStrike = SwaptionCashFixedIborDefinition.from(EXPIRY_DATE, swapDefinitionPayerHighStrike, IS_LONG); final SwaptionCashFixedIborDefinition swaptionDefinitionShortPayerHighStrike = SwaptionCashFixedIborDefinition.from(EXPIRY_DATE, swapDefinitionPayerHighStrike, !IS_LONG); final SwaptionCashFixedIbor swaptionLongPayerHighStrike = swaptionDefinitionLongPayerHighStrike.toDerivative(REFERENCE_DATE, CURVES_NAME); final SwaptionCashFixedIbor swaptionShortPayerHighStrike = swaptionDefinitionShortPayerHighStrike.toDerivative(REFERENCE_DATE, CURVES_NAME); final SwaptionCashFixedIborSABRExtrapolationRightMethod methodExtra = new SwaptionCashFixedIborSABRExtrapolationRightMethod(CUT_OFF_STRIKE, MU); // Swaption sensitivity InterestRateCurveSensitivity pvsLongPayerExtra = methodExtra.presentValueSensitivity(swaptionLongPayerHighStrike, sabrBundle); final InterestRateCurveSensitivity pvsShortPayerExtra = methodExtra.presentValueSensitivity(swaptionShortPayerHighStrike, sabrBundle); // Long/short parity final InterestRateCurveSensitivity pvsShortPayer_1 = pvsShortPayerExtra.multiply(-1); assertEquals(pvsLongPayerExtra.getSensitivities(), pvsShortPayer_1.getSensitivities()); // Present value sensitivity comparison with finite difference. final double deltaTolerance = 5.0E+4; // Testing note: Sensitivity is for a movement of 1. 1E+2 = 1 cent for a 1 bp move. Tolerance // increased to cope with numerical imprecision of finite difference. final double deltaShift = 1.0E-5; pvsLongPayerExtra = pvsLongPayerExtra.clean(); final double pv = methodExtra.presentValue(swaptionLongPayerHighStrike, sabrBundle); // 1. Forward curve sensitivity final String bumpedCurveName = "Bumped Curve"; final String[] bumpedCurvesForwardName = {FUNDING_CURVE_NAME, bumpedCurveName}; final SwaptionCashFixedIbor swaptionBumpedForward = swaptionDefinitionLongPayerHighStrike.toDerivative(REFERENCE_DATE, bumpedCurvesForwardName); final YieldAndDiscountCurve curveForward = curves.getCurve(FORWARD_CURVE_NAME); final Set<Double> timeForwardSet = new TreeSet<Double>(); for (final Payment pay : swaptionLongPayerHighStrike.getUnderlyingSwap().getSecondLeg().getPayments()) { final CouponIbor coupon = (CouponIbor) pay; timeForwardSet.add(coupon.getFixingPeriodStartTime()); timeForwardSet.add(coupon.getFixingPeriodEndTime()); } final int nbForwardDate = timeForwardSet.size(); final List<Double> timeForwardList = new ArrayList<Double>(timeForwardSet); Double[] timeForwardArray = new Double[nbForwardDate]; timeForwardArray = timeForwardList.toArray(timeForwardArray); final double[] yieldsForward = new double[nbForwardDate + 1]; final double[] nodeTimesForward = new double[nbForwardDate + 1]; yieldsForward[0] = curveForward.getInterestRate(0.0); for (int i = 0; i < nbForwardDate; i++) { nodeTimesForward[i + 1] = timeForwardArray[i]; yieldsForward[i + 1] = curveForward.getInterestRate(nodeTimesForward[i + 1]); } final YieldAndDiscountCurve tempCurveForward = new YieldCurve( InterpolatedDoublesCurve.fromSorted( nodeTimesForward, yieldsForward, new LinearInterpolator1D())); final List<DoublesPair> tempForward = pvsLongPayerExtra.getSensitivities().get(FORWARD_CURVE_NAME); final double[] resFwd = new double[nbForwardDate]; for (int i = 0; i < nbForwardDate; i++) { final YieldAndDiscountCurve bumpedCurveForward = tempCurveForward.withSingleShift(nodeTimesForward[i + 1], deltaShift); final YieldCurveBundle curvesBumpedForward = new YieldCurveBundle(); curvesBumpedForward.addAll(curves); curvesBumpedForward.setCurve("Bumped Curve", bumpedCurveForward); final SABRInterestRateDataBundle sabrBundleBumped = new SABRInterestRateDataBundle(sabrParameter, curvesBumpedForward); final double bumpedpv = methodExtra.presentValue(swaptionBumpedForward, sabrBundleBumped); resFwd[i] = (bumpedpv - pv) / deltaShift; final DoublesPair pair = tempForward.get(i); assertEquals( "Sensitivity to forward curve: Node " + i, nodeTimesForward[i + 1], pair.getFirst(), 1E-8); assertEquals( "Sensitivity to forward curve: Node " + i, resFwd[i], pair.getSecond(), deltaTolerance); } // 2. Funding curve sensitivity final String[] bumpedCurvesFundingName = {bumpedCurveName, FORWARD_CURVE_NAME}; final SwaptionCashFixedIbor swaptionBumpedFunding = swaptionDefinitionLongPayerHighStrike.toDerivative(REFERENCE_DATE, bumpedCurvesFundingName); final int nbPayDate = swaptionDefinitionLongPayerHighStrike.getUnderlyingSwap().getIborLeg().getPayments().length; final YieldAndDiscountCurve curveFunding = curves.getCurve(FUNDING_CURVE_NAME); final double[] yieldsFunding = new double[nbPayDate + 2]; final double[] nodeTimesFunding = new double[nbPayDate + 2]; yieldsFunding[0] = curveFunding.getInterestRate(0.0); nodeTimesFunding[1] = swaptionLongPayerHighStrike.getSettlementTime(); yieldsFunding[1] = curveFunding.getInterestRate(nodeTimesFunding[1]); for (int i = 0; i < nbPayDate; i++) { nodeTimesFunding[i + 2] = swaptionLongPayerHighStrike .getUnderlyingSwap() .getSecondLeg() .getNthPayment(i) .getPaymentTime(); yieldsFunding[i + 2] = curveFunding.getInterestRate(nodeTimesFunding[i + 2]); } final YieldAndDiscountCurve tempCurveFunding = new YieldCurve( InterpolatedDoublesCurve.fromSorted( nodeTimesFunding, yieldsFunding, new LinearInterpolator1D())); final List<DoublesPair> tempFunding = pvsLongPayerExtra.getSensitivities().get(FUNDING_CURVE_NAME); final double[] resDsc = new double[nbPayDate]; for (int i = 0; i < nbPayDate; i++) { final YieldAndDiscountCurve bumpedCurve = tempCurveFunding.withSingleShift(nodeTimesFunding[i + 1], deltaShift); final YieldCurveBundle curvesBumped = new YieldCurveBundle(); curvesBumped.addAll(curves); curvesBumped.setCurve("Bumped Curve", bumpedCurve); final SABRInterestRateDataBundle sabrBundleBumped = new SABRInterestRateDataBundle(sabrParameter, curvesBumped); final double bumpedpv = methodExtra.presentValue(swaptionBumpedFunding, sabrBundleBumped); resDsc[i] = (bumpedpv - pv) / deltaShift; final DoublesPair pair = tempFunding.get(i); assertEquals( "Sensitivity to discounting curve: Node " + i, nodeTimesFunding[i + 1], pair.getFirst(), 1E-8); assertEquals( "Sensitivity to discounting curve: Node " + i, resDsc[i], pair.getSecond(), deltaTolerance); } } @Test /** * Test the present value sensitivity to SABR parameters for a swaption with strike above the * cut-off strike. */ public void testPresentValueSABRSensitivity() { final YieldCurveBundle curves = TestsDataSetsSABR.createCurves1(); final SABRInterestRateParameters sabrParameter = TestsDataSetsSABR.createSABR1(); final SABRInterestRateDataBundle sabrBundle = new SABRInterestRateDataBundle(sabrParameter, curves); final double highStrike = 0.10; final SwapFixedIborDefinition swapDefinitionPayerHighStrike = SwapFixedIborDefinition.from( SETTLEMENT_DATE, CMS_INDEX, NOTIONAL, highStrike, FIXED_IS_PAYER); final SwaptionCashFixedIborDefinition swaptionDefinitionLongPayerHighStrike = SwaptionCashFixedIborDefinition.from(EXPIRY_DATE, swapDefinitionPayerHighStrike, IS_LONG); final SwaptionCashFixedIborDefinition swaptionDefinitionShortPayerHighStrike = SwaptionCashFixedIborDefinition.from(EXPIRY_DATE, swapDefinitionPayerHighStrike, !IS_LONG); final SwaptionCashFixedIbor swaptionLongPayerHighStrike = swaptionDefinitionLongPayerHighStrike.toDerivative(REFERENCE_DATE, CURVES_NAME); final SwaptionCashFixedIbor swaptionShortPayerHighStrike = swaptionDefinitionShortPayerHighStrike.toDerivative(REFERENCE_DATE, CURVES_NAME); // SwaptionCashFixedIborSABRExtrapolationRightMethod methodExtra = new // SwaptionCashFixedIborSABRExtrapolationRightMethod(CUT_OFF_STRIKE, MU); // Swaption sensitivity final PresentValueSABRSensitivityDataBundle pvsLongPayer = METHOD_EXTRAPOLATION.presentValueSABRSensitivity(swaptionLongPayerHighStrike, sabrBundle); PresentValueSABRSensitivityDataBundle pvsShortPayer = METHOD_EXTRAPOLATION.presentValueSABRSensitivity(swaptionShortPayerHighStrike, sabrBundle); // Long/short parity pvsShortPayer = PresentValueSABRSensitivityDataBundle.multiplyBy(pvsShortPayer, -1.0); assertEquals(pvsLongPayer.getAlpha(), pvsShortPayer.getAlpha()); // SABR sensitivity vs finite difference final double pvLongPayer = METHOD_EXTRAPOLATION.presentValue(swaptionLongPayerHighStrike, sabrBundle); final DoublesPair expectedExpiryTenor = new DoublesPair(swaptionLongPayerHighStrike.getTimeToExpiry(), ANNUITY_TENOR_YEAR); final double shift = 0.000005; // Alpha sensitivity vs finite difference computation final SABRInterestRateParameters sabrParameterAlphaBumped = TestsDataSetsSABR.createSABR1AlphaBumped(shift); final SABRInterestRateDataBundle sabrBundleAlphaBumped = new SABRInterestRateDataBundle(sabrParameterAlphaBumped, curves); final double pvLongPayerAlphaBumped = METHOD_EXTRAPOLATION.presentValue(swaptionLongPayerHighStrike, sabrBundleAlphaBumped); final double expectedAlphaSensi = (pvLongPayerAlphaBumped - pvLongPayer) / shift; assertEquals( "Number of alpha sensitivity", pvsLongPayer.getAlpha().getMap().keySet().size(), 1); assertEquals( "Alpha sensitivity expiry/tenor", pvsLongPayer.getAlpha().getMap().keySet().contains(expectedExpiryTenor), true); assertEquals( "Alpha sensitivity value", expectedAlphaSensi, pvsLongPayer.getAlpha().getMap().get(expectedExpiryTenor), 2.0E+3); // Rho sensitivity vs finite difference computation final SABRInterestRateParameters sabrParameterRhoBumped = TestsDataSetsSABR.createSABR1RhoBumped(shift); final SABRInterestRateDataBundle sabrBundleRhoBumped = new SABRInterestRateDataBundle(sabrParameterRhoBumped, curves); final double pvLongPayerRhoBumped = METHOD_EXTRAPOLATION.presentValue(swaptionLongPayerHighStrike, sabrBundleRhoBumped); final double expectedRhoSensi = (pvLongPayerRhoBumped - pvLongPayer) / shift; assertEquals("Number of rho sensitivity", pvsLongPayer.getRho().getMap().keySet().size(), 1); assertEquals( "Rho sensitivity expiry/tenor", pvsLongPayer.getRho().getMap().keySet().contains(expectedExpiryTenor), true); assertEquals( "Rho sensitivity value", expectedRhoSensi, pvsLongPayer.getRho().getMap().get(expectedExpiryTenor), 1.0E+0); // Alpha sensitivity vs finite difference computation final SABRInterestRateParameters sabrParameterNuBumped = TestsDataSetsSABR.createSABR1NuBumped(shift); final SABRInterestRateDataBundle sabrBundleNuBumped = new SABRInterestRateDataBundle(sabrParameterNuBumped, curves); final double pvLongPayerNuBumped = METHOD_EXTRAPOLATION.presentValue(swaptionLongPayerHighStrike, sabrBundleNuBumped); final double expectedNuSensi = (pvLongPayerNuBumped - pvLongPayer) / shift; assertEquals("Number of nu sensitivity", pvsLongPayer.getNu().getMap().keySet().size(), 1); assertEquals( "Nu sensitivity expiry/tenor", pvsLongPayer.getNu().getMap().keySet().contains(expectedExpiryTenor), true); assertEquals( "Nu sensitivity value", expectedNuSensi, pvsLongPayer.getNu().getMap().get(expectedExpiryTenor), 5.0E+1); } }
/** * 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)); } }
/** Tests the interest rate future option with margin transaction description. */ public class InterestRateFutureOptionMarginTransactionDefinitionTest { // 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 option mid-curve 1Y 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, CALENDAR, -SETTLEMENT_DAYS); 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 ZonedDateTime EXPIRATION_DATE = DateUtils.getUTCDate(2011, 9, 16); private static final double STRIKE = 0.9895; private static final boolean IS_CALL = true; private static final InterestRateFutureOptionMarginSecurityDefinition OPTION_ERU2 = new InterestRateFutureOptionMarginSecurityDefinition(ERU2, EXPIRATION_DATE, STRIKE, IS_CALL); // Transaction private static final int QUANTITY = -123; private static final ZonedDateTime TRADE_DATE = DateUtils.getUTCDate(2011, 5, 12); private static final double TRADE_PRICE = 0.0050; private static final InterestRateFutureOptionMarginTransactionDefinition OPTION_TRANSACTION = new InterestRateFutureOptionMarginTransactionDefinition( OPTION_ERU2, QUANTITY, TRADE_DATE, TRADE_PRICE); private static final ZonedDateTime REFERENCE_DATE = DateUtils.getUTCDate(2011, 5, 13); private static final String DISCOUNTING_CURVE_NAME = "Funding"; private static final String FORWARD_CURVE_NAME = "Forward"; private static final String[] CURVES_NAMES = {DISCOUNTING_CURVE_NAME, FORWARD_CURVE_NAME}; @Test(expectedExceptions = IllegalArgumentException.class) public void testNullUnderlying() { new InterestRateFutureOptionMarginTransactionDefinition( null, QUANTITY, TRADE_DATE, TRADE_PRICE); } @Test(expectedExceptions = IllegalArgumentException.class) public void testNullTradeDate() { new InterestRateFutureOptionMarginTransactionDefinition( OPTION_ERU2, QUANTITY, null, TRADE_PRICE); } @Test /** Tests the class getters. */ public void getter() { assertEquals(OPTION_ERU2, OPTION_TRANSACTION.getUnderlyingOption()); assertEquals(QUANTITY, OPTION_TRANSACTION.getQuantity()); assertEquals(TRADE_DATE, OPTION_TRANSACTION.getTradeDate()); assertEquals(TRADE_PRICE, OPTION_TRANSACTION.getTradePrice()); } @Test /** Tests the equal and hashCode methods. */ public void equalHash() { InterestRateFutureOptionMarginTransactionDefinition other = new InterestRateFutureOptionMarginTransactionDefinition( OPTION_ERU2, QUANTITY, TRADE_DATE, TRADE_PRICE); assertTrue(OPTION_TRANSACTION.equals(other)); assertTrue(OPTION_TRANSACTION.hashCode() == other.hashCode()); InterestRateFutureOptionMarginTransactionDefinition modifidOption; modifidOption = new InterestRateFutureOptionMarginTransactionDefinition( OPTION_ERU2, QUANTITY + 1, TRADE_DATE, TRADE_PRICE); assertFalse(OPTION_TRANSACTION.equals(modifidOption)); modifidOption = new InterestRateFutureOptionMarginTransactionDefinition( OPTION_ERU2, QUANTITY, LAST_TRADING_DATE, TRADE_PRICE); assertFalse(OPTION_TRANSACTION.equals(modifidOption)); modifidOption = new InterestRateFutureOptionMarginTransactionDefinition( OPTION_ERU2, QUANTITY, TRADE_DATE, TRADE_PRICE - 0.00001); assertFalse(OPTION_TRANSACTION.equals(modifidOption)); } @Test public void toDerivativeTradeInPast() { InterestRateFutureOptionMarginSecurity securityConverted = OPTION_ERU2.toDerivative(REFERENCE_DATE, CURVES_NAMES); double lastMarginPrice = 0.99; InterestRateFutureOptionMarginTransaction transactionConverted = OPTION_TRANSACTION.toDerivative(REFERENCE_DATE, lastMarginPrice, CURVES_NAMES); InterestRateFutureOptionMarginTransaction transaction = new InterestRateFutureOptionMarginTransaction(securityConverted, QUANTITY, lastMarginPrice); assertTrue("Conversion with trade date in the past", transactionConverted.equals(transaction)); } @Test public void toDerivativeTradeToday() { ZonedDateTime referenceDate = TRADE_DATE; InterestRateFutureOptionMarginSecurity securityConverted = OPTION_ERU2.toDerivative(referenceDate, CURVES_NAMES); double lastMarginPrice = 0.99; InterestRateFutureOptionMarginTransaction transactionConverted = OPTION_TRANSACTION.toDerivative(referenceDate, lastMarginPrice, CURVES_NAMES); InterestRateFutureOptionMarginTransaction transaction = new InterestRateFutureOptionMarginTransaction(securityConverted, QUANTITY, TRADE_PRICE); assertTrue("Conversion with trade date in the past", transactionConverted.equals(transaction)); } @Test(expectedExceptions = IllegalArgumentException.class) public void toDerivativeTradeFuture() { ZonedDateTime referenceDate = ScheduleCalculator.getAdjustedDate(TRADE_DATE, CALENDAR, -1); double lastMarginPrice = 0.99; OPTION_TRANSACTION.toDerivative(referenceDate, lastMarginPrice, CURVES_NAMES); } }
@Test(expectedExceptions = IllegalArgumentException.class) public void toDerivativeTradeFuture() { ZonedDateTime referenceDate = ScheduleCalculator.getAdjustedDate(TRADE_DATE, CALENDAR, -1); double lastMarginPrice = 0.99; OPTION_TRANSACTION.toDerivative(referenceDate, lastMarginPrice, CURVES_NAMES); }
/** Tests the CouponIborRatchet constructor. */ public class CouponIborRatchetTest { private static final Currency CUR = Currency.EUR; private static final Calendar CALENDAR = new MondayToFridayCalendar("A"); private static final Period TENOR_IBOR = Period.ofMonths(3); private static final int SETTLEMENT_DAYS = 2; 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 IborIndex INDEX_IBOR = new IborIndex( CUR, TENOR_IBOR, SETTLEMENT_DAYS, CALENDAR, DAY_COUNT_INDEX, BUSINESS_DAY, IS_EOM); private static final ZonedDateTime FIXING_DATE = DateUtils.getUTCDate(2014, 9, 5); private static final ZonedDateTime ACCRUAL_START_DATE = ScheduleCalculator.getAdjustedDate(FIXING_DATE, CALENDAR, SETTLEMENT_DAYS); private static final ZonedDateTime ACCRUAL_END_DATE = ScheduleCalculator.getAdjustedDate( ACCRUAL_START_DATE, BUSINESS_DAY, CALENDAR, IS_EOM, TENOR_IBOR); private static final ZonedDateTime PAYMENT_DATE = ACCRUAL_END_DATE; private static final DayCount DAY_COUNT_PAYMENT = DayCountFactory.INSTANCE.getDayCount("Actual/365"); private static final double ACCRUAL_FACTOR = DAY_COUNT_PAYMENT.getDayCountFraction(ACCRUAL_START_DATE, ACCRUAL_END_DATE); private static final double[] MAIN_COEF = new double[] {0.4, 0.5, 0.0010}; private static final double[] FLOOR_COEF = new double[] {0.75, 0.00, 0.00}; private static final double[] CAP_COEF = new double[] {1.50, 1.00, 0.0050}; private static final double NOTIONAL = 1000000; // 1m private static final CouponIborRatchetDefinition RATCHET_IBOR_DEFINITION = new CouponIborRatchetDefinition( CUR, PAYMENT_DATE, ACCRUAL_START_DATE, ACCRUAL_END_DATE, ACCRUAL_FACTOR, NOTIONAL, FIXING_DATE, INDEX_IBOR, MAIN_COEF, FLOOR_COEF, CAP_COEF); private static final ZonedDateTime REFERENCE_DATE = DateUtils.getUTCDate(2011, 9, 5); private static final String DISCOUNTING_CURVE_NAME = "Discounting"; private static final String FORWARD_CURVE_NAME = "Forward"; private static final String[] CURVES = {DISCOUNTING_CURVE_NAME, FORWARD_CURVE_NAME}; private static final CouponIborRatchet RATCHET_IBOR = RATCHET_IBOR_DEFINITION.toDerivative(REFERENCE_DATE, CURVES); @Test(expectedExceptions = IllegalArgumentException.class) public void nullindex() { new CouponIborRatchet( CUR, RATCHET_IBOR.getPaymentTime(), DISCOUNTING_CURVE_NAME, RATCHET_IBOR.getPaymentYearFraction(), NOTIONAL, RATCHET_IBOR.getFixingTime(), RATCHET_IBOR.getFixingPeriodStartTime(), RATCHET_IBOR.getFixingPeriodEndTime(), RATCHET_IBOR.getFixingYearFraction(), FORWARD_CURVE_NAME, null, MAIN_COEF, FLOOR_COEF, CAP_COEF); } @Test(expectedExceptions = IllegalArgumentException.class) public void nullMain() { new CouponIborRatchet( CUR, RATCHET_IBOR.getPaymentTime(), DISCOUNTING_CURVE_NAME, RATCHET_IBOR.getPaymentYearFraction(), NOTIONAL, RATCHET_IBOR.getFixingTime(), RATCHET_IBOR.getFixingPeriodStartTime(), RATCHET_IBOR.getFixingPeriodEndTime(), RATCHET_IBOR.getFixingYearFraction(), FORWARD_CURVE_NAME, INDEX_IBOR, null, FLOOR_COEF, CAP_COEF); } @Test(expectedExceptions = IllegalArgumentException.class) public void nullFloor() { new CouponIborRatchet( CUR, RATCHET_IBOR.getPaymentTime(), DISCOUNTING_CURVE_NAME, RATCHET_IBOR.getPaymentYearFraction(), NOTIONAL, RATCHET_IBOR.getFixingTime(), RATCHET_IBOR.getFixingPeriodStartTime(), RATCHET_IBOR.getFixingPeriodEndTime(), RATCHET_IBOR.getFixingYearFraction(), FORWARD_CURVE_NAME, INDEX_IBOR, MAIN_COEF, null, CAP_COEF); } @Test(expectedExceptions = IllegalArgumentException.class) public void nullCap() { new CouponIborRatchet( CUR, RATCHET_IBOR.getPaymentTime(), DISCOUNTING_CURVE_NAME, RATCHET_IBOR.getPaymentYearFraction(), NOTIONAL, RATCHET_IBOR.getFixingTime(), RATCHET_IBOR.getFixingPeriodStartTime(), RATCHET_IBOR.getFixingPeriodEndTime(), RATCHET_IBOR.getFixingYearFraction(), FORWARD_CURVE_NAME, INDEX_IBOR, MAIN_COEF, FLOOR_COEF, null); } @Test(expectedExceptions = IllegalArgumentException.class) public void numberMain() { new CouponIborRatchet( CUR, RATCHET_IBOR.getPaymentTime(), DISCOUNTING_CURVE_NAME, RATCHET_IBOR.getPaymentYearFraction(), NOTIONAL, RATCHET_IBOR.getFixingTime(), RATCHET_IBOR.getFixingPeriodStartTime(), RATCHET_IBOR.getFixingPeriodEndTime(), RATCHET_IBOR.getFixingYearFraction(), FORWARD_CURVE_NAME, INDEX_IBOR, new double[2], FLOOR_COEF, CAP_COEF); } @Test(expectedExceptions = IllegalArgumentException.class) public void numberFloor() { new CouponIborRatchet( CUR, RATCHET_IBOR.getPaymentTime(), DISCOUNTING_CURVE_NAME, RATCHET_IBOR.getPaymentYearFraction(), NOTIONAL, RATCHET_IBOR.getFixingTime(), RATCHET_IBOR.getFixingPeriodStartTime(), RATCHET_IBOR.getFixingPeriodEndTime(), RATCHET_IBOR.getFixingYearFraction(), FORWARD_CURVE_NAME, INDEX_IBOR, MAIN_COEF, new double[2], CAP_COEF); } @Test(expectedExceptions = IllegalArgumentException.class) public void numberCap() { new CouponIborRatchet( CUR, RATCHET_IBOR.getPaymentTime(), DISCOUNTING_CURVE_NAME, RATCHET_IBOR.getPaymentYearFraction(), NOTIONAL, RATCHET_IBOR.getFixingTime(), RATCHET_IBOR.getFixingPeriodStartTime(), RATCHET_IBOR.getFixingPeriodEndTime(), RATCHET_IBOR.getFixingYearFraction(), FORWARD_CURVE_NAME, INDEX_IBOR, MAIN_COEF, FLOOR_COEF, new double[2]); } @Test public void getter() { assertEquals("Ratchet Ibor Coupon: getter", MAIN_COEF, RATCHET_IBOR.getMainCoefficients()); assertEquals("Ratchet Ibor Coupon: getter", FLOOR_COEF, RATCHET_IBOR.getFloorCoefficients()); assertEquals("Ratchet Ibor Coupon: getter", CAP_COEF, RATCHET_IBOR.getCapCoefficients()); } @Test public void testEqualHash() { assertEquals("Ratchet Ibor Coupon: equal/hash", RATCHET_IBOR, RATCHET_IBOR); CouponIborRatchet other = new CouponIborRatchet( CUR, RATCHET_IBOR.getPaymentTime(), DISCOUNTING_CURVE_NAME, RATCHET_IBOR.getPaymentYearFraction(), NOTIONAL, RATCHET_IBOR.getFixingTime(), RATCHET_IBOR.getFixingPeriodStartTime(), RATCHET_IBOR.getFixingPeriodEndTime(), RATCHET_IBOR.getFixingYearFraction(), FORWARD_CURVE_NAME, INDEX_IBOR, MAIN_COEF, FLOOR_COEF, CAP_COEF); assertEquals("Ratchet Ibor Coupon: equal/hash", RATCHET_IBOR, other); assertEquals("Ratchet Ibor Coupon: equal/hash", RATCHET_IBOR.hashCode(), other.hashCode()); CouponIborRatchet modified; modified = new CouponIborRatchet( CUR, RATCHET_IBOR.getPaymentTime(), DISCOUNTING_CURVE_NAME, RATCHET_IBOR.getPaymentYearFraction(), NOTIONAL, RATCHET_IBOR.getFixingTime(), RATCHET_IBOR.getFixingPeriodStartTime(), RATCHET_IBOR.getFixingPeriodEndTime(), RATCHET_IBOR.getFixingYearFraction(), FORWARD_CURVE_NAME, INDEX_IBOR, new double[3], FLOOR_COEF, CAP_COEF); assertFalse("Ratchet Ibor Coupon: equal/hash", RATCHET_IBOR_DEFINITION.equals(modified)); modified = new CouponIborRatchet( CUR, RATCHET_IBOR.getPaymentTime(), DISCOUNTING_CURVE_NAME, RATCHET_IBOR.getPaymentYearFraction(), NOTIONAL, RATCHET_IBOR.getFixingTime(), RATCHET_IBOR.getFixingPeriodStartTime(), RATCHET_IBOR.getFixingPeriodEndTime(), RATCHET_IBOR.getFixingYearFraction(), FORWARD_CURVE_NAME, INDEX_IBOR, MAIN_COEF, new double[3], CAP_COEF); assertFalse("Ratchet Ibor Coupon: equal/hash", RATCHET_IBOR_DEFINITION.equals(modified)); modified = new CouponIborRatchet( CUR, RATCHET_IBOR.getPaymentTime(), DISCOUNTING_CURVE_NAME, RATCHET_IBOR.getPaymentYearFraction(), NOTIONAL, RATCHET_IBOR.getFixingTime(), RATCHET_IBOR.getFixingPeriodStartTime(), RATCHET_IBOR.getFixingPeriodEndTime(), RATCHET_IBOR.getFixingYearFraction(), FORWARD_CURVE_NAME, INDEX_IBOR, MAIN_COEF, FLOOR_COEF, new double[3]); assertFalse("Ratchet Ibor Coupon: equal/hash", RATCHET_IBOR_DEFINITION.equals(modified)); } }