QuantLib: a free/open-source library for quantitative finance
Fully annotated sources - version 1.32
Loading...
Searching...
No Matches
cashflowvectors.hpp
1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3/*
4 Copyright (C) 2000, 2001, 2002, 2003 RiskMap srl
5 Copyright (C) 2003, 2004 StatPro Italia srl
6 Copyright (C) 2006, 2007 Cristina Duminuco
7 Copyright (C) 2006, 2007 Giorgio Facchinetti
8 Copyright (C) 2006 Mario Pucci
9 Copyright (C) 2007 Ferdinando Ametrano
10 Copyright (C) 2017 Joseph Jeisman
11 Copyright (C) 2017 Fabrice Lecuyer
12
13 This file is part of QuantLib, a free-software/open-source library
14 for financial quantitative analysts and developers - http://quantlib.org/
15
16 QuantLib is free software: you can redistribute it and/or modify it
17 under the terms of the QuantLib license. You should have received a
18 copy of the license along with this program; if not, please email
19 <quantlib-dev@lists.sf.net>. The license is also available online at
20 <http://quantlib.org/license.shtml>.
21
22 This program is distributed in the hope that it will be useful, but WITHOUT
23 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
24 FOR A PARTICULAR PURPOSE. See the license for more details.
25*/
26
31#ifndef quantlib_cash_flow_vectors_hpp
32#define quantlib_cash_flow_vectors_hpp
33
34#include <ql/cashflows/fixedratecoupon.hpp>
35#include <ql/cashflows/replication.hpp>
36#include <ql/time/schedule.hpp>
37#include <ql/utilities/null.hpp>
38#include <ql/utilities/vectors.hpp>
39#include <ql/position.hpp>
40#include <ql/indexes/swapindex.hpp>
41
42namespace QuantLib {
43
44 namespace detail {
45
46 Rate effectiveFixedRate(const std::vector<Spread>& spreads,
47 const std::vector<Rate>& caps,
48 const std::vector<Rate>& floors,
49 Size i);
50
51 bool noOption(const std::vector<Rate>& caps,
52 const std::vector<Rate>& floors,
53 Size i);
54
55 }
56
57
58 template <typename InterestRateIndexType,
59 typename FloatingCouponType,
60 typename CappedFlooredCouponType>
61 Leg FloatingLeg(const Schedule& schedule,
62 const std::vector<Real>& nominals,
63 const ext::shared_ptr<InterestRateIndexType>& index,
64 const DayCounter& paymentDayCounter,
65 BusinessDayConvention paymentAdj,
66 const std::vector<Natural>& fixingDays,
67 const std::vector<Real>& gearings,
68 const std::vector<Spread>& spreads,
69 const std::vector<Rate>& caps,
70 const std::vector<Rate>& floors,
71 bool isInArrears,
72 bool isZero,
73 Natural paymentLag = 0,
74 Calendar paymentCalendar = Calendar(),
75 Period exCouponPeriod = Period(),
76 Calendar exCouponCalendar = Calendar(),
77 BusinessDayConvention exCouponAdjustment = Unadjusted,
78 bool exCouponEndOfMonth = false) {
79
80 Size n = schedule.size()-1;
81 QL_REQUIRE(!nominals.empty(), "no notional given");
82 QL_REQUIRE(nominals.size() <= n,
83 "too many nominals (" << nominals.size() <<
84 "), only " << n << " required");
85 QL_REQUIRE(gearings.size()<=n,
86 "too many gearings (" << gearings.size() <<
87 "), only " << n << " required");
88 QL_REQUIRE(spreads.size()<=n,
89 "too many spreads (" << spreads.size() <<
90 "), only " << n << " required");
91 QL_REQUIRE(caps.size()<=n,
92 "too many caps (" << caps.size() <<
93 "), only " << n << " required");
94 QL_REQUIRE(floors.size()<=n,
95 "too many floors (" << floors.size() <<
96 "), only " << n << " required");
97 QL_REQUIRE(!isZero || !isInArrears,
98 "in-arrears and zero features are not compatible");
99
100 Leg leg; leg.reserve(n);
101
102 // the following is not always correct
103 const Calendar& calendar = schedule.calendar();
104
105 if (paymentCalendar.empty()) {
106 paymentCalendar = calendar;
107 }
108 Date refStart, start, refEnd, end;
109 Date exCouponDate;
110 Date lastPaymentDate = paymentCalendar.advance(schedule.date(n), paymentLag, Days, paymentAdj);
111
112 for (Size i=0; i<n; ++i) {
113 refStart = start = schedule.date(i);
114 refEnd = end = schedule.date(i+1);
115 Date paymentDate =
116 isZero ? lastPaymentDate : paymentCalendar.advance(end, paymentLag, Days, paymentAdj);
117 if (i==0 && (schedule.hasIsRegular() && schedule.hasTenor() && !schedule.isRegular(i+1))) {
119 refStart = calendar.adjust(end - schedule.tenor(), bdc);
120 }
121 if (i==n-1 && (schedule.hasIsRegular() && schedule.hasTenor() && !schedule.isRegular(i+1))) {
123 refEnd = calendar.adjust(start + schedule.tenor(), bdc);
124 }
125 if (exCouponPeriod != Period()) {
126 if (exCouponCalendar.empty()) {
127 exCouponCalendar = calendar;
128 }
129 exCouponDate = exCouponCalendar.advance(paymentDate, -exCouponPeriod,
130 exCouponAdjustment, exCouponEndOfMonth);
131 }
132 if (detail::get(gearings, i, 1.0) == 0.0) { // fixed coupon
133 leg.push_back(ext::shared_ptr<CashFlow>(new
134 FixedRateCoupon(paymentDate,
135 detail::get(nominals, i, 1.0),
136 detail::effectiveFixedRate(spreads,caps,
137 floors,i),
138 paymentDayCounter,
139 start, end, refStart, refEnd,
140 exCouponDate)));
141 } else { // floating coupon
142 if (detail::noOption(caps, floors, i))
143 leg.push_back(ext::shared_ptr<CashFlow>(new
144 FloatingCouponType(
145 paymentDate,
146 detail::get(nominals, i, 1.0),
147 start, end,
148 detail::get(fixingDays, i, index->fixingDays()),
149 index,
150 detail::get(gearings, i, 1.0),
151 detail::get(spreads, i, 0.0),
152 refStart, refEnd,
153 paymentDayCounter, isInArrears, exCouponDate)));
154 else {
155 leg.push_back(ext::shared_ptr<CashFlow>(new
156 CappedFlooredCouponType(
157 paymentDate,
158 detail::get(nominals, i, 1.0),
159 start, end,
160 detail::get(fixingDays, i, index->fixingDays()),
161 index,
162 detail::get(gearings, i, 1.0),
163 detail::get(spreads, i, 0.0),
164 detail::get(caps, i, Null<Rate>()),
165 detail::get(floors, i, Null<Rate>()),
166 refStart, refEnd,
167 paymentDayCounter,
168 isInArrears, exCouponDate)));
169 }
170 }
171 }
172 return leg;
173 }
174
175
176 template <typename InterestRateIndexType,
177 typename FloatingCouponType,
178 typename DigitalCouponType>
180 const Schedule& schedule,
181 const std::vector<Real>& nominals,
182 const ext::shared_ptr<InterestRateIndexType>& index,
183 const DayCounter& paymentDayCounter,
184 BusinessDayConvention paymentAdj,
185 const std::vector<Natural>& fixingDays,
186 const std::vector<Real>& gearings,
187 const std::vector<Spread>& spreads,
188 bool isInArrears,
189 const std::vector<Rate>& callStrikes,
190 Position::Type callPosition,
191 bool isCallATMIncluded,
192 const std::vector<Rate>& callDigitalPayoffs,
193 const std::vector<Rate>& putStrikes,
194 Position::Type putPosition,
195 bool isPutATMIncluded,
196 const std::vector<Rate>& putDigitalPayoffs,
197 const ext::shared_ptr<DigitalReplication>& replication,
198 bool nakedOption = false) {
199 Size n = schedule.size()-1;
200 QL_REQUIRE(!nominals.empty(), "no notional given");
201 QL_REQUIRE(nominals.size() <= n,
202 "too many nominals (" << nominals.size() <<
203 "), only " << n << " required");
204 QL_REQUIRE(gearings.size()<=n,
205 "too many gearings (" << gearings.size() <<
206 "), only " << n << " required");
207 QL_REQUIRE(spreads.size()<=n,
208 "too many spreads (" << spreads.size() <<
209 "), only " << n << " required");
210 QL_REQUIRE(callStrikes.size()<=n,
211 "too many call rates (" << callStrikes.size() <<
212 "), only " << n << " required");
213 QL_REQUIRE(putStrikes.size()<=n,
214 "too many put rates (" << putStrikes.size() <<
215 "), only " << n << " required");
216
217 Leg leg; leg.reserve(n);
218
219 // the following is not always correct
220 const Calendar& calendar = schedule.calendar();
221
222 Date refStart, start, refEnd, end;
223 Date paymentDate;
224
225 for (Size i=0; i<n; ++i) {
226 refStart = start = schedule.date(i);
227 refEnd = end = schedule.date(i+1);
228 paymentDate = calendar.adjust(end, paymentAdj);
229 if (i==0 && (schedule.hasIsRegular() && schedule.hasTenor() && !schedule.isRegular(i+1))) {
231 refStart = calendar.adjust(end - schedule.tenor(), bdc);
232 }
233 if (i==n-1 && (schedule.hasIsRegular() && schedule.hasTenor() && !schedule.isRegular(i+1))) {
235 refEnd = calendar.adjust(start + schedule.tenor(), bdc);
236 }
237 if (detail::get(gearings, i, 1.0) == 0.0) { // fixed coupon
238 leg.push_back(ext::shared_ptr<CashFlow>(new
239 FixedRateCoupon(paymentDate,
240 detail::get(nominals, i, 1.0),
241 detail::get(spreads, i, 1.0),
242 paymentDayCounter,
243 start, end, refStart, refEnd)));
244 } else { // floating digital coupon
245 ext::shared_ptr<FloatingCouponType> underlying(new
246 FloatingCouponType(paymentDate,
247 detail::get(nominals, i, 1.0),
248 start, end,
249 detail::get(fixingDays, i, index->fixingDays()),
250 index,
251 detail::get(gearings, i, 1.0),
252 detail::get(spreads, i, 0.0),
253 refStart, refEnd,
254 paymentDayCounter, isInArrears));
255 leg.push_back(ext::shared_ptr<CashFlow>(new
256 DigitalCouponType(
257 underlying,
258 detail::get(callStrikes, i, Null<Real>()),
259 callPosition,
260 isCallATMIncluded,
261 detail::get(callDigitalPayoffs, i, Null<Real>()),
262 detail::get(putStrikes, i, Null<Real>()),
263 putPosition,
264 isPutATMIncluded,
265 detail::get(putDigitalPayoffs, i, Null<Real>()),
266 replication, nakedOption)));
267 }
268 }
269 return leg;
270 }
271
272}
273
274#endif
calendar class
Definition: calendar.hpp:61
Date adjust(const Date &, BusinessDayConvention convention=Following) const
Definition: calendar.cpp:84
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
Coupon paying a fixed interest rate
template class providing a null value for a given type.
Definition: null.hpp:76
Payment schedule.
Definition: schedule.hpp:40
const Calendar & calendar() const
Definition: schedule.hpp:176
bool isRegular(Size i) const
Definition: schedule.cpp:518
bool hasTenor() const
Definition: schedule.hpp:186
const Date & date(Size i) const
Definition: schedule.hpp:160
Size size() const
Definition: schedule.hpp:69
BusinessDayConvention businessDayConvention() const
Definition: schedule.hpp:196
bool hasIsRegular() const
Definition: schedule.cpp:516
const Period & tenor() const
Definition: schedule.hpp:190
BusinessDayConvention
Business Day conventions.
unsigned QL_INTEGER Natural
positive integer
Definition: types.hpp:43
Real Rate
interest rates
Definition: types.hpp:70
std::size_t Size
size of a container
Definition: types.hpp:58
T get(const std::vector< T > &v, Size i, U defaultValue)
Definition: vectors.hpp:35
Rate effectiveFixedRate(const std::vector< Spread > &spreads, const std::vector< Rate > &caps, const std::vector< Rate > &floors, Size i)
bool noOption(const std::vector< Rate > &caps, const std::vector< Rate > &floors, Size i)
Definition: any.hpp:35
Leg FloatingLeg(const Schedule &schedule, const std::vector< Real > &nominals, const ext::shared_ptr< InterestRateIndexType > &index, const DayCounter &paymentDayCounter, BusinessDayConvention paymentAdj, const std::vector< Natural > &fixingDays, const std::vector< Real > &gearings, const std::vector< Spread > &spreads, const std::vector< Rate > &caps, const std::vector< Rate > &floors, bool isInArrears, bool isZero, Natural paymentLag=0, Calendar paymentCalendar=Calendar(), Period exCouponPeriod=Period(), Calendar exCouponCalendar=Calendar(), BusinessDayConvention exCouponAdjustment=Unadjusted, bool exCouponEndOfMonth=false)
Leg FloatingDigitalLeg(const Schedule &schedule, const std::vector< Real > &nominals, const ext::shared_ptr< InterestRateIndexType > &index, const DayCounter &paymentDayCounter, BusinessDayConvention paymentAdj, const std::vector< Natural > &fixingDays, const std::vector< Real > &gearings, const std::vector< Spread > &spreads, bool isInArrears, const std::vector< Rate > &callStrikes, Position::Type callPosition, bool isCallATMIncluded, const std::vector< Rate > &callDigitalPayoffs, const std::vector< Rate > &putStrikes, Position::Type putPosition, bool isPutATMIncluded, const std::vector< Rate > &putDigitalPayoffs, const ext::shared_ptr< DigitalReplication > &replication, bool nakedOption=false)
std::vector< ext::shared_ptr< CashFlow > > Leg
Sequence of cash-flows.
Definition: cashflow.hpp:78