Skip to content

Commit c235cda

Browse files
Merge branch 'QPR-11765' into 'master'
Resolve QPR-11765 (add ctors to FloatingRateCoupon, IborCoupon taking explicit fixing dates) Closes QPR-11765 See merge request qs/quantlib!54
2 parents 3258ebc + 9921a4d commit c235cda

5 files changed

Lines changed: 92 additions & 10 deletions

File tree

ql/cashflows/couponpricer.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ namespace QuantLib {
6262
if (useIndexedCoupon_) {
6363
coupon.fixingEndDate_ = coupon.fixingMaturityDate_;
6464
} else {
65-
if (coupon.isInArrears_)
65+
if (coupon.isInArrears_ || coupon.fixingDays_ == Null<Size>())
6666
coupon.fixingEndDate_ = coupon.fixingMaturityDate_;
6767
else { // par coupon approximation
6868
Date nextFixingDate = coupon.iborIndex()->fixingCalendar().advance(

ql/cashflows/floatingratecoupon.cpp

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,43 @@ namespace QuantLib {
5353
if (dayCounter_.empty())
5454
dayCounter_ = index_->dayCounter();
5555

56+
// if isInArrears_ fix at the end of period
57+
Date refDate = isInArrears_ ? accrualEndDate_ : accrualStartDate_;
58+
fixingDate_ = index_->fixingCalendar().advance(refDate, -static_cast<Integer>(fixingDays_),
59+
Days, Preceding);
60+
61+
registerWith(index_);
62+
registerWith(Settings::instance().evaluationDate());
63+
}
64+
65+
FloatingRateCoupon::FloatingRateCoupon(const Date& paymentDate,
66+
Real nominal,
67+
const Date& startDate,
68+
const Date& endDate,
69+
const Date& fixingDate,
70+
const ext::shared_ptr<InterestRateIndex>& index,
71+
Real gearing,
72+
Spread spread,
73+
const Date& refPeriodStart,
74+
const Date& refPeriodEnd,
75+
DayCounter dayCounter,
76+
bool isInArrears,
77+
const Date& exCouponDate)
78+
: Coupon(paymentDate, nominal, startDate, endDate, refPeriodStart, refPeriodEnd, exCouponDate),
79+
index_(index), dayCounter_(std::move(dayCounter)), fixingDays_(Null<Size>()),
80+
gearing_(gearing), spread_(spread), isInArrears_(isInArrears) {
81+
QL_REQUIRE(index_, "no index provided");
82+
QL_REQUIRE(gearing_!=0, "Null gearing not allowed");
83+
84+
if (dayCounter_.empty())
85+
dayCounter_ = index_->dayCounter();
86+
87+
QL_REQUIRE(index_->fixingCalendar().isBusinessDay(fixingDate),
88+
"FloatingRateCoupon: fixing date " << fixingDate
89+
<< " not valid for fixing calendar "
90+
<< index_->fixingCalendar());
91+
fixingDate_ = fixingDate;
92+
5693
registerWith(index_);
5794
registerWith(Settings::instance().evaluationDate());
5895
}
@@ -77,10 +114,12 @@ namespace QuantLib {
77114
}
78115

79116
Date FloatingRateCoupon::fixingDate() const {
80-
// if isInArrears_ fix at the end of period
81-
Date refDate = isInArrears_ ? accrualEndDate_ : accrualStartDate_;
82-
return index_->fixingCalendar().advance(refDate,
83-
-static_cast<Integer>(fixingDays_), Days, Preceding);
117+
return fixingDate_;
118+
}
119+
120+
Natural FloatingRateCoupon::fixingDays() const {
121+
QL_REQUIRE(fixingDays_ != Null<Size>(), "FloatingRateCoupon::fixingDays() not given.");
122+
return fixingDays_;
84123
}
85124

86125
Rate FloatingRateCoupon::rate() const {

ql/cashflows/floatingratecoupon.hpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,19 @@ namespace QuantLib {
5757
DayCounter dayCounter = DayCounter(),
5858
bool isInArrears = false,
5959
const Date& exCouponDate = Date());
60+
FloatingRateCoupon(const Date& paymentDate,
61+
Real nominal,
62+
const Date& startDate,
63+
const Date& endDate,
64+
const Date& fixingDate,
65+
const ext::shared_ptr<InterestRateIndex>& index,
66+
Real gearing = 1.0,
67+
Spread spread = 0.0,
68+
const Date& refPeriodStart = Date(),
69+
const Date& refPeriodEnd = Date(),
70+
DayCounter dayCounter = DayCounter(),
71+
bool isInArrears = false,
72+
const Date& exCouponDate = Date());
6073

6174
//! \name LazyObject interface
6275
//@{
@@ -80,7 +93,7 @@ namespace QuantLib {
8093
//! floating index
8194
const ext::shared_ptr<InterestRateIndex>& index() const;
8295
//! fixing days
83-
Natural fixingDays() const { return fixingDays_; }
96+
Natural fixingDays() const;
8497
//! fixing date
8598
virtual Date fixingDate() const;
8699
//! index gearing, i.e. multiplicative coefficient for the index
@@ -113,6 +126,7 @@ namespace QuantLib {
113126
Real gearing_;
114127
Spread spread_;
115128
bool isInArrears_;
129+
Date fixingDate_;
116130
ext::shared_ptr<FloatingRateCouponPricer> pricer_;
117131
mutable Real rate_;
118132
};

ql/cashflows/iborcoupon.cpp

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,26 @@ namespace QuantLib {
4949
fixingDays, iborIndex, gearing, spread,
5050
refPeriodStart, refPeriodEnd,
5151
dayCounter, isInArrears, exCouponDate),
52-
iborIndex_(iborIndex) {
53-
fixingDate_ = fixingDate();
54-
}
52+
iborIndex_(iborIndex) {}
53+
54+
IborCoupon::IborCoupon(const Date& paymentDate,
55+
Real nominal,
56+
const Date& startDate,
57+
const Date& endDate,
58+
const Date& fixingDate,
59+
const ext::shared_ptr<IborIndex>& iborIndex,
60+
Real gearing,
61+
Spread spread,
62+
const Date& refPeriodStart,
63+
const Date& refPeriodEnd,
64+
const DayCounter& dayCounter,
65+
bool isInArrears,
66+
const Date& exCouponDate)
67+
: FloatingRateCoupon(paymentDate, nominal, startDate, endDate,
68+
fixingDate, iborIndex, gearing, spread,
69+
refPeriodStart, refPeriodEnd,
70+
dayCounter, isInArrears, exCouponDate),
71+
iborIndex_(iborIndex) {}
5572

5673
void IborCoupon::initializeCachedData() const {
5774
auto p = ext::dynamic_pointer_cast<IborCouponPricer>(pricer_);

ql/cashflows/iborcoupon.hpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,19 @@ namespace QuantLib {
5353
const DayCounter& dayCounter = DayCounter(),
5454
bool isInArrears = false,
5555
const Date& exCouponDate = Date());
56+
IborCoupon(const Date& paymentDate,
57+
Real nominal,
58+
const Date& startDate,
59+
const Date& endDate,
60+
const Date& fixingDate,
61+
const ext::shared_ptr<IborIndex>& index,
62+
Real gearing = 1.0,
63+
Spread spread = 0.0,
64+
const Date& refPeriodStart = Date(),
65+
const Date& refPeriodEnd = Date(),
66+
const DayCounter& dayCounter = DayCounter(),
67+
bool isInArrears = false,
68+
const Date& exCouponDate = Date());
5669
//! \name Inspectors
5770
//@{
5871
const ext::shared_ptr<IborIndex>& iborIndex() const { return iborIndex_; }
@@ -90,7 +103,6 @@ namespace QuantLib {
90103
private:
91104
friend class IborCouponPricer;
92105
ext::shared_ptr<IborIndex> iborIndex_;
93-
Date fixingDate_;
94106
// computed by coupon pricer (depending on par coupon flag) and stored here
95107
void initializeCachedData() const;
96108
mutable bool cachedDataIsInitialized_ = false;

0 commit comments

Comments
 (0)