Skip to content

Commit

Permalink
Merge 4ed9da4 into af1e9db
Browse files Browse the repository at this point in the history
  • Loading branch information
DeimosXing committed Feb 26, 2024
2 parents af1e9db + 4ed9da4 commit 2342634
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 4 deletions.
12 changes: 9 additions & 3 deletions ql/time/calendar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,9 +159,15 @@ namespace QuantLib {
Date d1 = d + n*unit;

// we are sure the unit is Months or Years
if (endOfMonth && isEndOfMonth(d))
return Calendar::endOfMonth(d1);

if (endOfMonth){
if (c == Unadjusted && Date::isEndOfMonth(d)){
// move to end of calendar day if using Unadjusted convention and d is last calendar day
return Date::endOfMonth(d1);
} else if (isEndOfMonth(d)) {
// move to end of business day if d is last bussiness day
return Calendar::endOfMonth(d1);
}
}
return adjust(d1, c);
}
}
Expand Down
2 changes: 1 addition & 1 deletion test-suite/businessdayconventions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ BOOST_AUTO_TEST_CASE(testConventions) {
//Unadjusted
SingleCase(SouthAfrica(), Unadjusted, Date(3,February,2015), Period(1,Months), false, Date(3,March,2015)),
SingleCase(SouthAfrica(), Unadjusted, Date(3,February,2015), Period(4,Days), false, Date(9,February,2015)),
SingleCase(SouthAfrica(), Unadjusted, Date(31,January,2015), Period(1,Months), true, Date(27,February,2015)),
SingleCase(SouthAfrica(), Unadjusted, Date(31,January,2015), Period(1,Months), true, Date(28,February,2015)),
SingleCase(SouthAfrica(), Unadjusted, Date(31,January,2015), Period(1,Months), false, Date(28,February,2015)),

//HalfMonthModifiedFollowing
Expand Down
32 changes: 32 additions & 0 deletions test-suite/cashflows.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,38 @@ BOOST_AUTO_TEST_CASE(testIrregularFirstCouponReferenceDatesAtEndOfMonth) {
"got " << firstCoupon->referencePeriodStart());
}

BOOST_AUTO_TEST_CASE(testIrregularFirstCouponReferenceDatesAtEndOfCalendarMonth) {
BOOST_TEST_MESSAGE("Testing irregular first coupon reference dates at end of calendar month with end of month enabled...");
Schedule schedule =
MakeSchedule()
.withCalendar(UnitedStates(UnitedStates::GovernmentBond))
.from(Date(30, September, 2017)).to(Date(30, September, 2022))
.withTenor(6*Months)
.withConvention(Unadjusted)
.withTerminationDateConvention(Unadjusted)
.withFirstDate(Date(31, March, 2018))
.withNextToLastDate(Date(31, March, 2022))
.endOfMonth()
.backwards();

Leg leg = FixedRateLeg(schedule)
.withNotionals(100.0)
.withCouponRates(0.01875, ActualActual(ActualActual::ISMA));

for (const auto& elem : leg) {
BOOST_TEST_MESSAGE("Reference Period: " << ext::dynamic_pointer_cast<Coupon>(elem)->referencePeriodStart() << " - " << ext::dynamic_pointer_cast<Coupon>(elem)->referencePeriodEnd());
BOOST_TEST_MESSAGE("Amount: " << ext::dynamic_pointer_cast<Coupon>(elem)->amount());
}

ext::shared_ptr<Coupon> firstCoupon =
ext::dynamic_pointer_cast<Coupon>(leg.front());
if (firstCoupon->referencePeriodStart() != Date(30, September, 2017))
BOOST_ERROR("Expected reference start date at end of calendar day of the month, "
"got " << firstCoupon->referencePeriodStart());
// Expect first cashflow to be 0.9375
BOOST_TEST(firstCoupon->amount() == 0.9375, boost::test_tools::tolerance(0.0001));
}

BOOST_AUTO_TEST_CASE(testIrregularLastCouponReferenceDatesAtEndOfMonth) {
BOOST_TEST_MESSAGE("Testing irregular last coupon reference dates with end of month enabled...");
Schedule schedule =
Expand Down

0 comments on commit 2342634

Please sign in to comment.