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