QuantLib: a free/open-source library for quantitative finance
Fully annotated sources - version 1.32
Loading...
Searching...
No Matches
makecms.cpp
1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3/*
4 Copyright (C) 2006, 2007, 2014 Ferdinando Ametrano
5
6 This file is part of QuantLib, a free-software/open-source library
7 for financial quantitative analysts and developers - http://quantlib.org/
8
9 QuantLib is free software: you can redistribute it and/or modify it
10 under the terms of the QuantLib license. You should have received a
11 copy of the license along with this program; if not, please email
12 <quantlib-dev@lists.sf.net>. The license is also available online at
13 <http://quantlib.org/license.shtml>.
14
15 This program is distributed in the hope that it will be useful, but WITHOUT
16 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17 FOR A PARTICULAR PURPOSE. See the license for more details.
18*/
19
20#include <ql/instruments/makecms.hpp>
21#include <ql/instruments/swap.hpp>
22#include <ql/pricingengines/swap/discountingswapengine.hpp>
23#include <ql/cashflows/iborcoupon.hpp>
24#include <ql/cashflows/cashflows.hpp>
25#include <ql/cashflows/couponpricer.hpp>
26#include <ql/indexes/swapindex.hpp>
27#include <ql/indexes/iborindex.hpp>
28#include <ql/time/schedule.hpp>
29#include <ql/time/daycounters/actual360.hpp>
30
31namespace QuantLib {
32
33 MakeCms::MakeCms(const Period& swapTenor,
34 const ext::shared_ptr<SwapIndex>& swapIndex,
35 const ext::shared_ptr<IborIndex>& iborIndex,
36 Spread iborSpread,
37 const Period& forwardStart)
38 : swapTenor_(swapTenor), swapIndex_(swapIndex), iborIndex_(iborIndex), iborSpread_(iborSpread),
39 useAtmSpread_(false), forwardStart_(forwardStart),
40
41 cmsSpread_(0.0), cmsGearing_(1.0), cmsCap_(Null<Real>()), cmsFloor_(Null<Real>()),
42
43
44 cmsCalendar_(swapIndex->fixingCalendar()), floatCalendar_(iborIndex->fixingCalendar()),
45 payCms_(true), nominal_(1.0), cmsTenor_(3 * Months), floatTenor_(iborIndex->tenor()),
46 cmsConvention_(ModifiedFollowing), cmsTerminationDateConvention_(ModifiedFollowing),
47 floatConvention_(iborIndex->businessDayConvention()),
48 floatTerminationDateConvention_(iborIndex->businessDayConvention()),
49 cmsRule_(DateGeneration::Backward), floatRule_(DateGeneration::Backward),
50 cmsEndOfMonth_(false), floatEndOfMonth_(false),
51
52 cmsDayCount_(Actual360()), floatDayCount_(iborIndex->dayCounter()),
53 // arbitrary choice:
54 // engine_(new DiscountingSwapEngine(iborIndex->termStructure())),
55 engine_(new DiscountingSwapEngine(swapIndex->forwardingTermStructure())) {}
56
57
58 MakeCms::MakeCms(const Period& swapTenor,
59 const ext::shared_ptr<SwapIndex>& swapIndex,
60 Spread iborSpread,
61 const Period& forwardStart)
62 : swapTenor_(swapTenor), swapIndex_(swapIndex), iborIndex_(swapIndex->iborIndex()),
63 iborSpread_(iborSpread), useAtmSpread_(false), forwardStart_(forwardStart),
64
65 cmsSpread_(0.0), cmsGearing_(1.0), cmsCap_(Null<Real>()), cmsFloor_(Null<Real>()),
66
67
68 cmsCalendar_(swapIndex->fixingCalendar()), floatCalendar_(iborIndex_->fixingCalendar()),
69 payCms_(true), nominal_(1.0), cmsTenor_(3 * Months), floatTenor_(iborIndex_->tenor()),
70 cmsConvention_(ModifiedFollowing), cmsTerminationDateConvention_(ModifiedFollowing),
71 floatConvention_(iborIndex_->businessDayConvention()),
72 floatTerminationDateConvention_(iborIndex_->businessDayConvention()),
73 cmsRule_(DateGeneration::Backward), floatRule_(DateGeneration::Backward),
74 cmsEndOfMonth_(false), floatEndOfMonth_(false),
75
76 cmsDayCount_(Actual360()), floatDayCount_(iborIndex_->dayCounter()),
77 engine_(new DiscountingSwapEngine(swapIndex->forwardingTermStructure())) {}
78
79
80 MakeCms::operator Swap() const {
81 ext::shared_ptr<Swap> swap = *this;
82 return *swap;
83 }
84
85 MakeCms::operator ext::shared_ptr<Swap>() const {
86
87 Date startDate;
88 if (effectiveDate_ != Date())
89 startDate = effectiveDate_;
90 else {
91 Natural fixingDays = iborIndex_->fixingDays();
93 // if the evaluation date is not a business day
94 // then move to the next business day
95 refDate = floatCalendar_.adjust(refDate);
96 Date spotDate = floatCalendar_.advance(refDate,
97 fixingDays*Days);
98 startDate = spotDate+forwardStart_;
99 }
100
101 Date terminationDate = startDate+swapTenor_;
102
103 Schedule cmsSchedule(startDate, terminationDate,
104 cmsTenor_, cmsCalendar_,
105 cmsConvention_,
106 cmsTerminationDateConvention_,
107 cmsRule_, cmsEndOfMonth_,
108 cmsFirstDate_, cmsNextToLastDate_);
109
110 Schedule floatSchedule(startDate, terminationDate,
111 floatTenor_, floatCalendar_,
112 floatConvention_,
113 floatTerminationDateConvention_,
114 floatRule_ , floatEndOfMonth_,
115 floatFirstDate_, floatNextToLastDate_);
116
117 Leg cmsLeg = CmsLeg(cmsSchedule, swapIndex_)
118 .withNotionals(nominal_)
119 .withPaymentDayCounter(cmsDayCount_)
120 .withPaymentAdjustment(cmsConvention_)
121 .withFixingDays(swapIndex_->fixingDays())
122 .withGearings(cmsGearing_)
123 .withSpreads(cmsSpread_)
124 .withCaps(cmsCap_)
125 .withFloors(cmsFloor_);
126 if (couponPricer_ != nullptr)
127 setCouponPricer(cmsLeg, couponPricer_);
128
129 Rate usedSpread = iborSpread_;
130 if (useAtmSpread_) {
131 QL_REQUIRE(!iborIndex_->forwardingTermStructure().empty(),
132 "null term structure set to this instance of " <<
133 iborIndex_->name());
134 QL_REQUIRE(!swapIndex_->forwardingTermStructure().empty(),
135 "null term structure set to this instance of " <<
136 swapIndex_->name());
137 QL_REQUIRE(couponPricer_,
138 "no CmsCouponPricer set (yet)");
139 Leg floatLeg = IborLeg(floatSchedule, iborIndex_)
140 .withNotionals(nominal_)
141 .withPaymentDayCounter(floatDayCount_)
142 .withPaymentAdjustment(floatConvention_)
143 .withFixingDays(iborIndex_->fixingDays());
144
145 Swap temp(cmsLeg, floatLeg);
146 temp.setPricingEngine(engine_);
147
148 Real npv = temp.legNPV(0)+temp.legNPV(1);
149
150 usedSpread = -npv/temp.legBPS(1)*1e-4;
151 } else {
152 QL_REQUIRE(usedSpread != Null<Spread>(),
153 "null spread set");
154 }
155
156 Leg floatLeg = IborLeg(floatSchedule, iborIndex_)
157 .withNotionals(nominal_)
158 .withPaymentDayCounter(floatDayCount_)
159 .withPaymentAdjustment(floatConvention_)
160 .withFixingDays(iborIndex_->fixingDays())
161 .withSpreads(usedSpread);
162
163 ext::shared_ptr<Swap> swap;
164 if (payCms_)
165 swap = ext::make_shared<Swap>(cmsLeg, floatLeg);
166 else
167 swap = ext::make_shared<Swap>(floatLeg, cmsLeg);
168 swap->setPricingEngine(engine_);
169 return swap;
170 }
171
173 payCms_ = !flag;
174 return *this;
175 }
176
178 nominal_ = n;
179 return *this;
180 }
181
182 MakeCms&
183 MakeCms::withEffectiveDate(const Date& effectiveDate) {
184 effectiveDate_ = effectiveDate;
185 return *this;
186 }
187
189 const Handle<YieldTermStructure>& discountingTermStructure) {
190 engine_ = ext::make_shared<DiscountingSwapEngine>(discountingTermStructure);
191 return *this;
192 }
193
195 const ext::shared_ptr<CmsCouponPricer>& couponPricer) {
196 couponPricer_ = couponPricer;
197 return *this;
198 }
199
201 cmsTenor_ = t;
202 return *this;
203 }
204
205 MakeCms&
207 cmsCalendar_ = cal;
208 return *this;
209 }
210
211 MakeCms&
213 cmsConvention_ = bdc;
214 return *this;
215 }
216
217 MakeCms&
220 return *this;
221 }
222
224 cmsRule_ = r;
225 return *this;
226 }
227
229 cmsEndOfMonth_ = flag;
230 return *this;
231 }
232
234 cmsFirstDate_ = d;
235 return *this;
236 }
237
238 MakeCms&
241 return *this;
242 }
243
244 MakeCms&
246 cmsDayCount_ = dc;
247 return *this;
248 }
249
251 floatTenor_ = t;
252 return *this;
253 }
254
255 MakeCms&
257 floatCalendar_ = cal;
258 return *this;
259 }
260
261 MakeCms&
263 floatConvention_ = bdc;
264 return *this;
265 }
266
267 MakeCms&
270 return *this;
271 }
272
274 floatRule_ = r;
275 return *this;
276 }
277
279 floatEndOfMonth_ = flag;
280 return *this;
281 }
282
283 MakeCms&
285 floatFirstDate_ = d;
286 return *this;
287 }
288
289 MakeCms&
292 return *this;
293 }
294
295 MakeCms&
297 floatDayCount_ = dc;
298 return *this;
299 }
300
302 useAtmSpread_ = flag;
303 return *this;
304 }
305
306}
Actual/360 day count convention.
Definition: actual360.hpp:37
calendar class
Definition: calendar.hpp:61
helper class building a sequence of capped/floored cms-rate coupons
Definition: cmscoupon.hpp:70
CmsLeg & withFloors(Rate floor)
Definition: cmscoupon.cpp:122
CmsLeg & withCaps(Rate cap)
Definition: cmscoupon.cpp:112
CmsLeg & withGearings(Real gearing)
Definition: cmscoupon.cpp:92
CmsLeg & withSpreads(Spread spread)
Definition: cmscoupon.cpp:102
CmsLeg & withPaymentDayCounter(const DayCounter &)
Definition: cmscoupon.cpp:72
CmsLeg & withNotionals(Real notional)
Definition: cmscoupon.cpp:62
CmsLeg & withPaymentAdjustment(BusinessDayConvention)
Definition: cmscoupon.cpp:77
CmsLeg & withFixingDays(Natural fixingDays)
Definition: cmscoupon.cpp:82
Concrete date class.
Definition: date.hpp:125
static Date advance(const Date &d, Integer units, TimeUnit)
Definition: date.cpp:139
day counter class
Definition: daycounter.hpp:44
Shared handle to an observable.
Definition: handle.hpp:41
helper class building a sequence of capped/floored ibor-rate coupons
Definition: iborcoupon.hpp:133
IborLeg & withSpreads(Spread spread)
Definition: iborcoupon.cpp:208
IborLeg & withPaymentAdjustment(BusinessDayConvention)
Definition: iborcoupon.cpp:173
IborLeg & withPaymentDayCounter(const DayCounter &)
Definition: iborcoupon.cpp:168
IborLeg & withNotionals(Real notional)
Definition: iborcoupon.cpp:158
IborLeg & withFixingDays(Natural fixingDays)
Definition: iborcoupon.cpp:188
void setPricingEngine(const ext::shared_ptr< PricingEngine > &)
set the pricing engine to be used.
Definition: instrument.cpp:35
helper class for instantiating CMS
Definition: makecms.hpp:40
MakeCms & withDiscountingTermStructure(const Handle< YieldTermStructure > &discountingTermStructure)
Definition: makecms.cpp:188
BusinessDayConvention cmsTerminationDateConvention_
Definition: makecms.hpp:106
MakeCms & withNominal(Real n)
Definition: makecms.cpp:177
MakeCms & withCmsLegEndOfMonth(bool flag=true)
Definition: makecms.cpp:228
ext::shared_ptr< CmsCouponPricer > couponPricer_
Definition: makecms.hpp:115
Date floatNextToLastDate_
Definition: makecms.hpp:111
MakeCms & withCmsLegNextToLastDate(const Date &d)
Definition: makecms.cpp:239
Period floatTenor_
Definition: makecms.hpp:105
DateGeneration::Rule floatRule_
Definition: makecms.hpp:108
MakeCms & withFloatingLegDayCount(const DayCounter &dc)
Definition: makecms.cpp:296
DayCounter floatDayCount_
Definition: makecms.hpp:112
MakeCms & withCmsLegRule(DateGeneration::Rule r)
Definition: makecms.cpp:223
MakeCms & withFloatingLegConvention(BusinessDayConvention bdc)
Definition: makecms.cpp:262
MakeCms & withFloatingLegRule(DateGeneration::Rule r)
Definition: makecms.cpp:273
MakeCms & withCmsLegConvention(BusinessDayConvention bdc)
Definition: makecms.cpp:212
BusinessDayConvention floatTerminationDateConvention_
Definition: makecms.hpp:107
MakeCms & withCmsLegCalendar(const Calendar &cal)
Definition: makecms.cpp:206
MakeCms & withCmsLegDayCount(const DayCounter &dc)
Definition: makecms.cpp:245
MakeCms & withFloatingLegTenor(const Period &t)
Definition: makecms.cpp:250
MakeCms & withEffectiveDate(const Date &)
Definition: makecms.cpp:183
DayCounter cmsDayCount_
Definition: makecms.hpp:112
ext::shared_ptr< PricingEngine > engine_
Definition: makecms.hpp:114
MakeCms & receiveCms(bool flag=true)
Definition: makecms.cpp:172
MakeCms & withCmsLegTerminationDateConvention(BusinessDayConvention)
Definition: makecms.cpp:218
MakeCms(const Period &swapTenor, const ext::shared_ptr< SwapIndex > &swapIndex, const ext::shared_ptr< IborIndex > &iborIndex, Spread iborSpread=0.0, const Period &forwardStart=0 *Days)
Definition: makecms.cpp:33
MakeCms & withFloatingLegNextToLastDate(const Date &d)
Definition: makecms.cpp:290
MakeCms & withCmsLegFirstDate(const Date &d)
Definition: makecms.cpp:233
Calendar cmsCalendar_
Definition: makecms.hpp:101
MakeCms & withFloatingLegFirstDate(const Date &d)
Definition: makecms.cpp:284
Calendar floatCalendar_
Definition: makecms.hpp:101
Date cmsNextToLastDate_
Definition: makecms.hpp:110
BusinessDayConvention floatConvention_
Definition: makecms.hpp:107
MakeCms & withCmsCouponPricer(const ext::shared_ptr< CmsCouponPricer > &couponPricer)
Definition: makecms.cpp:194
MakeCms & withAtmSpread(bool flag=true)
Definition: makecms.cpp:301
MakeCms & withFloatingLegTerminationDateConvention(BusinessDayConvention bdc)
Definition: makecms.cpp:268
MakeCms & withCmsLegTenor(const Period &t)
Definition: makecms.cpp:200
DateGeneration::Rule cmsRule_
Definition: makecms.hpp:108
BusinessDayConvention cmsConvention_
Definition: makecms.hpp:106
MakeCms & withFloatingLegEndOfMonth(bool flag=true)
Definition: makecms.cpp:278
MakeCms & withFloatingLegCalendar(const Calendar &cal)
Definition: makecms.cpp:256
template class providing a null value for a given type.
Definition: null.hpp:76
Payment schedule.
Definition: schedule.hpp:40
DateProxy & evaluationDate()
the date at which pricing is to be performed.
Definition: settings.hpp:147
static Settings & instance()
access to the unique instance
Definition: singleton.hpp:104
Interest rate swap.
Definition: swap.hpp:41
Real legBPS(Size j) const
Definition: swap.hpp:82
Real legNPV(Size j) const
Definition: swap.hpp:88
BusinessDayConvention
Business Day conventions.
QL_REAL Real
real number
Definition: types.hpp:50
unsigned QL_INTEGER Natural
positive integer
Definition: types.hpp:43
Real Spread
spreads on interest rates
Definition: types.hpp:74
Real Rate
interest rates
Definition: types.hpp:70
Definition: any.hpp:35
void swap(Array &v, Array &w) noexcept
Definition: array.hpp:903
void setCouponPricer(const Leg &leg, const ext::shared_ptr< FloatingRateCouponPricer > &pricer)
std::vector< ext::shared_ptr< CashFlow > > Leg
Sequence of cash-flows.
Definition: cashflow.hpp:78
Date-generation rule.