97 {
98
99 QuantLib::ext::shared_ptr<Conventions> conventions = InstrumentConventions::instance().conventions();
100
101
102 string ccy = config->currency();
103 string swaptionVol = "SwaptionVolatility/" + ccy + "/" + config->swaptionVolatility();
104 auto it = swaptionVolCurves.find(swaptionVol);
105
106 if (it == swaptionVolCurves.end())
107 QL_FAIL("The swaption vol curve not found " << swaptionVol);
108 Handle<SwaptionVolatilityStructure> vol(it->second->volTermStructure());
109
110 string dc = "Yield/" + ccy + "/" + config->discountCurve();
111 Handle<YieldTermStructure> yts;
112 auto it2 = yieldCurves.find(dc);
113 if (it2 != yieldCurves.end()) {
114 yts = it2->second->handle();
115 } else {
116 QL_FAIL("The discount curve not found, " << dc);
117 }
118
119 Real lower = (vol->volatilityType() == ShiftedLognormal) ? 0.0001 : -2;
120 Real upper = (vol->volatilityType() == ShiftedLognormal) ? 2.0000 : 2;
121
122 LinearTsrPricer::Settings settings;
123 settings.withRateBound(lower, upper);
124
125 Real rev = 0;
126 Handle<Quote> revQuote(QuantLib::ext::shared_ptr<Quote>(new SimpleQuote(rev)));
127
128 QuantLib::ext::shared_ptr<QuantLib::CmsCouponPricer> cmsPricer =
129 QuantLib::ext::make_shared<LinearTsrPricer>(vol, revQuote, yts, settings);
130
131
132 Handle<QuantExt::CorrelationTermStructure> ch(curve);
133 QuantLib::ext::shared_ptr<FloatingRateCouponPricer> pricer =
134 QuantLib::ext::make_shared<QuantExt::LognormalCmsSpreadPricer>(cmsPricer, ch, yts, 16);
135
136
137 auto it3 = swapIndices.find(config->index1());
138 if (it3 == swapIndices.end())
139 QL_FAIL("The swap index not found " << config->index1());
140
141 QuantLib::ext::shared_ptr<SwapIndex> index1 = it3->second;
142
143 auto it4 = swapIndices.find(config->index2());
144 if (it4 == swapIndices.end())
145 QL_FAIL("The swap index not found " << config->index2());
146
147 QuantLib::ext::shared_ptr<SwapIndex> index2 = it4->second;
148
149 vector<QuantLib::ext::shared_ptr<QuantExt::CmsCapHelper>> instruments;
150
151 QuantLib::ext::shared_ptr<Convention> tmp = conventions->get(config->conventions());
152 QL_REQUIRE(tmp, "no conventions found with id " << config->conventions());
153
154 QuantLib::ext::shared_ptr<CmsSpreadOptionConvention> conv = QuantLib::ext::dynamic_pointer_cast<CmsSpreadOptionConvention>(tmp);
155 QL_REQUIRE(conv != NULL, "CMS Correlation curves require CMSSpreadOption convention ");
156 Period forwardStart = conv->forwardStart();
157 Period spotDays = conv->spotDays();
158 Period cmsTenor = conv->swapTenor();
159 Natural fixingDays = conv->fixingDays();
160 Calendar
calendar = conv->calendar();
161 DayCounter dcount = conv->dayCounter();
162 BusinessDayConvention bdc = conv->rollConvention();
163 vector<Period> optionTenors = parseVectorOfValues<Period>(config->optionTenors(), &
parsePeriod);
164
165 for (Size i = 0; i < prices.size(); i++) {
166 QuantLib::ext::shared_ptr<QuantExt::CmsCapHelper> inst = QuantLib::ext::make_shared<QuantExt::CmsCapHelper>(
167 asof, index1, index2, yts, prices[i], correlations[i], optionTenors[i], forwardStart, spotDays, cmsTenor,
168 fixingDays,
calendar, dcount, bdc, pricer, cmsPricer);
169 instruments.push_back(inst);
170 }
171
172
173 EndCriteria endCriteria(1000, 500, 1E-8, 1E-8, 1E-8);
174 BoundaryConstraint constraint(-1, 1);
175 vector<Real> weights(prices.size(), 1);
176
177 Array prms(prices.size(), 0);
178 vector<bool> all(prms.size(), false);
179 Projection proj(prms, all);
180 ProjectedConstraint pc(constraint, proj);
181
182 QuantLib::ext::shared_ptr<OptimizationMethod> method = QuantLib::ext::make_shared<LevenbergMarquardt>(1E-8, 1E-8, 1E-8);
183
185
186 Problem prob(c, pc, proj.project(prms));
187
188 method->minimize(prob, endCriteria);
189
190 Array result(prob.currentValue());
191}
friend class CalibrationFunction