21#include <ql/cashflows/capflooredcoupon.hpp>
22#include <ql/cashflows/cashflowvectors.hpp>
23#include <ql/cashflows/cmscoupon.hpp>
28 const Date& endDate, Natural fixingDays,
29 const QuantLib::ext::shared_ptr<SwapIndex>& swapIndex, Size duration,
30 Real gearing, Spread spread,
const Date& refPeriodStart,
31 const Date& refPeriodEnd,
const DayCounter& dayCounter,
32 bool isInArrears,
const Date& exCouponDate)
33 :
FloatingRateCoupon(paymentDate, nominal, startDate, endDate, fixingDays, swapIndex, gearing, spread,
34 refPeriodStart, refPeriodEnd, dayCounter, isInArrears, exCouponDate),
35 swapIndex_(swapIndex), duration_(duration) {}
42 Real swapRate =
swapIndex_->fixing(fixingDate());
45 tmp += 1.0 / std::pow(1.0 + swapRate,
static_cast<Real
>(i + 1));
54 Visitor<DurationAdjustedCmsCoupon>* v1 =
dynamic_cast<Visitor<DurationAdjustedCmsCoupon>*
>(&v);
58 FloatingRateCoupon::accept(v);
63 : schedule_(schedule), swapIndex_(swapIndex), paymentLag_(0), paymentCalendar_(Calendar()),
64 paymentAdjustment_(Following), inArrears_(false), zeroPayments_(false), exCouponPeriod_(Period()),
65 exCouponCalendar_(Calendar()), exCouponAdjustment_(Unadjusted), exCouponEndOfMonth_(false), duration_(duration) {}
108 gearings_ = std::vector<Real>(1, gearing);
118 spreads_ = std::vector<Spread>(1, spread);
128 caps_ = std::vector<Rate>(1, cap);
138 floors_ = std::vector<Rate>(1, floor);
163 BusinessDayConvention convention,
bool endOfMonth) {
171DurationAdjustedCmsLeg::operator Leg()
const {
172 Size n = schedule_.size() - 1;
174 QL_REQUIRE(!notionals_.empty(),
"no notional given");
175 QL_REQUIRE(notionals_.size() <= n,
"too many notionals (" << notionals_.size() <<
"), only " << n <<
" required");
176 QL_REQUIRE(gearings_.size() <= n,
"too many gearings (" << gearings_.size() <<
"), only " << n <<
" required");
177 QL_REQUIRE(spreads_.size() <= n,
"too many spreads (" << spreads_.size() <<
"), only " << n <<
" required");
178 QL_REQUIRE(caps_.size() <= n,
"too many caps (" << caps_.size() <<
"), only " << n <<
" required");
179 QL_REQUIRE(floors_.size() <= n,
"too many floors (" << floors_.size() <<
"), only " << n <<
" required");
180 QL_REQUIRE(!zeroPayments_ || !inArrears_,
"in-arrears and zero features are not compatible");
185 Calendar calendar = schedule_.calendar();
186 Calendar paymentCalendar = schedule_.calendar();
188 if (!paymentCalendar_.empty()) {
189 paymentCalendar = paymentCalendar_;
192 Date refStart, start, refEnd, end;
194 Date lastPaymentDate = paymentCalendar.advance(schedule_.date(n), paymentLag_, Days, paymentAdjustment_);
196 for (Size i = 0; i < n; ++i) {
197 refStart = start = schedule_.date(i);
198 refEnd = end = schedule_.date(i + 1);
200 zeroPayments_ ? lastPaymentDate : paymentCalendar.advance(end, paymentLag_, Days, paymentAdjustment_);
201 if (i == 0 && (schedule_.hasIsRegular() && schedule_.hasTenor() && !schedule_.isRegular(i + 1))) {
202 BusinessDayConvention bdc = schedule_.businessDayConvention();
203 refStart = calendar.adjust(end - schedule_.tenor(), bdc);
205 if (i == n - 1 && (schedule_.hasIsRegular() && schedule_.hasTenor() && !schedule_.isRegular(i + 1))) {
206 BusinessDayConvention bdc = schedule_.businessDayConvention();
207 refEnd = calendar.adjust(start + schedule_.tenor(), bdc);
209 if (exCouponPeriod_ != Period()) {
210 Calendar exCouponCalendar = calendar;
211 if (!exCouponCalendar_.empty()) {
212 exCouponCalendar = exCouponCalendar_;
215 exCouponCalendar_.advance(paymentDate, -exCouponPeriod_, exCouponAdjustment_, exCouponEndOfMonth_);
217 auto cpn = QuantLib::ext::make_shared<DurationAdjustedCmsCoupon>(
218 paymentDate, detail::get(notionals_, i, 1.0), start, end,
219 detail::get(fixingDays_, i, swapIndex_->fixingDays()), swapIndex_, duration_,
220 detail::get(gearings_, i, 1.0), detail::get(spreads_, i, 0.0), refStart, refEnd, paymentDayCounter_,
221 inArrears_, exCouponDate);
222 if (detail::noOption(caps_, floors_, i)) {
225 leg.push_back(QuantLib::ext::make_shared<CappedFlooredCoupon>(cpn, detail::get(caps_, i, Null<Rate>()),
226 detail::get(floors_, i, Null<Rate>())));
Real durationAdjustment() const
Rate indexFixing() const override
void accept(AcyclicVisitor &) override
QuantLib::ext::shared_ptr< SwapIndex > swapIndex_
DurationAdjustedCmsCoupon(const Date &paymentDate, Real nominal, const Date &startDate, const Date &endDate, Natural fixingDays, const QuantLib::ext::shared_ptr< SwapIndex > &index, Size duration=0, Real gearing=1.0, Spread spread=0.0, const Date &refPeriodStart=Date(), const Date &refPeriodEnd=Date(), const DayCounter &dayCounter=DayCounter(), bool isInArrears=false, const Date &exCouponDate=Date())
DurationAdjustedCmsLeg & withPaymentCalendar(const Calendar &)
BusinessDayConvention paymentAdjustment_
std::vector< Rate > caps_
BusinessDayConvention exCouponAdjustment_
DurationAdjustedCmsLeg & withPaymentAdjustment(BusinessDayConvention)
DurationAdjustedCmsLeg & withZeroPayments(bool flag=true)
Calendar paymentCalendar_
DurationAdjustedCmsLeg & withSpreads(Spread spread)
DurationAdjustedCmsLeg & withFixingDays(Natural fixingDays)
std::vector< Real > notionals_
std::vector< Spread > spreads_
DurationAdjustedCmsLeg & withDuration(Size duration)
DurationAdjustedCmsLeg & withPaymentLag(Natural lag)
DurationAdjustedCmsLeg & withFloors(Rate floor)
DurationAdjustedCmsLeg(const Schedule &schedule, const QuantLib::ext::shared_ptr< SwapIndex > &swapIndex, const Size duration)
DurationAdjustedCmsLeg & withNotionals(Real notional)
std::vector< Natural > fixingDays_
DurationAdjustedCmsLeg & withGearings(Real gearing)
DurationAdjustedCmsLeg & withExCouponPeriod(const Period &, const Calendar &, BusinessDayConvention, bool endOfMonth=false)
Calendar exCouponCalendar_
DurationAdjustedCmsLeg & withPaymentDayCounter(const DayCounter &)
std::vector< Rate > floors_
DurationAdjustedCmsLeg & inArrears(bool flag=true)
DurationAdjustedCmsLeg & withCaps(Rate cap)
std::vector< Real > gearings_
DayCounter paymentDayCounter_
cms coupon scaled by a duration number