1 /* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 3 /* 4 5 Copyright (C) 2007 Mark Joshi 6 7 This file is part of QuantLib, a free-software/open-source library 8 for financial quantitative analysts and developers - http://quantlib.org/ 9 10 QuantLib is free software: you can redistribute it and/or modify it 11 under the terms of the QuantLib license. You should have received a 12 copy of the license along with this program; if not, please email 13 <quantlib-dev@lists.sf.net>. The license is also available online at 14 <http://quantlib.org/license.shtml>. 15 16 This program is distributed in the hope that it will be useful, but WITHOUT 17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 18 FOR A PARTICULAR PURPOSE. See the license for more details. 19 */ 20 21 #include <ql/models/marketmodels/models/capletcoterminalperiodic.hpp> 22 #include <ql/models/marketmodels/models/capletcoterminalmaxhomogeneity.hpp> 23 #include <ql/models/marketmodels/models/piecewiseconstantvariance.hpp> 24 #include <ql/models/marketmodels/models/volatilityinterpolationspecifier.hpp> 25 #include <ql/math/matrix.hpp> 26 #include <ql/models/marketmodels/curvestate.hpp> 27 #include <ql/models/marketmodels/evolutiondescription.hpp> 28 #include <ql/models/marketmodels/piecewiseconstantcorrelation.hpp> 29 #include <ql/models/marketmodels/models/pseudorootfacade.hpp> 30 #include <ql/models/marketmodels/models/cotswaptofwdadapter.hpp> 31 #include <ql/models/marketmodels/models/fwdperiodadapter.hpp> 32 #include <ql/models/marketmodels/models/fwdtocotswapadapter.hpp> 33 #include <ql/shared_ptr.hpp> 34 #include <vector> 35 36 namespace QuantLib 37 { 38 39 // for the displaced swap 40 capletSwaptionPeriodicCalibration(const EvolutionDescription & evolution,const ext::shared_ptr<PiecewiseConstantCorrelation> & corr,VolatilityInterpolationSpecifier & displacedSwapVariances,const std::vector<Volatility> & capletVols,const ext::shared_ptr<CurveState> & cs,const Spread displacement,Real caplet0Swaption1Priority,Size numberOfFactors,Size period,Size max1dIterations,Real tolerance1d,Size maxUnperiodicIterations,Real toleranceUnperiodic,Size maxPeriodIterations,Real periodTolerance,Real &,Real & totalSwaptionError,std::vector<Matrix> & swapCovariancePseudoRoots,std::vector<Real> & finalScales,Size & iterationsDone,Real & errorImprovement,Matrix & modelSwaptionVolsMatrix)41 Integer capletSwaptionPeriodicCalibration( 42 const EvolutionDescription& evolution, 43 const ext::shared_ptr<PiecewiseConstantCorrelation>& corr, 44 VolatilityInterpolationSpecifier& 45 displacedSwapVariances, 46 const std::vector<Volatility>& capletVols, 47 const ext::shared_ptr<CurveState>& cs, 48 const Spread displacement, 49 Real caplet0Swaption1Priority, 50 Size numberOfFactors, 51 Size period, 52 Size max1dIterations, 53 Real tolerance1d, 54 Size maxUnperiodicIterations, 55 Real toleranceUnperiodic, 56 Size maxPeriodIterations, 57 Real periodTolerance, 58 Real& , // deformationSize used to return information, not set yet 59 Real& totalSwaptionError, // ? 60 std::vector<Matrix>& swapCovariancePseudoRoots, // the thing we really want the pseudo root for each time step 61 std::vector<Real> & finalScales, //scalings used for matching 62 Size& iterationsDone, // number of period iteratations done 63 Real& errorImprovement, // improvement in error for last iteration 64 Matrix& modelSwaptionVolsMatrix // the swaption vols calibrated to at each step of the iteration 65 ) 66 { 67 68 Size numberSmallRates = evolution.numberOfRates(); 69 Size numberSmallSteps = evolution.numberOfSteps(); 70 71 QL_REQUIRE( numberSmallSteps == numberSmallRates, 72 "periodic calibration class requires evolution to the reset of each rate"); 73 74 Size numberBigRates = numberSmallRates/period; 75 Size offset = numberSmallRates % period; 76 77 std::vector<Spread> newDisplacements(numberBigRates,displacement); 78 79 QL_REQUIRE(displacedSwapVariances.getNoBigRates() == numberBigRates, 80 "mismatch between number of swap variances given and number of rates and period"); 81 82 Integer failures=0; 83 84 85 std::vector<Real> scalingFactors(numberBigRates); 86 for (Size i=0; i < numberBigRates; ++i) 87 scalingFactors[i] =1.0; 88 89 displacedSwapVariances.setLastCapletVol(*capletVols.rbegin()); 90 91 92 std::vector<Real> marketSwaptionVols(numberBigRates); 93 for (Size i=0; i < numberBigRates; ++i) { 94 marketSwaptionVols[i] = 95 displacedSwapVariances.originalVariances()[i]->totalVolatility(i); 96 } 97 98 std::vector<Real> modelSwaptionVols(numberBigRates); 99 100 Real periodSwaptionRmsError; 101 102 iterationsDone = 0; 103 104 Real previousError = 1.0e+10; // very large number 105 106 107 modelSwaptionVolsMatrix =Matrix(maxPeriodIterations,numberBigRates,0.0); 108 109 110 do 111 { 112 displacedSwapVariances.setScalingFactors(scalingFactors); 113 114 115 CTSMMCapletMaxHomogeneityCalibration unperiodicCalibrator( 116 evolution, 117 corr, 118 displacedSwapVariances.interpolatedVariances(), 119 capletVols, 120 cs, 121 displacement, 122 caplet0Swaption1Priority); 123 124 125 failures = static_cast<QuantLib::Integer>( 126 unperiodicCalibrator.calibrate(numberOfFactors, maxUnperiodicIterations, 127 toleranceUnperiodic, max1dIterations, tolerance1d)); 128 129 swapCovariancePseudoRoots = unperiodicCalibrator.swapPseudoRoots(); 130 131 ext::shared_ptr<MarketModel> smm(new 132 PseudoRootFacade(swapCovariancePseudoRoots, 133 evolution.rateTimes(), 134 cs->coterminalSwapRates(), 135 std::vector<Spread>(evolution.numberOfRates(), displacement))); 136 137 ext::shared_ptr<MarketModel> flmm(new CotSwapToFwdAdapter(smm)); 138 139 Matrix capletTotCovariance = flmm->totalCovariance(numberSmallRates-1); 140 141 ext::shared_ptr<MarketModel> periodflmm( new FwdPeriodAdapter(flmm, period, 142 offset, 143 newDisplacements)); 144 145 ext::shared_ptr<MarketModel> periodsmm(new FwdToCotSwapAdapter(periodflmm)); 146 147 148 Matrix swaptionTotCovariance(periodsmm->totalCovariance(periodsmm->numberOfSteps()-1)); 149 150 151 152 totalSwaptionError=0.0; 153 154 for (Size i=0; i < numberBigRates; ++i) 155 { 156 modelSwaptionVols[i] = std::sqrt(swaptionTotCovariance[i][i]/periodsmm->evolution().rateTimes()[i]); 157 Real scale = marketSwaptionVols[i]/modelSwaptionVols[i]; 158 scalingFactors[i] *= scale; // since applied to vol 159 160 totalSwaptionError += (marketSwaptionVols[i]-modelSwaptionVols[i])* (marketSwaptionVols[i]-modelSwaptionVols[i]); 161 162 } 163 164 for (Size i=0; i < numberBigRates; ++i) 165 modelSwaptionVolsMatrix[iterationsDone][i] = modelSwaptionVols[i]; 166 167 periodSwaptionRmsError = std::sqrt(totalSwaptionError/numberBigRates); 168 errorImprovement = previousError -periodSwaptionRmsError; 169 previousError = periodSwaptionRmsError; 170 } 171 while (errorImprovement> periodTolerance/10.0 && periodSwaptionRmsError >periodTolerance && ++iterationsDone < maxPeriodIterations); 172 173 finalScales = scalingFactors; 174 175 return failures; 176 177 } 178 179 180 } 181