87 {
88
89 QuantLib::ext::shared_ptr<SwaptionVolatilityDiscrete> svDisc;
90
91
92
93
94 vector<Real> strikeSpreads(1, 0.0);
95 QuantLib::ext::shared_ptr<SwapIndex> swapIndexBase, shortSwapIndexBase;
96 QuantLib::ext::shared_ptr<SwaptionVolatilityCube> cube;
97 if (QuantLib::ext::dynamic_pointer_cast<SwaptionVolCubeWithATM>(
svsIn_)) {
98 cube = QuantLib::ext::static_pointer_cast<SwaptionVolCubeWithATM>(
svsIn_)->cube();
99 }
100 if (QuantLib::ext::dynamic_pointer_cast<SwaptionVolatilityCube>(
svsIn_)) {
101 cube = QuantLib::ext::static_pointer_cast<SwaptionVolatilityCube>(
svsIn_);
102 }
103 if (cube) {
104 svDisc = cube;
105 strikeSpreads = cube->strikeSpreads();
106 swapIndexBase = cube->swapIndexBase();
107 shortSwapIndexBase = cube->shortSwapIndexBase();
108 }
else if (QuantLib::ext::dynamic_pointer_cast<SwaptionVolatilityDiscrete>(
svsIn_)) {
109 svDisc = QuantLib::ext::static_pointer_cast<SwaptionVolatilityDiscrete>(
svsIn_);
110 } else {
111 QL_FAIL("SwaptionVolatilityConverter: unknown input volatility structure");
112 }
113
114
115 DayCounter dayCounter = svDisc->dayCounter();
116 bool extrapolation = svDisc->allowsExtrapolation();
117 Calendar calendar = svDisc->calendar();
118 BusinessDayConvention bdc = svDisc->businessDayConvention();
119
120 const vector<Date>& optionDates = svDisc->optionDates();
121 const vector<Period>& optionTenors = svDisc->optionTenors();
122 const vector<Period>& swapTenors = svDisc->swapTenors();
123 const vector<Time>& optionTimes = svDisc->optionTimes();
124 const vector<Time>& swapLengths = svDisc->swapLengths();
125 Size nOptionTimes = optionTimes.size();
126 Size nSwapLengths = swapLengths.size();
127 Size nStrikeSpreads = strikeSpreads.size();
128
129 Real targetShift = 0.0;
130
131
134 "SwaptionVolatilityConverter: number of shift rows does not equal the number of option tenors");
136 "SwaptionVolatilityConverter: number of shift columns does not equal the number of swap tenors");
137 }
138
139
140 Matrix volatilities(nOptionTimes, nSwapLengths);
141 for (Size i = 0; i < nOptionTimes; ++i) {
142 for (Size j = 0; j < nSwapLengths; ++j) {
145 volatilities[i][j] =
convert(optionDates[i], swapTenors[j], 0.0, dayCounter,
targetType_, targetShift);
146 }
147 }
148
149
150 Handle<SwaptionVolatilityStructure> atmStructure;
151 if (calendar.empty() || optionTenors.empty()) {
152
153 atmStructure = Handle<SwaptionVolatilityStructure>(
154 QuantLib::ext::make_shared<SwaptionVolatilityMatrix>(
asof_, calendar, bdc, optionDates, swapTenors, volatilities,
156 } else {
157 atmStructure = Handle<SwaptionVolatilityStructure>(QuantLib::ext::shared_ptr<SwaptionVolatilityMatrix>(
158 new SwaptionVolatilityMatrix(
asof_, calendar, bdc, optionTenors, swapTenors, volatilities, Actual365Fixed(),
160 }
161
162
163 if (!cube)
164 return *atmStructure;
165
166
167
168 std::vector<std::vector<Handle<Quote> > > volSpreads(nOptionTimes * nSwapLengths,
169 std::vector<Handle<Quote> >(nStrikeSpreads));
170 for (Size k = 0; k < nStrikeSpreads; ++k) {
171 for (Size i = 0; i < nOptionTimes; ++i) {
172 for (Size j = 0; j < nSwapLengths; ++j) {
175 Real outVol =
176 convert(optionDates[i], swapTenors[j], strikeSpreads[k], dayCounter,
targetType_, targetShift);
177 volSpreads[i * nSwapLengths + j][k] = Handle<Quote>(QuantLib::ext::make_shared<SimpleQuote>(outVol));
178 }
179 }
180 }
181
182
183 QuantLib::ext::shared_ptr<SwaptionVolatilityCube> cubeOut = QuantLib::ext::shared_ptr<QuantExt::SwaptionVolCube2>(
185 shortSwapIndexBase, false, true, false));
186 cubeOut->enableExtrapolation(cube->allowsExtrapolation());
187 return QuantLib::ext::make_shared<SwaptionVolCubeWithATM>(cubeOut);
188
189}
QuantLib::ext::shared_ptr< SwaptionVolatilityStructure > convert() const
Method that returns the converted SwaptionVolatilityStructure