QuantLib: a free/open-source library for quantitative finance
Fully annotated sources - version 1.32
Loading...
Searching...
No Matches
pathwiseproductcaplet.cpp
1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3/*
4Copyright (C) 2008 Mark Joshi
5
6This file is part of QuantLib, a free-software/open-source library
7for financial quantitative analysts and developers - http://quantlib.org/
8
9QuantLib is free software: you can redistribute it and/or modify it
10under the terms of the QuantLib license. You should have received a
11copy 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
15This program is distributed in the hope that it will be useful, but WITHOUT
16ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17FOR A PARTICULAR PURPOSE. See the license for more details.
18*/
19
20#include <ql/models/marketmodels/curvestate.hpp>
21#include <ql/models/marketmodels/products/multistep/multistepforwards.hpp>
22#include <ql/models/marketmodels/products/pathwise/pathwiseproductcaplet.hpp>
23#include <ql/models/marketmodels/utilities.hpp>
24#include <utility>
25
26namespace QuantLib {
27
28
30 {
31 return false;
32 }
33
35 const std::vector<Real>& accruals,
36 const std::vector<Time>& paymentTimes,
37 const std::vector<Rate>& strikes)
38 : rateTimes_(rateTimes),
39 accruals_(accruals),
40 paymentTimes_(paymentTimes),
41 strikes_(strikes) ,
42 numberRates_(accruals_.size())
43 {
44 checkIncreasingTimes(rateTimes);
45 checkIncreasingTimes(paymentTimes);
46 std::vector<Time> evolTimes(rateTimes_);
47 evolTimes.pop_back();
48
49 QL_REQUIRE(evolTimes.size()==numberRates_,
50 "rateTimes.size()<> numberOfRates+1");
51
52 QL_REQUIRE(paymentTimes.size()==numberRates_,
53 "paymentTimes.size()<> numberOfRates");
54
55 QL_REQUIRE(accruals.size()==numberRates_,
56 "accruals.size()<> numberOfRates");
57
58 QL_REQUIRE(strikes.size()==numberRates_,
59 "strikes.size()<> numberOfRates");
60
61
62 evolution_ = EvolutionDescription(rateTimes,evolTimes);
63
64 }
65
66
67
68
70 const CurveState& currentState,
71 std::vector<Size>& numberCashFlowsThisStep,
72 std::vector<std::vector<MarketModelPathwiseMultiProduct::CashFlow> >& cashFlowsGenerated)
73 {
74 Rate liborRate = currentState.forwardRate(currentIndex_);
75 cashFlowsGenerated[currentIndex_][0].timeIndex = currentIndex_;
76 cashFlowsGenerated[currentIndex_][0].amount[0] =
78
79 std::fill(numberCashFlowsThisStep.begin(),
80 numberCashFlowsThisStep.end(),0);
81
82 if ( cashFlowsGenerated[currentIndex_][0].amount[0] >0)
83 {
84 numberCashFlowsThisStep[currentIndex_] = 1;
85 for (Size i=1; i <= numberRates_; ++i)
86 cashFlowsGenerated[currentIndex_][0].amount[i] =0;
87
88 cashFlowsGenerated[currentIndex_][0].amount[currentIndex_+1] = accruals_[currentIndex_];
89 }
91 return (currentIndex_ == strikes_.size());
92 }
93
94 std::unique_ptr<MarketModelPathwiseMultiProduct>
96 {
97 return std::unique_ptr<MarketModelPathwiseMultiProduct>(new MarketModelPathwiseMultiCaplet(*this));
98 }
99
101 {
102 std::vector<Size> numeraires(numberRates_);
103 for (Size i=0; i < numberRates_; ++i)
104 numeraires[i] = i+1;
105
106 return numeraires;
107 }
108
110 {
111 return evolution_;
112 }
113
115 {
116 return paymentTimes_;
117 }
118
120 {
121 return numberRates_;
122 }
123
125 {
126 return 1;
127
128 }
129
131 {
133 }
134
137
139 {
140 return true;
141 }
142
143
145 const std::vector<Real>& accruals,
146 const std::vector<Time>& paymentTimes,
147 const std::vector<Rate>& strikes)
148 : rateTimes_(rateTimes),
149 accruals_(accruals),
150 paymentTimes_(paymentTimes),
151 strikes_(strikes) ,
152 numberRates_(accruals_.size())
153 {
154 checkIncreasingTimes(rateTimes);
155 checkIncreasingTimes(paymentTimes);
156 std::vector<Time> evolTimes(rateTimes_);
157 evolTimes.pop_back();
158
159 QL_REQUIRE(evolTimes.size()==numberRates_,
160 "rateTimes.size()<> numberOfRates+1");
161
162 QL_REQUIRE(paymentTimes.size()==numberRates_,
163 "paymentTimes.size()<> numberOfRates");
164
165 QL_REQUIRE(accruals.size()==numberRates_,
166 "accruals.size()<> numberOfRates");
167
168 QL_REQUIRE(strikes.size()==numberRates_,
169 "strikes.size()<> numberOfRates");
170
171
172 evolution_ = EvolutionDescription(rateTimes,evolTimes);
173
174 }
175
177 const std::vector<Real>& accruals,
178 const std::vector<Time>& paymentTimes,
179 Rate strike)
180 : rateTimes_(rateTimes),
181 accruals_(accruals),
182 paymentTimes_(paymentTimes),
183 strikes_(accruals.size()) ,
184 numberRates_(accruals_.size())
185 {
186 checkIncreasingTimes(rateTimes);
187 checkIncreasingTimes(paymentTimes);
188 std::vector<Time> evolTimes(rateTimes_);
189 evolTimes.pop_back();
190
191 QL_REQUIRE(evolTimes.size()==numberRates_,
192 "rateTimes.size()<> numberOfRates+1");
193
194 QL_REQUIRE(paymentTimes.size()==numberRates_,
195 "paymentTimes.size()<> numberOfRates");
196
197 QL_REQUIRE(accruals.size()==numberRates_,
198 "accruals.size()<> numberOfRates");
199
200
201 std::fill(strikes_.begin(), strikes_.end(),strike);
202
203
204 evolution_ = EvolutionDescription(rateTimes,evolTimes);
205
206 }
207
208
210 const CurveState& currentState,
211 std::vector<Size>& numberCashFlowsThisStep,
212 std::vector<std::vector<MarketModelPathwiseMultiProduct::CashFlow> >& cashFlowsGenerated)
213 {
214 Rate liborRate = currentState.forwardRate(currentIndex_);
215 cashFlowsGenerated[currentIndex_][0].timeIndex = currentIndex_;
216 cashFlowsGenerated[currentIndex_][0].amount[0] =
218
219 std::fill(numberCashFlowsThisStep.begin(),
220 numberCashFlowsThisStep.end(),0);
221
222 if ( cashFlowsGenerated[currentIndex_][0].amount[0] >0)
223 {
224 numberCashFlowsThisStep[currentIndex_] = 1;
225 for (Size i=1; i <= numberRates_; ++i)
226 cashFlowsGenerated[currentIndex_][0].amount[i] =0;
227
228 cashFlowsGenerated[currentIndex_][0].amount[currentIndex_+1] = accruals_[currentIndex_]*currentState.discountRatio(currentIndex_+1,0);
229
230 for (Size i=0; i <= currentIndex_; ++i)
231 {
232 Real stepDF = currentState.discountRatio(i+1,i);
233 cashFlowsGenerated[currentIndex_][0].amount[i+1] -= accruals_[i]*stepDF
234 *cashFlowsGenerated[currentIndex_][0].amount[0];
235 }
236 }
238 return (currentIndex_ == strikes_.size());
239 }
240
241 std::unique_ptr<MarketModelPathwiseMultiProduct>
243 {
244 return std::unique_ptr<MarketModelPathwiseMultiProduct>(new MarketModelPathwiseMultiDeflatedCaplet(*this));
245 }
246
248 {
249 std::vector<Size> numeraires(numberRates_);
250 for (Size i=0; i < numberRates_; ++i)
251 numeraires[i] = i;
252
253 return numeraires;
254 }
255
257 {
258 return evolution_;
259 }
260
262 {
263 return paymentTimes_;
264 }
265
267 {
268 return numberRates_;
269 }
270
272 {
273 return 1;
274
275 }
276
278 {
280 }
281
283 const std::vector<Time>& rateTimes,
284 const std::vector<Real>& accruals,
285 const std::vector<Time>& paymentTimes,
286 Rate strike,
287 std::vector<std::pair<Size, Size> > startsAndEnds)
288 : underlyingCaplets_(rateTimes, accruals, paymentTimes, strike), numberRates_(accruals.size()),
289 startsAndEnds_(std::move(startsAndEnds)) {
290 for (Size j=0; j < startsAndEnds_.size(); ++j)
291 {
292 QL_REQUIRE(startsAndEnds_[j].first < startsAndEnds_[j].second,"a cap must start before it ends: " << j << startsAndEnds_[j].first << startsAndEnds_[j].second );
293 QL_REQUIRE(startsAndEnds_[j].second <= accruals.size() ,"a cap must end when the underlying caplets: " << j << startsAndEnds_[j].first << startsAndEnds_[j].second );
294
295 }
296
297 innerCashFlowSizes_.resize(accruals.size());
298 innerCashFlowsGenerated_.resize(accruals.size());
299 for (auto& i : innerCashFlowsGenerated_) {
302 i[j].amount.resize(accruals.size() + 1);
303 }
304 }
305
306
308 {
310 }
311
312
314 {
316 }
317
319 {
321 }
322
324 {
325 return startsAndEnds_.size();
326 }
328 {
330 }
331
332 // has division by the numeraire already been done?
334 {
336 }
337
338
340 {
343 }
344
345
347 const CurveState& currentState,
348 std::vector<Size>& numberCashFlowsThisStep,
349 std::vector<std::vector<MarketModelPathwiseMultiProduct::CashFlow> >& cashFlowsGenerated)
350 {
351
353
354 for (Size k=0; k < startsAndEnds_.size(); ++k)
355 numberCashFlowsThisStep[k]=0;
356
357 for (Size j=0; j < numberRates_; ++j)
358 {
359 if (innerCashFlowSizes_[j]>0)
360 {
361 for (Size k=0; k < startsAndEnds_.size(); ++k)
362 {
363 if (startsAndEnds_[k].first <= j && j < startsAndEnds_[k].second)
364 {
365 for (Size l=0; l < innerCashFlowSizes_[j]; ++l)
366 cashFlowsGenerated[k][numberCashFlowsThisStep[k]++] = innerCashFlowsGenerated_[j][l];
367 }
368 }
369 }
370 }
371
372 return done;
373 }
374
375 std::unique_ptr<MarketModelPathwiseMultiProduct>
377 {
378 return std::unique_ptr<MarketModelPathwiseMultiProduct>(new MarketModelPathwiseMultiDeflatedCap(*this));
379 }
380
381}
382
Curve state for market-model simulations
Definition: curvestate.hpp:41
virtual Rate forwardRate(Size i) const =0
virtual Real discountRatio(Size i, Size j) const =0
Market-model evolution description.
std::vector< Size > suggestedNumeraires() const override
MarketModelPathwiseMultiCaplet(const std::vector< Time > &rateTimes, const std::vector< Real > &accruals, const std::vector< Time > &paymentTimes, const std::vector< Rate > &strikes)
bool nextTimeStep(const CurveState &currentState, std::vector< Size > &numberCashFlowsThisStep, std::vector< std::vector< MarketModelPathwiseMultiProduct::CashFlow > > &cashFlowsGenerated) override
return value indicates whether path is finished, TRUE means done
std::unique_ptr< MarketModelPathwiseMultiProduct > clone() const override
returns a newly-allocated copy of itself
std::vector< Time > possibleCashFlowTimes() const override
const EvolutionDescription & evolution() const override
void reset() override
during simulation put product at start of path
std::vector< Size > suggestedNumeraires() const override
MarketModelPathwiseMultiDeflatedCap(const std::vector< Time > &rateTimes, const std::vector< Real > &accruals, const std::vector< Time > &paymentTimes, Rate strike, std::vector< std::pair< Size, Size > > startsAndEnds)
bool nextTimeStep(const CurveState &currentState, std::vector< Size > &numberCashFlowsThisStep, std::vector< std::vector< MarketModelPathwiseMultiProduct::CashFlow > > &cashFlowsGenerated) override
return value indicates whether path is finished, TRUE means done
std::unique_ptr< MarketModelPathwiseMultiProduct > clone() const override
returns a newly-allocated copy of itself
MarketModelPathwiseMultiDeflatedCaplet underlyingCaplets_
std::vector< std::pair< Size, Size > > startsAndEnds_
std::vector< Time > possibleCashFlowTimes() const override
const EvolutionDescription & evolution() const override
std::vector< std::vector< MarketModelPathwiseMultiProduct::CashFlow > > innerCashFlowsGenerated_
void reset() override
during simulation put product at start of path
std::vector< Size > suggestedNumeraires() const override
MarketModelPathwiseMultiDeflatedCaplet(const std::vector< Time > &rateTimes, const std::vector< Real > &accruals, const std::vector< Time > &paymentTimes, const std::vector< Rate > &strikes)
bool nextTimeStep(const CurveState &currentState, std::vector< Size > &numberCashFlowsThisStep, std::vector< std::vector< MarketModelPathwiseMultiProduct::CashFlow > > &cashFlowsGenerated) override
return value indicates whether path is finished, TRUE means done
std::unique_ptr< MarketModelPathwiseMultiProduct > clone() const override
returns a newly-allocated copy of itself
std::vector< Time > possibleCashFlowTimes() const override
const EvolutionDescription & evolution() const override
void reset() override
during simulation put product at start of path
QL_REAL Real
real number
Definition: types.hpp:50
Real Rate
interest rates
Definition: types.hpp:70
std::size_t Size
size of a container
Definition: types.hpp:58
Definition: any.hpp:35
void checkIncreasingTimes(const std::vector< Time > &times)
check for strictly increasing times, first time greater than zero
Definition: utilities.cpp:92
STL namespace.