QuantLib: a free/open-source library for quantitative finance
Fully annotated sources - version 1.32
Loading...
Searching...
No Matches
cmsmarketcalibration.cpp
1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3/*
4 Copyright (C) 2007 Marco Bianchetti
5 Copyright (C) 2006, 2007 Giorgio Facchinetti
6 Cpoyright (C) 2014 Peter Caspers
7
8 This file is part of QuantLib, a free-software/open-source library
9 for financial quantitative analysts and developers - http://quantlib.org/
10
11 QuantLib is free software: you can redistribute it and/or modify it
12 under the terms of the QuantLib license. You should have received a
13 copy of the license along with this program; if not, please email
14 <quantlib-dev@lists.sf.net>. The license is also available online at
15 <http://quantlib.org/license.shtml>.
16
17 This program is distributed in the hope that it will be useful, but WITHOUT
18 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
19 FOR A PARTICULAR PURPOSE. See the license for more details.
20*/
21
22#include <ql/termstructures/volatility/swaption/cmsmarketcalibration.hpp>
23#include <ql/termstructures/volatility/swaption/cmsmarket.hpp>
24#include <ql/termstructures/volatility/swaption/sabrswaptionvolatilitycube.hpp>
25#include <ql/math/optimization/problem.hpp>
26#include <ql/math/optimization/constraint.hpp>
27
28namespace {
29 using namespace QuantLib;
30
31 class ObjectiveFunction : public CostFunction {
32 public:
33 explicit ObjectiveFunction(CmsMarketCalibration *smileAndCms)
34 : smileAndCms_(smileAndCms), volCube_(smileAndCms->volCube_),
35 cmsMarket_(smileAndCms->cmsMarket_),
36 weights_(smileAndCms->weights_),
37 calibrationType_(smileAndCms->calibrationType_) {};
38
39 Real value(const Array& x) const override;
40 Array values(const Array& x) const override;
41
42 protected:
43 Real switchErrorFunctionOnCalibrationType() const;
44 Array switchErrorsFunctionOnCalibrationType() const;
45
46 CmsMarketCalibration *smileAndCms_;
48 ext::shared_ptr<CmsMarket> cmsMarket_;
49 Matrix weights_;
51
52 private:
53 virtual void updateVolatilityCubeAndCmsMarket(const Array &x) const;
54 };
55
56 class ObjectiveFunction2 : public ObjectiveFunction {
57 public:
58 ObjectiveFunction2(CmsMarketCalibration *smileAndCms,
59 Real fixedMeanReversion)
60 : ObjectiveFunction(smileAndCms),
61 fixedMeanReversion_(fixedMeanReversion) {};
62
63 private:
64 void updateVolatilityCubeAndCmsMarket(const Array& x) const override;
65 Real fixedMeanReversion_;
66 };
67
68 class ObjectiveFunction3 : public ObjectiveFunction {
69 public:
70 explicit ObjectiveFunction3(CmsMarketCalibration *smileAndCms)
71 : ObjectiveFunction(smileAndCms) {};
72
73 private:
74 void updateVolatilityCubeAndCmsMarket(const Array& x) const override;
75 };
76
77 class ObjectiveFunction4 : public ObjectiveFunction {
78 public:
79 ObjectiveFunction4(CmsMarketCalibration *smileAndCms,
80 Real fixedMeanReversion)
81 : ObjectiveFunction(smileAndCms),
82 fixedMeanReversion_(fixedMeanReversion) {};
83
84 private:
85 void updateVolatilityCubeAndCmsMarket(const Array& x) const override;
86 Real fixedMeanReversion_;
87 };
88
89 class ObjectiveFunction5 : public ObjectiveFunction {
90 public:
91 ObjectiveFunction5(CmsMarketCalibration *smileAndCms,
92 Real fixedMeanReversion)
93 : ObjectiveFunction(smileAndCms),
94 fixedMeanReversion_(fixedMeanReversion) {};
95
96 private:
97 void updateVolatilityCubeAndCmsMarket(const Array& x) const override;
98 Real fixedMeanReversion_;
99 };
100
101 class ObjectiveFunction6 : public ObjectiveFunction {
102 public:
103 explicit ObjectiveFunction6(CmsMarketCalibration *smileAndCms)
104 : ObjectiveFunction(smileAndCms) {};
105
106 private:
107 void updateVolatilityCubeAndCmsMarket(const Array& x) const override;
108 };
109
110 //===========================================================================//
111 // ObjectiveFunction (constant beta, free mean reversion) //
112 //===========================================================================//
113
114 Real ObjectiveFunction::value(const Array &x) const {
115 updateVolatilityCubeAndCmsMarket(x);
116 return switchErrorFunctionOnCalibrationType();
117 }
118
119 Array ObjectiveFunction::values(const Array &x) const {
120 updateVolatilityCubeAndCmsMarket(x);
121 return switchErrorsFunctionOnCalibrationType();
122 }
123
124 void
125 ObjectiveFunction::updateVolatilityCubeAndCmsMarket(const Array &x) const {
126 const std::vector<Period> &swapTenors = cmsMarket_->swapTenors();
127 Size nSwapTenors = swapTenors.size();
128 QL_REQUIRE(nSwapTenors + 1 == x.size(),
129 "bad calibration guess nSwapTenors+1 != x.size()");
130 const ext::shared_ptr<SabrSwaptionVolatilityCube> volCubeBySabr =
131 ext::dynamic_pointer_cast<SabrSwaptionVolatilityCube>(*volCube_);
132 for (Size i = 0; i < nSwapTenors; ++i)
133 volCubeBySabr->recalibration(CmsMarketCalibration::betaTransformDirect(x[i]),
134 swapTenors[i]);
135 Real meanReversion =
137 cmsMarket_->reprice(volCube_, meanReversion);
138 }
139
140 Real ObjectiveFunction::switchErrorFunctionOnCalibrationType() const {
141 switch (calibrationType_) {
143 return cmsMarket_->weightedSpreadError(weights_);
145 return cmsMarket_->weightedSpotNpvError(weights_);
147 return cmsMarket_->weightedFwdNpvError(weights_);
148 default:
149 QL_FAIL("unknown/illegal calibration type");
150 }
151 }
152
153 Array ObjectiveFunction::switchErrorsFunctionOnCalibrationType() const {
154 switch (calibrationType_) {
156 return cmsMarket_->weightedSpreadErrors(weights_);
158 return cmsMarket_->weightedSpotNpvErrors(weights_);
160 return cmsMarket_->weightedFwdNpvErrors(weights_);
161 default:
162 QL_FAIL("unknown/illegal calibration type");
163 }
164 }
165
166 //===========================================================================//
167 // ObjectiveFunction2 (constant beta, fixed mean reversion) //
168 //===========================================================================//
169
170 void
171 ObjectiveFunction2::updateVolatilityCubeAndCmsMarket(const Array &x) const {
172 const std::vector<Period> &swapTenors = cmsMarket_->swapTenors();
173 Size nSwapTenors = swapTenors.size();
174 QL_REQUIRE(nSwapTenors == x.size(),
175 "bad calibration guess nSwapTenors != x.size()");
176 const ext::shared_ptr<SabrSwaptionVolatilityCube> volCubeBySabr =
177 ext::dynamic_pointer_cast<SabrSwaptionVolatilityCube>(*volCube_);
178 for (Size i = 0; i < nSwapTenors; ++i)
179 volCubeBySabr->recalibration(QuantLib::CmsMarketCalibration::betaTransformDirect(x[i]),
180 swapTenors[i]);
181 cmsMarket_->reprice(volCube_, fixedMeanReversion_ == Null<Real>() ?
182 Null<Real>() :
184 fixedMeanReversion_));
185 }
186
187 //===========================================================================//
188 // ObjectiveFunction3 (beta termstructure, free mean reversion) //
189 //===========================================================================//
190
191 void
192 ObjectiveFunction3::updateVolatilityCubeAndCmsMarket(const Array &x) const {
193 const std::vector<Period> &swapTenors = cmsMarket_->swapTenors();
194 const std::vector<Period> &swapLengths = cmsMarket_->swapLengths();
195 Size nSwapTenors = swapTenors.size();
196 Size nSwapLengths = swapLengths.size();
197 QL_REQUIRE(
198 (nSwapLengths * nSwapTenors) + 1 == x.size(),
199 "bad calibration guess (nSwapLengths*nSwapTenors)+1 != x.size()");
200 const ext::shared_ptr<SabrSwaptionVolatilityCube> volCubeBySabr =
201 ext::dynamic_pointer_cast<SabrSwaptionVolatilityCube>(*volCube_);
202 for (Size i = 0; i < nSwapTenors; ++i) {
203 std::vector<Real> beta(x.begin() + (i * nSwapLengths),
204 x.begin() + ((i + 1) * nSwapLengths));
205 for (Real& j : beta)
207 volCubeBySabr->recalibration(swapLengths, beta, swapTenors[i]);
208 }
209 Real meanReversion =
210 CmsMarketCalibration::reversionTransformDirect(x[nSwapLengths + nSwapTenors]);
211 cmsMarket_->reprice(volCube_, meanReversion);
212 }
213
214 //===========================================================================//
215 // ObjectiveFunction4 (beta termstructure, fixed mean reversion) //
216 //===========================================================================//
217
218 void
219 ObjectiveFunction4::updateVolatilityCubeAndCmsMarket(const Array &x) const {
220 const std::vector<Period> &swapTenors = cmsMarket_->swapTenors();
221 const std::vector<Period> &swapLengths = cmsMarket_->swapLengths();
222 Size nSwapTenors = swapTenors.size();
223 Size nSwapLengths = swapLengths.size();
224 QL_REQUIRE(
225 (nSwapLengths * nSwapTenors) == x.size(),
226 "bad calibration guess (nSwapLengths*nSwapTenors) != x.size()");
227 const ext::shared_ptr<SabrSwaptionVolatilityCube> volCubeBySabr =
228 ext::dynamic_pointer_cast<SabrSwaptionVolatilityCube>(*volCube_);
229 for (Size i = 0; i < nSwapTenors; ++i) {
230 std::vector<Real> beta(x.begin() + (i * nSwapLengths),
231 x.begin() + ((i + 1) * nSwapLengths));
232 for (Real& j : beta)
234 volCubeBySabr->recalibration(swapLengths, beta, swapTenors[i]);
235 }
236 cmsMarket_->reprice(volCube_, fixedMeanReversion_ == Null<Real>() ?
237 Null<Real>() :
239 fixedMeanReversion_));
240 }
241
242 //=============================================================================//
243 // ObjectiveFunction5 (beta parameteric termstructure, fixed mean reversion) //
244 //=============================================================================//
245
246 void
247 ObjectiveFunction5::updateVolatilityCubeAndCmsMarket(const Array &x) const {
248 const std::vector<Period> &swapTenors = cmsMarket_->swapTenors();
249 const std::vector<Period> &swapLengths = cmsMarket_->swapLengths();
250 Size nSwapTenors = swapTenors.size();
251 Size nSwapLengths = swapLengths.size();
252 QL_REQUIRE((3 * nSwapTenors) == x.size(),
253 "bad calibration guess (3*nSwapTenors) != x.size()");
254 const ext::shared_ptr<SabrSwaptionVolatilityCube> volCubeBySabr =
255 ext::dynamic_pointer_cast<SabrSwaptionVolatilityCube>(*volCube_);
256 for (Size i = 0; i < nSwapTenors; ++i) {
257 Real betaInf = CmsMarketCalibration::betaTransformDirect(x[0 + 3 * i]);
259 Real decay = x[2 + 3 * i] * x[2 + 3 * i];
260 std::vector<Real> beta(nSwapLengths);
261 for (Size j = 0; j < beta.size(); ++j) {
262 Real t = smileAndCms_->volCube_->timeFromReference(
263 smileAndCms_->volCube_->optionDateFromTenor(swapLengths[j]));
264 beta[j] = betaInf + (beta0 - betaInf) * std::exp(-decay * t);
265 }
266 volCubeBySabr->recalibration(swapLengths, beta, swapTenors[i]);
267 }
268 cmsMarket_->reprice(volCube_, fixedMeanReversion_ == Null<Real>() ?
269 Null<Real>() :
271 fixedMeanReversion_));
272 }
273
274 //===========================================================================//
275 // ObjectiveFunction6 (beta parameteric termstructure, free mean reversion) //
276 //===========================================================================//
277
278 void
279 ObjectiveFunction6::updateVolatilityCubeAndCmsMarket(const Array &x) const {
280 const std::vector<Period> &swapTenors = cmsMarket_->swapTenors();
281 const std::vector<Period> &swapLengths = cmsMarket_->swapLengths();
282 Size nSwapTenors = swapTenors.size();
283 Size nSwapLengths = swapLengths.size();
284 QL_REQUIRE((3 * nSwapTenors) == x.size(),
285 "bad calibration guess (3*nSwapTenors) != x.size()");
286 const ext::shared_ptr<SabrSwaptionVolatilityCube> volCubeBySabr =
287 ext::dynamic_pointer_cast<SabrSwaptionVolatilityCube>(*volCube_);
288 for (Size i = 0; i < nSwapTenors; ++i) {
289 Real betaInf = CmsMarketCalibration::betaTransformDirect(x[0 + 3 * i]);
291 Real decay = x[2 + 3 * i] * x[2 + 3 * i];
292 std::vector<Real> beta(nSwapLengths);
293 for (Size j = 0; j < beta.size(); ++j) {
294 Real t = smileAndCms_->volCube_->timeFromReference(
295 smileAndCms_->volCube_->optionDateFromTenor(swapLengths[j]));
296 beta[j] = betaInf + (beta0 - betaInf) * std::exp(-decay * t);
297 }
298 volCubeBySabr->recalibration(swapLengths, beta, swapTenors[i]);
299 }
300 Real meanReversion =
302 cmsMarket_->reprice(volCube_, meanReversion);
303 }
304}
305
306namespace QuantLib {
307
308 //===========================================================================//
309 // CmsMarketCalibration //
310 //===========================================================================//
311
314 ext::shared_ptr<CmsMarket> &cmsMarket, const Matrix &weights,
315 CalibrationType calibrationType)
316 : volCube_(volCube), cmsMarket_(cmsMarket), weights_(weights),
317 calibrationType_(calibrationType) {
318
319 QL_REQUIRE(weights.rows() == cmsMarket_->swapLengths().size(),
320 "weights number of rows ("
321 << weights.rows()
322 << ") must be equal to number of swap lengths ("
323 << cmsMarket_->swapLengths().size() << ")");
324 QL_REQUIRE(weights.columns() == cmsMarket_->swapTenors().size(),
325 "weights number of columns ("
326 << weights.columns()
327 << ") must be equal to number of swap indexes ("
328 << cmsMarket_->swapTenors().size());
329 }
330
332 const ext::shared_ptr<EndCriteria> &endCriteria,
333 const ext::shared_ptr<OptimizationMethod> &method, const Array &guess,
334 bool isMeanReversionFixed) {
335 Size nSwapTenors = cmsMarket_->swapTenors().size();
336 QL_REQUIRE(isMeanReversionFixed || guess.size() == nSwapTenors + 1,
337 "if mean reversion is not fixed, a guess must be provided");
338 QL_REQUIRE(nSwapTenors == guess.size() ||
339 nSwapTenors == guess.size() - 1,
340 "guess size (" << guess.size()
341 << ") must be equal to swap tenors size ("
342 << nSwapTenors
343 << ") or greater by one if mean reversion is "
344 "given as last element");
345 bool isMeanReversionGiven = (nSwapTenors == guess.size() - 1);
346 Size nBeta = guess.size() - (isMeanReversionGiven ? 1 : 0);
347 Array result;
348 if (isMeanReversionFixed) {
349 NoConstraint constraint;
350 Real fixedMeanReversion =
351 isMeanReversionGiven ? guess[nBeta] : Null<Real>();
352 Array betasGuess(nBeta);
353 for (Size i = 0; i < nBeta; ++i)
354 betasGuess[i] = guess[i];
355 ObjectiveFunction2 costFunction(
356 this, fixedMeanReversion == Null<Real>()
357 ? Null<Real>()
358 : reversionTransformInverse(fixedMeanReversion));
359 Problem problem(costFunction, constraint, betasGuess);
360 endCriteria_ = method->minimize(problem, *endCriteria);
361 Array tmp = problem.currentValue();
362 error_ = costFunction.value(tmp);
363 result = Array(nBeta + (isMeanReversionGiven ? 1 : 0));
364 for (Size i = 0; i < nBeta; ++i)
365 result[i] = betaTransformDirect(tmp[i]);
366 if (isMeanReversionGiven)
367 result[nBeta] = fixedMeanReversion;
368 } else {
369 NoConstraint constraint;
370 ObjectiveFunction costFunction(this);
371 Array betaReversionGuess(nBeta + 1);
372 for (Size i = 0; i < nBeta; ++i)
373 betaReversionGuess[i] = betaTransformInverse(guess[i]);
374 betaReversionGuess[nBeta] = reversionTransformInverse(guess[nBeta]);
375 Problem problem(costFunction, constraint, betaReversionGuess);
376 endCriteria_ = method->minimize(problem, *endCriteria);
377 result = problem.currentValue();
378 error_ = costFunction.value(result);
379 for (Size i = 0; i < nBeta; ++i)
380 result[i] = betaTransformDirect(result[i]);
381 result[nBeta] = reversionTransformDirect(result[nBeta]);
382 }
383 const ext::shared_ptr<SabrSwaptionVolatilityCube> volCubeBySabr =
384 ext::dynamic_pointer_cast<SabrSwaptionVolatilityCube>(*volCube_);
385 volCubeBySabr->updateAfterRecalibration();
386 sparseSabrParameters_ = volCubeBySabr->sparseSabrParameters();
387 denseSabrParameters_ = volCubeBySabr->denseSabrParameters();
388 browseCmsMarket_ = cmsMarket_->browse();
389
390 return result;
391 }
392
394 const ext::shared_ptr<EndCriteria> &endCriteria,
395 const ext::shared_ptr<OptimizationMethod> &method,
396 const Matrix &guess, bool isMeanReversionFixed,
397 const Real meanReversionGuess) {
398 Size nSwapTenors = cmsMarket_->swapTenors().size();
399 Size nSwapLengths = cmsMarket_->swapLengths().size();
400 QL_REQUIRE(isMeanReversionFixed || meanReversionGuess != Null<Real>(),
401 "if mean reversion is not fixed, a guess must be provided");
402 QL_REQUIRE(nSwapTenors == guess.columns(),
403 "number of swap tenors ("
404 << nSwapTenors
405 << ") must be equal to number of guess columns ("
406 << guess.columns() << ")");
407 QL_REQUIRE(nSwapLengths == guess.rows(),
408 "number of swap lengths ("
409 << nSwapLengths
410 << ") must be equal to number of guess rows ("
411 << guess.rows() << ")");
412 Matrix result;
413 Size nBeta = nSwapTenors * nSwapLengths;
414 if (isMeanReversionFixed) {
415 NoConstraint constraint;
416 Array betasGuess(nBeta);
417 for (Size i = 0; i < nSwapTenors; ++i) {
418 for (Size j = 0; j < nSwapLengths; ++j) {
419 betasGuess[i * nSwapLengths + j] =
420 betaTransformInverse(guess[j][i]);
421 }
422 }
423 ObjectiveFunction4 costFunction(
424 this, meanReversionGuess == Null<Real>()
425 ? meanReversionGuess
426 : reversionTransformInverse(meanReversionGuess));
427 Problem problem(costFunction, constraint, betasGuess);
428 endCriteria_ = method->minimize(problem, *endCriteria);
429 Array tmp = problem.currentValue();
430 error_ = costFunction.value(tmp);
431 result = Matrix(nSwapLengths,
432 nSwapTenors +
433 (meanReversionGuess != Null<Real>() ? 1 : 0));
434 for (Size i = 0; i < nSwapTenors; ++i) {
435 for (Size j = 0; j < nSwapLengths; ++j) {
436 result[j][i] =
437 betaTransformDirect(tmp[i * nSwapLengths + j]);
438 }
439 }
440 if (meanReversionGuess != Null<Real>()) {
441 for (Size j = 0; j < nSwapLengths; ++j) {
442 result[j][nSwapTenors] = meanReversionGuess;
443 }
444 }
445 } else {
446 NoConstraint constraint;
447 Array betasReversionGuess(nBeta + 1);
448 for (Size i = 0; i < nSwapTenors; ++i) {
449 for (Size j = 0; j < nSwapLengths; ++j) {
450 betasReversionGuess[i * nSwapLengths + j] =
451 betaTransformInverse(guess[j][i]);
452 }
453 }
454 betasReversionGuess[nBeta] =
455 reversionTransformInverse(meanReversionGuess);
456 ObjectiveFunction3 costFunction(this);
457 Problem problem(costFunction, constraint, betasReversionGuess);
458 endCriteria_ = method->minimize(problem, *endCriteria);
459 Array tmp = problem.currentValue();
460 error_ = costFunction.value(tmp);
461 result = Matrix(nSwapLengths, nSwapTenors + 1);
462 for (Size i = 0; i < nSwapTenors; ++i) {
463 for (Size j = 0; j < nSwapLengths; ++j) {
464 result[j][i] =
465 betaTransformDirect(tmp[i * nSwapLengths + j]);
466 }
467 }
468 for (Size j = 0; j < nSwapLengths; ++j) {
469 result[j][nSwapTenors] = reversionTransformDirect(tmp[nBeta]);
470 }
471 }
472 const ext::shared_ptr<SabrSwaptionVolatilityCube> volCubeBySabr =
473 ext::dynamic_pointer_cast<SabrSwaptionVolatilityCube>(*volCube_);
474 volCubeBySabr->updateAfterRecalibration();
475 sparseSabrParameters_ = volCubeBySabr->sparseSabrParameters();
476 denseSabrParameters_ = volCubeBySabr->denseSabrParameters();
477 browseCmsMarket_ = cmsMarket_->browse();
478
479 return result;
480 }
481
483 const ext::shared_ptr<EndCriteria> &endCriteria,
484 const ext::shared_ptr<OptimizationMethod> &method,
485 const Matrix &guess, bool isMeanReversionFixed,
486 const Real meanReversionGuess) {
487
488 Size nSwapTenors = cmsMarket_->swapTenors().size();
489 Size nSwapLengths = cmsMarket_->swapLengths().size();
490 QL_REQUIRE(isMeanReversionFixed || meanReversionGuess != Null<Real>(),
491 "if mean reversion is not fixed, a guess must be provided");
492 QL_REQUIRE(nSwapTenors == guess.columns(),
493 "number of swap tenors ("
494 << nSwapTenors
495 << ") must be equal to number of guess columns ("
496 << guess.columns() << ")");
497 QL_REQUIRE(3 == guess.rows(),
498 "number of parameters ("
499 << 3 << ") must be equal to number of guess rows ("
500 << guess.rows() << ")");
501
502 Matrix result;
503 Size nParams = nSwapTenors * 3;
504 if (isMeanReversionFixed) {
505 NoConstraint constraint;
506 Array betasGuess(nParams);
507 for (Size i = 0; i < nSwapTenors; ++i) {
508 for (Size j = 0; j < nParams; ++j) {
509 betasGuess[i * 3 + j] =
510 (j == 0 || j == 1) ? betaTransformInverse(guess[j][i])
511 : std::sqrt(guess[j][i]);
512 }
513 }
514 ObjectiveFunction5 costFunction(
515 this, meanReversionGuess == Null<Real>()
516 ? meanReversionGuess
517 : reversionTransformInverse(meanReversionGuess));
518 Problem problem(costFunction, constraint, betasGuess);
519 endCriteria_ = method->minimize(problem, *endCriteria);
520 Array tmp = problem.currentValue();
521 error_ = costFunction.value(tmp);
522 result = Matrix(
523 3, nSwapTenors + (meanReversionGuess != Null<Real>() ? 1 : 0));
524 for (Size i = 0; i < nSwapTenors; ++i) {
525 for (Size j = 0; j < 3; ++j) {
526 result[j][i] = (j == 0 || j == 1)
527 ? betaTransformDirect(tmp[i * 3 + j])
528 : tmp[i * 3 + j] * tmp[i * 3 + j];
529 }
530 }
531 if (meanReversionGuess != Null<Real>()) {
532 for (Size j = 0; j < nSwapLengths; ++j) {
533 result[j][nSwapTenors] = meanReversionGuess;
534 }
535 }
536 } else {
537 NoConstraint constraint;
538 Array betasReversionGuess(nParams + 1);
539 for (Size i = 0; i < nSwapTenors; ++i) {
540 for (Size j = 0; j < nParams; ++j) {
541 betasReversionGuess[i * nSwapLengths + j] =
542 (j == 0 || j == 1) ? betaTransformInverse(guess[j][i])
543 : std::sqrt(guess[j][i]);
544 }
545 }
546 betasReversionGuess[nParams] =
547 reversionTransformInverse(meanReversionGuess);
548 ObjectiveFunction6 costFunction(this);
549 Problem problem(costFunction, constraint, betasReversionGuess);
550 endCriteria_ = method->minimize(problem, *endCriteria);
551 Array tmp = problem.currentValue();
552 error_ = costFunction.value(tmp);
553 result = Matrix(3, nSwapTenors + 1);
554 for (Size i = 0; i < nSwapTenors; ++i) {
555 for (Size j = 0; j < 3; ++j) {
556 result[j][i] =
557 (j == 0 || j == 1)
558 ? betaTransformDirect(tmp[i * nSwapLengths + j])
559 : tmp[i * 3 + j] * tmp[i * 3 + j];
560 }
561 }
562 for (Size j = 0; j < nSwapLengths; ++j) {
563 result[j][nSwapTenors] = reversionTransformDirect(tmp[nParams]);
564 }
565 }
566
567 const ext::shared_ptr<SabrSwaptionVolatilityCube> volCubeBySabr =
568 ext::dynamic_pointer_cast<SabrSwaptionVolatilityCube>(*volCube_);
569 volCubeBySabr->updateAfterRecalibration();
570 sparseSabrParameters_ = volCubeBySabr->sparseSabrParameters();
571 denseSabrParameters_ = volCubeBySabr->denseSabrParameters();
572 browseCmsMarket_ = cmsMarket_->browse();
573
574 return result;
575 }
576}
1-D array used in linear algebra.
Definition: array.hpp:52
Size size() const
dimension of the array
Definition: array.hpp:495
const_iterator begin() const
Definition: array.hpp:503
static Real reversionTransformDirect(Real y)
static Real betaTransformInverse(Real beta)
Matrix computeParametric(const ext::shared_ptr< EndCriteria > &endCriteria, const ext::shared_ptr< OptimizationMethod > &method, const Matrix &guess, bool isMeanReversionFixed, Real meanReversionGuess=Null< Real >())
Array compute(const ext::shared_ptr< EndCriteria > &endCriteria, const ext::shared_ptr< OptimizationMethod > &method, const Array &guess, bool isMeanReversionFixed)
static Real reversionTransformInverse(Real reversion)
CmsMarketCalibration(Handle< SwaptionVolatilityStructure > &volCube, ext::shared_ptr< CmsMarket > &cmsMarket, const Matrix &weights, CalibrationType calibrationType)
ext::shared_ptr< CmsMarket > cmsMarket_
Handle< SwaptionVolatilityStructure > volCube_
Cost function abstract class for optimization problem.
virtual Array values(const Array &x) const =0
method to overload to compute the cost function values in x
virtual Real value(const Array &x) const
method to overload to compute the cost function value in x
Shared handle to an observable.
Definition: handle.hpp:41
Matrix used in linear algebra.
Definition: matrix.hpp:41
Size rows() const
Definition: matrix.hpp:504
Size columns() const
Definition: matrix.hpp:508
No constraint.
Definition: constraint.hpp:79
template class providing a null value for a given type.
Definition: null.hpp:76
Constrained optimization problem.
Definition: problem.hpp:42
const Array & currentValue() const
current value of the local minimum
Definition: problem.hpp:81
QL_REAL Real
real number
Definition: types.hpp:50
std::size_t Size
size of a container
Definition: types.hpp:58
Definition: any.hpp:35