/** * Resolves this schedule using the specified reference data. * <p> * Calling this method binds the reference data and roll convention, returning a * function that can convert a {@code SchedulePeriod} to an {@code FxReset}. * <p> * The reset schedule is created within the bounds of the specified accrual period. * The reset frequency is added repeatedly to the unadjusted start date of the period * in order to generate the schedule, potentially leaving a short final stub. * The dates are adjusted using the specified roll convention and the business * day adjustment of this class. * * @param rollConvention the applicable roll convention * @param refData the reference data to use when resolving * @return the reset schedule * @throws ReferenceDataNotFoundException if an identifier cannot be resolved in the reference data * @throws RuntimeException if the schedule is invalid */ Function<SchedulePeriod, Schedule> createSchedule(RollConvention rollConvention, ReferenceData refData) { return accrualPeriod -> accrualPeriod.subSchedule( resetFrequency, rollConvention, StubConvention.SHORT_FINAL, businessDayAdjustment).createSchedule(refData); }
/** * Converts this swap leg to the equivalent {@code ResolvedSwapLeg}. * <p> * An {@link ResolvedSwapLeg} represents the same data as this leg, but with * a complete schedule of dates defined using {@link KnownAmountSwapPaymentPeriod}. * * @param refData the reference data to use when resolving * @return the equivalent resolved swap leg * @throws ReferenceDataNotFoundException if an identifier cannot be resolved in the reference data * @throws RuntimeException if unable to resolve due to an invalid swap schedule or definition */ @Override public ResolvedSwapLeg resolve(ReferenceData refData) { Schedule resolvedAccruals = accrualSchedule.createSchedule(refData); Schedule resolvedPayments = paymentSchedule.createSchedule(resolvedAccruals, refData); List<SwapPaymentPeriod> payPeriods = createPaymentPeriods(resolvedPayments, refData); return new ResolvedSwapLeg(getType(), payReceive, payPeriods, ImmutableList.of(), currency); }
public void test_accruedInterest_exCoupon_out() { LocalDate refDate = LocalDate.of(2014, 6, 10); CapitalIndexedBondPaymentPeriod period = PRODUCT_EX_COUPON.getPeriodicPayments().get(16); double computed = PRODUCT_EX_COUPON.accruedInterest(refDate); Schedule sch = SCHEDULE.createSchedule(REF_DATA).toUnadjusted(); double factor = ACT_ACT_ICMA.relativeYearFraction(period.getUnadjustedStartDate(), refDate, sch); assertEquals(computed, factor * REAL_COUPON_VALUE * NOTIONAL * 2d, TOL * REAL_COUPON_VALUE * NOTIONAL); }
public void test_accruedInterest() { LocalDate refDate = LocalDate.of(2014, 6, 10); double computed = PRODUCT.accruedInterest(refDate); Schedule sch = SCHEDULE.createSchedule(REF_DATA).toUnadjusted(); CapitalIndexedBondPaymentPeriod period = PRODUCT.getPeriodicPayments().get(16); double factor = ACT_ACT_ICMA.relativeYearFraction(period.getUnadjustedStartDate(), refDate, sch); assertEquals(computed, factor * REAL_COUPON_VALUE * NOTIONAL * 2d, TOL * REAL_COUPON_VALUE * NOTIONAL); }
public void test_subSchedule_3monthIn3Month() { SchedulePeriod test = SchedulePeriod.of(JUN_17, SEP_17); Schedule schedule = test.subSchedule(P3M, RollConventions.DAY_17, StubConvention.NONE, BusinessDayAdjustment.NONE) .createSchedule(REF_DATA); assertEquals(schedule.size(), 1); assertEquals(schedule.getPeriod(0), SchedulePeriod.of(JUN_17, SEP_17)); }
public void test_subSchedule_2monthIn3Month_shortInitial() { SchedulePeriod test = SchedulePeriod.of(JUN_17, SEP_17); Schedule schedule = test.subSchedule(P2M, RollConventions.DAY_17, StubConvention.SHORT_INITIAL, BusinessDayAdjustment.NONE) .createSchedule(REF_DATA); assertEquals(schedule.size(), 2); assertEquals(schedule.getPeriod(0), SchedulePeriod.of(JUN_17, JUL_17)); assertEquals(schedule.getPeriod(1), SchedulePeriod.of(JUL_17, SEP_17)); assertEquals(schedule.getFrequency(), P2M); assertEquals(schedule.getRollConvention(), RollConventions.DAY_17); }
public void test_subSchedule_2monthIn3Month_shortFinal() { SchedulePeriod test = SchedulePeriod.of(JUN_17, SEP_17); Schedule schedule = test.subSchedule(P2M, RollConventions.DAY_17, StubConvention.SHORT_FINAL, BusinessDayAdjustment.NONE) .createSchedule(REF_DATA); assertEquals(schedule.size(), 2); assertEquals(schedule.getPeriod(0), SchedulePeriod.of(JUN_17, AUG_17)); assertEquals(schedule.getPeriod(1), SchedulePeriod.of(AUG_17, SEP_17)); assertEquals(schedule.getFrequency(), P2M); assertEquals(schedule.getRollConvention(), RollConventions.DAY_17); }
public void test_subSchedule_1monthIn3Month() { SchedulePeriod test = SchedulePeriod.of(JUN_17, SEP_17); Schedule schedule = test.subSchedule(P1M, RollConventions.DAY_17, StubConvention.NONE, BusinessDayAdjustment.NONE) .createSchedule(REF_DATA); assertEquals(schedule.size(), 3); assertEquals(schedule.getPeriod(0), SchedulePeriod.of(JUN_17, JUL_17)); assertEquals(schedule.getPeriod(1), SchedulePeriod.of(JUL_17, AUG_17)); assertEquals(schedule.getPeriod(2), SchedulePeriod.of(AUG_17, SEP_17)); assertEquals(schedule.getFrequency(), P1M); assertEquals(schedule.getRollConvention(), RollConventions.DAY_17); }
/** * Converts this swap leg to the equivalent {@code ResolvedSwapLeg}. * <p> * An {@link ResolvedSwapLeg} represents the same data as this leg, but with * a complete schedule of dates defined using {@link RatePaymentPeriod}. * * @return the equivalent resolved swap leg * @throws ReferenceDataNotFoundException if an identifier cannot be resolved in the reference data * @throws RuntimeException if unable to resolve due to an invalid swap schedule or definition */ @Override public ResolvedSwapLeg resolve(ReferenceData refData) { DayCount dayCount = calculation.getDayCount(); Schedule resolvedAccruals = accrualSchedule.createSchedule(refData); Schedule resolvedPayments = paymentSchedule.createSchedule(resolvedAccruals, refData); List<RateAccrualPeriod> accrualPeriods = calculation.createAccrualPeriods(resolvedAccruals, resolvedPayments, refData); List<NotionalPaymentPeriod> payPeriods = paymentSchedule.createPaymentPeriods( resolvedAccruals, resolvedPayments, accrualPeriods, dayCount, notionalSchedule, payReceive, refData); LocalDate startDate = accrualPeriods.get(0).getStartDate(); ImmutableList<SwapPaymentEvent> payEvents = notionalSchedule.createEvents(payPeriods, startDate, refData); return new ResolvedSwapLeg(getType(), payReceive, payPeriods, payEvents, getCurrency()); }
public void test_dirtyPriceFromStandardYield() { double yield = 0.0175; LocalDate standardSettle = SETTLE_OFFSET.adjust(VALUATION, REF_DATA); double computed = PRICER.dirtyPriceFromStandardYield(PRODUCT, RATES_PROVIDER, standardSettle, yield); Schedule sch = SCHEDULE.createSchedule(REF_DATA).toUnadjusted(); CapitalIndexedBondPaymentPeriod period = PRODUCT.getPeriodicPayments().get(16); double factorPeriod = ACT_ACT_ICMA.relativeYearFraction(period.getUnadjustedStartDate(), period.getUnadjustedEndDate(), sch); double factorSpot = ACT_ACT_ICMA.relativeYearFraction(period.getUnadjustedStartDate(), standardSettle, sch); double factorToNext = (factorPeriod - factorSpot) / factorPeriod; double dscFactor = 1d / (1d + 0.5 * yield); double expected = Math.pow(dscFactor, 3); for (int i = 0; i < 4; ++i) { expected += REAL_COUPON_VALUE * Math.pow(dscFactor, i); } expected *= Math.pow(dscFactor, factorToNext); assertEquals(computed, expected, TOL); }
public void test_accruedInterest_exCoupon_in() { CapitalIndexedBondPaymentPeriod period = PRODUCT_EX_COUPON.getPeriodicPayments().get(16); LocalDate refDate = period.getDetachmentDate(); double computed = PRODUCT_EX_COUPON.accruedInterest(refDate); Schedule sch = SCHEDULE.createSchedule(REF_DATA).toUnadjusted(); double factor = ACT_ACT_ICMA.relativeYearFraction(period.getUnadjustedStartDate(), refDate, sch); double factorTotal = ACT_ACT_ICMA.relativeYearFraction(period.getUnadjustedStartDate(), period.getUnadjustedEndDate(), sch); assertEquals(computed, (factor - factorTotal) * REAL_COUPON_VALUE * NOTIONAL * 2d, TOL * REAL_COUPON_VALUE * NOTIONAL); }
.lastRegularEndDate(lastReg) .build(); Schedule test = defn.createSchedule(REF_DATA); assertEquals(test.size(), unadjusted.size() - 1); for (int i = 0; i < test.size(); i++) {
public void test_resolve() { FixedCouponBond base = sut(); ResolvedFixedCouponBond resolved = base.resolve(REF_DATA); assertEquals(resolved.getLegalEntityId(), LEGAL_ENTITY); assertEquals(resolved.getSettlementDateOffset(), DATE_OFFSET); assertEquals(resolved.getYieldConvention(), YIELD_CONVENTION); ImmutableList<FixedCouponBondPaymentPeriod> periodicPayments = resolved.getPeriodicPayments(); int expNum = 20; assertEquals(periodicPayments.size(), expNum); LocalDate unadjustedEnd = END_DATE; Schedule unadjusted = PERIOD_SCHEDULE.createSchedule(REF_DATA).toUnadjusted(); for (int i = 0; i < expNum; ++i) { FixedCouponBondPaymentPeriod payment = periodicPayments.get(expNum - 1 - i); assertEquals(payment.getCurrency(), EUR); assertEquals(payment.getNotional(), NOTIONAL); assertEquals(payment.getFixedRate(), FIXED_RATE); assertEquals(payment.getUnadjustedEndDate(), unadjustedEnd); assertEquals(payment.getEndDate(), BUSINESS_ADJUST.adjust(unadjustedEnd, REF_DATA)); assertEquals(payment.getPaymentDate(), payment.getEndDate()); LocalDate unadjustedStart = unadjustedEnd.minusMonths(6); assertEquals(payment.getUnadjustedStartDate(), unadjustedStart); assertEquals(payment.getStartDate(), BUSINESS_ADJUST.adjust(unadjustedStart, REF_DATA)); assertEquals(payment.getYearFraction(), unadjusted.getPeriod(expNum - 1 - i).yearFraction(DAY_COUNT, unadjusted)); assertEquals(payment.getDetachmentDate(), EX_COUPON.adjust(payment.getPaymentDate(), REF_DATA)); unadjustedEnd = unadjustedStart; } Payment expectedPayment = Payment.of(CurrencyAmount.of(EUR, NOTIONAL), BUSINESS_ADJUST.adjust(END_DATE, REF_DATA)); assertEquals(resolved.getNominalPayment(), expectedPayment); }
.build(); Schedule schedule = scheduleDefinition.createSchedule(REF_DATA); assertEquals(schedule.size(), 5);
public void test_override_fallbackWhenStartDateMismatch() { PeriodicSchedule defn = PeriodicSchedule.builder() .startDate(JUL_04) .endDate(SEP_17) .overrideStartDate(AdjustableDate.of(JUN_17, BusinessDayAdjustment.of(FOLLOWING, SAT_SUN))) .frequency(P1M) .businessDayAdjustment(BDA) .rollConvention(DAY_17) .build(); Schedule test = defn.createSchedule(REF_DATA); assertEquals(test.size(), 3); SchedulePeriod period0 = test.getPeriod(0); assertEquals(period0.getUnadjustedStartDate(), JUN_17); assertEquals(period0.getUnadjustedEndDate(), JUL_17); assertEquals(period0.getStartDate(), JUN_17); assertEquals(period0.getEndDate(), JUL_17); SchedulePeriod period1 = test.getPeriod(1); assertEquals(period1.getUnadjustedStartDate(), JUL_17); assertEquals(period1.getUnadjustedEndDate(), AUG_17); assertEquals(period1.getStartDate(), JUL_17); assertEquals(period1.getEndDate(), AUG_18); SchedulePeriod period2 = test.getPeriod(2); assertEquals(period2.getUnadjustedStartDate(), AUG_17); assertEquals(period2.getUnadjustedEndDate(), SEP_17); assertEquals(period2.getStartDate(), AUG_18); assertEquals(period2.getEndDate(), SEP_17); }
public void test_override_fallbackWhenStartDateMismatchEndStub() { PeriodicSchedule defn = PeriodicSchedule.builder() .startDate(JUL_04) .endDate(SEP_04) .overrideStartDate(AdjustableDate.of(JUN_17, BusinessDayAdjustment.of(FOLLOWING, SAT_SUN))) .frequency(P1M) .businessDayAdjustment(BDA) .rollConvention(DAY_17) .lastRegularEndDate(AUG_17) .build(); Schedule test = defn.createSchedule(REF_DATA); assertEquals(test.size(), 3); SchedulePeriod period0 = test.getPeriod(0); assertEquals(period0.getUnadjustedStartDate(), JUN_17); assertEquals(period0.getUnadjustedEndDate(), JUL_17); assertEquals(period0.getStartDate(), JUN_17); assertEquals(period0.getEndDate(), JUL_17); SchedulePeriod period1 = test.getPeriod(1); assertEquals(period1.getUnadjustedStartDate(), JUL_17); assertEquals(period1.getUnadjustedEndDate(), AUG_17); assertEquals(period1.getStartDate(), JUL_17); assertEquals(period1.getEndDate(), AUG_18); SchedulePeriod period2 = test.getPeriod(2); assertEquals(period2.getUnadjustedStartDate(), AUG_17); assertEquals(period2.getUnadjustedEndDate(), SEP_04); assertEquals(period2.getStartDate(), AUG_18); assertEquals(period2.getEndDate(), SEP_04); }
@Override public ResolvedFixedCouponBond resolve(ReferenceData refData) { Schedule adjustedSchedule = accrualSchedule.createSchedule(refData); Schedule unadjustedSchedule = adjustedSchedule.toUnadjusted(); DateAdjuster exCouponPeriodAdjuster = exCouponPeriod.resolve(refData);
@Test(expectedExceptions = ScheduleException.class, expectedExceptionsMessageRegExp = ".*duplicate adjusted dates.*") public void test_emptyWhenAdjusted_term_createSchedule() { PeriodicSchedule defn = PeriodicSchedule.builder() .startDate(date(2015, 5, 29)) .endDate(date(2015, 5, 31)) .frequency(TERM) .businessDayAdjustment(BDA) .stubConvention(null) .rollConvention(null) .firstRegularStartDate(null) .lastRegularEndDate(null) .build(); defn.createSchedule(REF_DATA); }
@Test(expectedExceptions = ScheduleException.class, expectedExceptionsMessageRegExp = ".*duplicate adjusted dates.*") public void test_emptyWhenAdjusted_twoPeriods_createSchedule() { PeriodicSchedule defn = PeriodicSchedule.builder() .startDate(date(2015, 5, 27)) .endDate(date(2015, 5, 31)) .frequency(Frequency.ofDays(2)) .businessDayAdjustment(BDA) .stubConvention(STUB_NONE) .rollConvention(null) .firstRegularStartDate(null) .lastRegularEndDate(null) .build(); defn.createSchedule(REF_DATA); }
@Test( expectedExceptions = ScheduleException.class, expectedExceptionsMessageRegExp = "Schedule calculation resulted in invalid period") public void test_brokenWhenAdjusted_twoPeriods_createSchedule() { // generate unadjusted dates that are sorted (Wed, then Fri, then Sun) // use weird BusinessDayConvention to move Sunday back to Thursday // result is adjusted dates that are not sorted (Wed, then Fri, then Thu) PeriodicSchedule defn = PeriodicSchedule.builder() .startDate(date(2015, 5, 27)) .endDate(date(2015, 5, 31)) .frequency(Frequency.ofDays(2)) .businessDayAdjustment(BusinessDayAdjustment.of(new BusinessDayConvention() { @Override public String getName() { return "TestBack3OnSun"; } @Override public LocalDate adjust(LocalDate date, HolidayCalendar calendar) { return (date.getDayOfWeek() == SUNDAY ? date.minusDays(3) : date); } }, NO_HOLIDAYS)) .stubConvention(STUB_NONE) .rollConvention(null) .firstRegularStartDate(null) .lastRegularEndDate(null) .build(); defn.createSchedule(REF_DATA); }