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 implementation specifies how to decide volatility structure for additional 22 synthetic rates which are interleaved 23 24 here we work with abcd curves and interpolate the a, b, c and d 25 26 */ 27 28 #include <ql/models/marketmodels/models/volatilityinterpolationspecifierabcd.hpp> 29 #include <ql/types.hpp> 30 #include <ql/errors.hpp> 31 #include <ql/shared_ptr.hpp> 32 #include <vector> 33 34 namespace QuantLib 35 { 36 VolatilityInterpolationSpecifierabcd(Size period,Size offset,const std::vector<PiecewiseConstantAbcdVariance> & originalVariances,const std::vector<Time> & timesForSmallRates,Real lastCapletVol)37 VolatilityInterpolationSpecifierabcd::VolatilityInterpolationSpecifierabcd(Size period, 38 Size offset, 39 const std::vector< PiecewiseConstantAbcdVariance>& originalVariances, // these should be associated with the long rates 40 const std::vector<Time>& timesForSmallRates, // these should be associated with the shorter rates 41 Real lastCapletVol 42 ) 43 : 44 period_(period), 45 offset_(offset), 46 interpolatedVariances_(timesForSmallRates.size()-1), 47 originalVariances_(originalVariances.size()), 48 originalABCDVariances_(originalVariances), 49 originalABCDVariancesScaled_(originalVariances), 50 lastCapletVol_(lastCapletVol), 51 timesForSmallRates_(timesForSmallRates), 52 scalingFactors_(originalVariances.size(),1.0), 53 noBigRates_(originalVariances.size()), 54 noSmallRates_(timesForSmallRates.size()-1) 55 { 56 QL_REQUIRE( (noSmallRates_ - offset) /period == noBigRates_, "size mismatch in VolatilityInterpolationSpecifierabcd"); 57 58 for (Size i=0; i < noBigRates_; ++i) 59 for (Size j=0; j < originalVariances[i].rateTimes().size(); ++j) 60 QL_REQUIRE( originalVariances[i].rateTimes()[j] == timesForSmallRates[offset+j*period],"rate times in variances passed in don't match small times in VolatilityInterpolationSpecifierabcd"); 61 62 if (lastCapletVol_ == 0.0) 63 lastCapletVol_ = originalVariances[noBigRates_-1].totalVolatility(noBigRates_-1); 64 65 // change type of array to PiecewiseConstantVariance for client, from PiecewiseConstantAbcdVariance 66 for (Size i=0; i < noBigRates_; ++i) 67 originalVariances_[i] = ext::shared_ptr<PiecewiseConstantVariance>(new PiecewiseConstantAbcdVariance(originalVariances[i])); 68 69 recompute(); 70 71 } 72 ~VolatilityInterpolationSpecifierabcd()73 VolatilityInterpolationSpecifierabcd::~VolatilityInterpolationSpecifierabcd() 74 { 75 } 76 setScalingFactors(const std::vector<Real> & scales)77 void VolatilityInterpolationSpecifierabcd::setScalingFactors(const std::vector<Real>& scales) 78 { 79 QL_REQUIRE(scalingFactors_.size() == scales.size(), "inappropriate number of scales passed in to VolatilityInterpolationSpecifierabcd::setScalingFactors "); 80 scalingFactors_= scales; 81 recompute(); 82 } 83 setLastCapletVol(Real vol)84 void VolatilityInterpolationSpecifierabcd::setLastCapletVol(Real vol) 85 { 86 lastCapletVol_ = vol; 87 recompute(); 88 } 89 90 interpolatedVariances() const91 const std::vector<ext::shared_ptr<PiecewiseConstantVariance> >& VolatilityInterpolationSpecifierabcd::interpolatedVariances() const 92 { 93 return interpolatedVariances_; 94 } 95 originalVariances() const96 const std::vector<ext::shared_ptr<PiecewiseConstantVariance> >& VolatilityInterpolationSpecifierabcd::originalVariances() const 97 { 98 return originalVariances_; 99 } 100 getPeriod() const101 Size VolatilityInterpolationSpecifierabcd::getPeriod() const 102 { 103 return period_; 104 } 105 getOffset() const106 Size VolatilityInterpolationSpecifierabcd::getOffset() const 107 { 108 return offset_; 109 } 110 getNoBigRates() const111 Size VolatilityInterpolationSpecifierabcd::getNoBigRates() const 112 { 113 return noBigRates_; 114 } getNoSmallRates() const115 Size VolatilityInterpolationSpecifierabcd::getNoSmallRates() const 116 { 117 return noSmallRates_; 118 } 119 120 recompute()121 void VolatilityInterpolationSpecifierabcd::recompute() 122 { 123 // PiecewiseConstantAbcdVariance(Real a, Real b, Real c, Real d, 124 // Size resetIndex, 125 // const std::vector<Time>& rateTimes); 126 127 128 for (Size i=0; i < noBigRates_; ++i) 129 { 130 Real a,b,c,d; 131 originalABCDVariances_[i].getABCD(a,b,c,d); 132 a*=scalingFactors_[i]; 133 b*=scalingFactors_[i]; 134 // c is not scaled 135 d*=scalingFactors_[i]; 136 137 originalABCDVariancesScaled_[i] = PiecewiseConstantAbcdVariance(a,b,c,d, i, originalABCDVariances_[i].rateTimes()); 138 139 } 140 141 // three cases: 142 //before offset, 143 // between offset and last big rate, 144 // and after last big rate 145 146 // before offset 147 148 { 149 Real a,b,c,d; 150 originalABCDVariancesScaled_[0].getABCD(a,b,c,d); 151 152 for (Size i=0; i < offset_; ++i) 153 interpolatedVariances_[i] = ext::shared_ptr<PiecewiseConstantVariance>( 154 new PiecewiseConstantAbcdVariance(a,b,c,d,i,timesForSmallRates_)); 155 } 156 157 158 // in between rates 159 160 for (Size j=0; j < noBigRates_-1; ++j) 161 { 162 Real a,b,c,d; 163 Real a0,b0,c0,d0; 164 Real a1,b1,c1,d1; 165 originalABCDVariancesScaled_[j].getABCD(a0,b0,c0,d0); 166 originalABCDVariancesScaled_[j+1].getABCD(a1,b1,c1,d1); 167 a= 0.5*(a0+a1); 168 b= 0.5*(b0+b1); 169 c= 0.5*(c0+c1); 170 d= 0.5*(d0+d1); 171 172 for (Size i=0; i < period_; ++i) 173 interpolatedVariances_[i+j*period_+offset_] = ext::shared_ptr<PiecewiseConstantVariance>( 174 new PiecewiseConstantAbcdVariance(a,b,c,d,i+j*period_,timesForSmallRates_)); 175 176 } 177 178 179 { 180 Real a,b,c,d; 181 originalABCDVariancesScaled_[noBigRates_-1].getABCD(a,b,c,d); 182 183 for (Size i=offset_+(noBigRates_-1)*period_; i < noSmallRates_; ++i) 184 interpolatedVariances_[i] = ext::shared_ptr<PiecewiseConstantVariance>( 185 new PiecewiseConstantAbcdVariance(a,b,c,d,i,timesForSmallRates_)); 186 187 // very last rate is special as we must match the caplet vol 188 Real vol = interpolatedVariances_[noSmallRates_-1]->totalVolatility(noSmallRates_-1); 189 190 Real scale = lastCapletVol_/vol; 191 a*=scale; 192 b*=scale; 193 d*=scale; 194 interpolatedVariances_[noSmallRates_-1] = ext::shared_ptr<PiecewiseConstantVariance>( 195 new PiecewiseConstantAbcdVariance(a,b,c,d,noSmallRates_-1,timesForSmallRates_)); 196 197 } 198 } 199 200 } 201