From 3a7f76a0a24838105470ec13b4b35b7a39575694 Mon Sep 17 00:00:00 2001 From: lfathimakn <141994361+lfathimakn@users.noreply.github.com> Date: Sun, 17 Sep 2023 12:56:05 +0530 Subject: [PATCH 1/4] Fix for duplicate dates removal if combinePeriodsIfNecessary is set to true --- .../com/opengamma/strata/basics/schedule/PeriodicSchedule.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/basics/src/main/java/com/opengamma/strata/basics/schedule/PeriodicSchedule.java b/modules/basics/src/main/java/com/opengamma/strata/basics/schedule/PeriodicSchedule.java index c49d6dcb62..f798bf5ead 100644 --- a/modules/basics/src/main/java/com/opengamma/strata/basics/schedule/PeriodicSchedule.java +++ b/modules/basics/src/main/java/com/opengamma/strata/basics/schedule/PeriodicSchedule.java @@ -454,7 +454,7 @@ public Schedule createSchedule(ReferenceData refData, boolean combinePeriodsIfNe adj = new ArrayList<>(adj); unadj = new ArrayList<>(unadj); for (int i = 0; i < adj.size() - 1; i++) { - if (adj.get(i).equals(adj.get(i + 1))) { + while (i < adj.size() - 1 && adj.get(i).equals(adj.get(i + 1))) { adj.remove(i); unadj.remove(i); } From b60b3e50dc767c76f33e60106c7b242be4a30dcb Mon Sep 17 00:00:00 2001 From: lfathimakn <141994361+lfathimakn@users.noreply.github.com> Date: Sun, 17 Sep 2023 12:57:51 +0530 Subject: [PATCH 2/4] Test case for fixing duplicate dates removal if combinePeriodsIfNecessary is set to true Test case for fixing duplicate dates removal if combinePeriodsIfNecessary is set to true --- .../basics/schedule/PeriodicScheduleTest.java | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/modules/basics/src/test/java/com/opengamma/strata/basics/schedule/PeriodicScheduleTest.java b/modules/basics/src/test/java/com/opengamma/strata/basics/schedule/PeriodicScheduleTest.java index 53fbe9140d..76e864dba7 100644 --- a/modules/basics/src/test/java/com/opengamma/strata/basics/schedule/PeriodicScheduleTest.java +++ b/modules/basics/src/test/java/com/opengamma/strata/basics/schedule/PeriodicScheduleTest.java @@ -13,6 +13,7 @@ import static com.opengamma.strata.basics.date.HolidayCalendarIds.NO_HOLIDAYS; import static com.opengamma.strata.basics.date.HolidayCalendarIds.SAT_SUN; import static com.opengamma.strata.basics.schedule.Frequency.P12M; +import static com.opengamma.strata.basics.schedule.Frequency.P1D; import static com.opengamma.strata.basics.schedule.Frequency.P1M; import static com.opengamma.strata.basics.schedule.Frequency.P1W; import static com.opengamma.strata.basics.schedule.Frequency.P2M; @@ -73,6 +74,7 @@ import com.opengamma.strata.basics.date.BusinessDayConvention; import com.opengamma.strata.basics.date.HolidayCalendar; import com.opengamma.strata.basics.date.HolidayCalendarId; +import com.opengamma.strata.basics.date.HolidayCalendarIds; import com.opengamma.strata.basics.date.HolidayCalendars; /** @@ -1208,6 +1210,49 @@ public HolidayCalendarId getId() { assertThat(schedule.getPeriod(2).getStartDate()).isEqualTo(date(2020, 10, 9)); } + @Test + public void test_combinePeriodsWhenNecessary_1d_createSchedule_duplicate_exception() { + HolidayCalendarId id = SAT_SUN; + HolidayCalendar calendar = HolidayCalendars.SAT_SUN; + + ReferenceData referenceData = ImmutableReferenceData.of(id, calendar); + BusinessDayAdjustment businessDayAdjustment = BusinessDayAdjustment.of(MODIFIED_FOLLOWING, id); + PeriodicSchedule defn = PeriodicSchedule.builder() + .startDate(date(2020, 9, 18)) + .endDate(date(2020, 12, 18)) + .frequency(P1D) + .businessDayAdjustment(businessDayAdjustment) + .stubConvention(SHORT_FINAL) + .rollConvention(null) + .build(); + + Schedule schedule = defn.createSchedule(referenceData, true); + assertThat(schedule.getPeriods()).hasSize(65); + assertThat(schedule.getPeriod(0).getStartDate()).isEqualTo(date(2020, 9, 18)); + assertThat(schedule.getPeriod(0).getEndDate()).isEqualTo(date(2020, 9, 21)); + } + + @Test + public void test_combinePeriodsWhenNecessary_1d_createSchedule() { + HolidayCalendarId id = SAT_SUN; + HolidayCalendar calendar = HolidayCalendars.SAT_SUN; + + ReferenceData referenceData = ImmutableReferenceData.of(id, calendar); + BusinessDayAdjustment businessDayAdjustment = BusinessDayAdjustment.of(MODIFIED_FOLLOWING, id); + PeriodicSchedule defn = PeriodicSchedule.builder() + .startDate(date(2020, 9, 18)) + .endDate(date(2020, 12, 18)) + .frequency(P1D) + .businessDayAdjustment(businessDayAdjustment) + .stubConvention(SHORT_FINAL) + .rollConvention(null) + .build(); + + assertThatExceptionOfType(ScheduleException.class) + .isThrownBy(() -> defn.createSchedule(referenceData, false)) + .withMessageMatching(".*duplicate adjusted dates.*"); + } + @Test public void test_emptyWhenAdjusted_twoPeriods_createUnadjustedDates() { PeriodicSchedule defn = PeriodicSchedule.builder() From 84aabd2e088f7ef62570744440af637fc72259e4 Mon Sep 17 00:00:00 2001 From: lfathimakn <141994361+lfathimakn@users.noreply.github.com> Date: Sun, 17 Sep 2023 13:01:15 +0530 Subject: [PATCH 3/4] Fix for duplicate dates removal if combinePeriodsIfNecessary is set to true Fix for duplicate dates removal if combinePeriodsIfNecessary is set to true --- .../strata/product/bond/FixedCouponBond.java | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/modules/product/src/main/java/com/opengamma/strata/product/bond/FixedCouponBond.java b/modules/product/src/main/java/com/opengamma/strata/product/bond/FixedCouponBond.java index 7ee1c591b7..ddb6d4a766 100644 --- a/modules/product/src/main/java/com/opengamma/strata/product/bond/FixedCouponBond.java +++ b/modules/product/src/main/java/com/opengamma/strata/product/bond/FixedCouponBond.java @@ -161,10 +161,28 @@ private void validate() { "The ex-coupon period is measured from the payment date, thus the days must be non-positive"); } - //------------------------------------------------------------------------- + /** + * Resolves fixed coupon bond using specified reference data. + * @param refData the reference data to use when resolving + * @return the resolved instance + * @throws ReferenceDataNotFoundException if an identifier cannot be resolved in the reference data + * @throws RuntimeException if unable to resolve due to an invalid definition + */ @Override public ResolvedFixedCouponBond resolve(ReferenceData refData) { - Schedule adjustedSchedule = accrualSchedule.createSchedule(refData); + return resolve(refData, false); + } + + /** + * Resolves fixed coupon bond using specified reference data. + * @param refData the reference data to use when resolving + * @param combinePeriodsIfNecessary flag to indicate that duplicate periods can be combined + * @return the resolved instance + * @throws ReferenceDataNotFoundException if an identifier cannot be resolved in the reference data + * @throws RuntimeException if unable to resolve due to an invalid definition + */ + public ResolvedFixedCouponBond resolve(ReferenceData refData, boolean combinePeriodsIfNecessary) { + Schedule adjustedSchedule = accrualSchedule.createSchedule(refData, combinePeriodsIfNecessary); Schedule unadjustedSchedule = adjustedSchedule.toUnadjusted(); DateAdjuster exCouponPeriodAdjuster = exCouponPeriod.resolve(refData); From 695c5378dcd2c59433f41b2f6b616949b69b28f3 Mon Sep 17 00:00:00 2001 From: lfathimakn <141994361+lfathimakn@users.noreply.github.com> Date: Sun, 8 Oct 2023 21:11:17 +0530 Subject: [PATCH 4/4] Update FixedCouponBond.java Update FixedCouponBond to combine periods always --- .../strata/product/bond/FixedCouponBond.java | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/modules/product/src/main/java/com/opengamma/strata/product/bond/FixedCouponBond.java b/modules/product/src/main/java/com/opengamma/strata/product/bond/FixedCouponBond.java index ddb6d4a766..6199d8f423 100644 --- a/modules/product/src/main/java/com/opengamma/strata/product/bond/FixedCouponBond.java +++ b/modules/product/src/main/java/com/opengamma/strata/product/bond/FixedCouponBond.java @@ -170,19 +170,7 @@ private void validate() { */ @Override public ResolvedFixedCouponBond resolve(ReferenceData refData) { - return resolve(refData, false); - } - - /** - * Resolves fixed coupon bond using specified reference data. - * @param refData the reference data to use when resolving - * @param combinePeriodsIfNecessary flag to indicate that duplicate periods can be combined - * @return the resolved instance - * @throws ReferenceDataNotFoundException if an identifier cannot be resolved in the reference data - * @throws RuntimeException if unable to resolve due to an invalid definition - */ - public ResolvedFixedCouponBond resolve(ReferenceData refData, boolean combinePeriodsIfNecessary) { - Schedule adjustedSchedule = accrualSchedule.createSchedule(refData, combinePeriodsIfNecessary); + Schedule adjustedSchedule = accrualSchedule.createSchedule(refData, true); Schedule unadjustedSchedule = adjustedSchedule.toUnadjusted(); DateAdjuster exCouponPeriodAdjuster = exCouponPeriod.resolve(refData);