00001
00022 #include <boost/lexical_cast.hpp>
00023 #include <boost/array.hpp>
00024
00025 #include "ivolt0.hpp"
00026
00027 #include "inflationvolatility.hpp"
00028
00029 #include <ql/math/interpolations/cubicinterpolation.hpp>
00030 #include <ql/math/interpolations/bicubicsplineinterpolation.hpp>
00031 #include <ql/termstructures/yield/zerocurve.hpp>
00032
00033 #include <ql/cashflows/inflationcoupon.hpp>
00034 #include <ql/cashflows/inflationcouponpricer.hpp>
00035
00036 #include <ql/experimental/inflation/yoycapfloortermpricesurface.hpp>
00037 #include <ql/pricingengines/inflation/inflationcapfloorengines.hpp>
00038 #include <ql/experimental/inflation/yoyoptionletstripper.hpp>
00039
00040 #include <ql/experimental/inflation/kinterpolatedyoyoptionletvolatilitysurface.hpp>
00041 #include <ql/experimental/inflation/interpolatedyoyoptionletstripper.hpp>
00042
00043 #include <ql/cashflows/capflooredinflationcoupon.hpp>
00044 #include <ql/indexes/inflation/euhicp.hpp>
00045 #include <ql/indexes/inflation/ukrpi.hpp>
00046
00047 #include <iostream>
00048
00049 #include <boost/bind.hpp>
00050
00051 static int watcher = 0;
00052
00053
00054
00055 namespace {
00056
00057 using namespace std;
00058 using namespace boost;
00059 using namespace QuantLib;
00060
00061 struct Shifter {
00062 const Date & baseDate;
00063 BusinessDayConvention bdc;
00064 TimeUnit timeunit;
00065 Calendar cal;
00066 int offset;
00067
00068 Shifter (const Date & baseDate)
00069 : baseDate(baseDate), offset(0), timeunit(Years), bdc(ModifiedFollowing), cal(TARGET())
00070 {}
00071
00072
00073 Date as(const Real & d) {
00074 Size ys = (Size)floor(d);
00075 Size ds = (Size)((d-(Real)ys)*365);
00076 return baseDate + Period(ys,Years) + Period(ds,Days);
00077 }
00078
00079
00080 operator Date () {
00081 Date dd = cal.advance(baseDate, offset++, timeunit, bdc);
00082 return dd;
00083 }
00084 };
00085
00086 struct helper2 {
00087 helper2() {}
00088
00089 string ts1(const Date & d, const Rate & r) const {
00090 std::string s = boost::lexical_cast<std::string>(d);
00091 s += ", " + boost::lexical_cast<std::string>(r);
00092 return s;
00093 }
00094
00095 ostream & write(ostream & os, std::pair<QuantLib::Date const, double> & p0) const {
00096 return os << QuantLib::io::iso_date(p0.first) << "," << p0.second << endl;
00097 }
00098
00099 ostream & write(ostream & os, const TimeSeries<Rate> & ts,
00100 std::pair<string, string> & h0) {
00101 os << h0.first << "," << h0.second << endl;
00102 for (TimeSeries<Rate>::const_iterator i = ts.begin();
00103 i != ts.end(); ++i) {
00104 std::pair<QuantLib::Date const, double> di = *i;
00105 write(os, di);
00106 }
00107 }
00108
00109 };
00110
00111
00112 struct helper1 {
00113 const Date &baseDate;
00114 const vector<Real> & dates;
00115 const vector<Real> & rates;
00116
00117 explicit helper1(const Date &e,
00118 const vector<Real> & d,
00119 const vector<Real> & r) : baseDate(e), dates(d), rates(r) {}
00120
00121 operator TimeSeries<Rate> () const {
00122 vector<Date> dates0((dates.size()));
00123 Shifter f2(baseDate);
00124
00125 transform(dates.begin(), dates.end(),
00126 dates0.begin(),
00127 boost::bind(&Shifter::as,boost::ref(f2),_1));
00128
00129 TimeSeries<Rate> ts(dates0.begin(),
00130 dates0.end(),
00131 rates.begin());
00132
00133 return ts;
00134 }
00135 };
00136
00137 void no_deletion(void*) {}
00138
00139
00140 Handle<YieldTermStructure> nominalEUR;
00141 Handle<YieldTermStructure> nominalGBP;
00142
00143 RelinkableHandle<YoYInflationTermStructure> yoyEU;
00144 RelinkableHandle<YoYInflationTermStructure> yoyUK;
00145
00146 vector<Rate> cStrikesEU;
00147 vector<Rate> fStrikesEU;
00148 vector<Period> cfMaturitiesEU;
00149 shared_ptr<Matrix> cPriceEU;
00150 shared_ptr<Matrix> fPriceEU;
00151
00152 shared_ptr<YoYInflationIndex> yoyIndexUK(new YYUKRPIr(true, yoyUK));
00153 shared_ptr<YoYInflationIndex> yoyIndexEU(new YYEUHICPr(true, yoyEU));
00154
00155 vector<Rate> cStrikesUK;
00156 vector<Rate> fStrikesUK;
00157 vector<Period> cfMaturitiesUK;
00158 shared_ptr<Matrix> cPriceUK;
00159 shared_ptr<Matrix> fPriceUK;
00160
00161 shared_ptr<InterpolatedYoYCapFloorTermPriceSurface<Bicubic,Cubic> > priceSurfEU;
00162
00163
00164
00165 Date eval = Date(Day(23), Month(11), Year(2007));
00166
00167
00168 Real timesEUR[] = {0.0109589, 0.0684932, 0.263014, 0.317808, 0.567123, 0.816438,
00169 1.06575, 1.31507, 1.56438, 2.0137, 3.01918, 4.01644,
00170 5.01644, 6.01644, 7.01644, 8.01644, 9.02192, 10.0192,
00171 12.0192, 15.0247, 20.0301, 25.0356, 30.0329, 40.0384,
00172 50.0466};
00173 Real ratesEUR[] = {0.0415600, 0.0426840, 0.0470980, 0.0458506, 0.0449550, 0.0439784,
00174 0.0431887, 0.0426604, 0.0422925, 0.0424591, 0.0421477, 0.0421853,
00175 0.0424016, 0.0426969, 0.0430804, 0.0435011, 0.0439368, 0.0443825,
00176 0.0452589, 0.0463389, 0.0472636, 0.0473401, 0.0470629, 0.0461092,
00177 0.0450794};
00178
00179 Real timesGBP[] = {0.008219178, 0.010958904, 0.01369863, 0.019178082, 0.073972603,
00180 0.323287671, 0.57260274, 0.821917808, 1.071232877, 1.320547945,
00181 1.506849315, 2.002739726, 3.002739726, 4.002739726, 5.005479452,
00182 6.010958904, 7.008219178, 8.005479452, 9.008219178, 10.00821918,
00183 12.01369863, 15.0109589, 20.01369863, 25.01917808, 30.02191781,
00184 40.03287671, 50.03561644, 60.04109589, 70.04931507};
00185
00186 Real ratesGBP[] = {0.0577363, 0.0582314, 0.0585265, 0.0587165, 0.0596598,
00187 0.0612506, 0.0589676, 0.0570512, 0.0556147, 0.0546082,
00188 0.0549492, 0.053801, 0.0529333, 0.0524068, 0.0519712,
00189 0.0516615, 0.0513711, 0.0510433, 0.0507974, 0.0504833,
00190 0.0498998, 0.0490464, 0.04768, 0.0464862, 0.045452,
00191 0.0437699, 0.0425311, 0.0420073, 0.041151};
00192
00193
00194 std::vector<Real> teur0(×EUR[0], ×EUR[LENGTH(timesEUR)]);
00195 std::vector<Real> tgbp0(×GBP[0], ×GBP[LENGTH(timesGBP)]);
00196 std::vector<Real> reur0(&ratesEUR[0], &ratesEUR[LENGTH(ratesEUR)]);
00197 std::vector<Real> rgbp0(&ratesGBP[0], &ratesGBP[LENGTH(ratesGBP)]);
00198
00199 TimeSeries<Rate> teur1;
00200 TimeSeries<Rate> tgbp1;
00201
00202 DayCounter dcc_yc0 = Actual365Fixed();
00203
00204
00205
00206
00207
00208
00209
00210
00211 Real yoyEUrates[] = {0.0237951,
00212 0.0238749, 0.0240334, 0.0241934, 0.0243567, 0.0245323,
00213 0.0247213, 0.0249348, 0.0251768, 0.0254337, 0.0257258,
00214 0.0260217, 0.0263006, 0.0265538, 0.0267803, 0.0269378,
00215 0.0270608, 0.0271363, 0.0272, 0.0272512, 0.0272927,
00216 0.027317, 0.0273615, 0.0273811, 0.0274063, 0.0274307,
00217 0.0274625, 0.027527, 0.0275952, 0.0276734, 0.027794};
00218
00219 std::vector<Rate> yoyEUrates0(yoyEUrates, yoyEUrates + LENGTH(yoyEUrates) );
00220
00221
00222 const Size ncStrikesEU = 6;
00223 const Size nfStrikesEU = 6;
00224 const Size ncfMaturitiesEU = 7;
00225 Real capStrikesEU[ncStrikesEU] = {0.02, 0.025, 0.03, 0.035, 0.04, 0.05};
00226 Period capMaturitiesEU[ncfMaturitiesEU] = {3*Years, 5*Years, 7*Years,
00227 10*Years, 15*Years, 20*Years, 30*Years};
00228 Real capPricesEU[ncStrikesEU][ncfMaturitiesEU] =
00229 {{116.225, 204.945, 296.285, 434.29, 654.47, 844.775, 1132.33},
00230 {34.305, 71.575, 114.1, 184.33, 307.595, 421.395, 602.35},
00231 {6.37, 19.085, 35.635, 66.42, 127.69, 189.685, 296.195},
00232 {1.325, 5.745, 12.585, 26.945, 58.95, 94.08, 158.985},
00233 {0.501, 2.37, 5.38, 13.065, 31.91, 53.95, 96.97},
00234 {0.501, 0.695, 1.47, 4.415, 12.86, 23.75, 46.7}};
00235
00236 Real floorStrikesEU[nfStrikesEU] = {-0.01, 0.00, 0.005, 0.01, 0.015, 0.02};
00237 Real floorPricesEU[nfStrikesEU][ncfMaturitiesEU] =
00238 {{0.501, 0.851, 2.44, 6.645, 16.23, 26.85, 46.365},
00239 {0.501, 2.236, 5.555, 13.075, 28.46, 44.525, 73.08},
00240 {1.025, 3.935, 9.095, 19.64, 39.93, 60.375, 96.02},
00241 {2.465, 7.885, 16.155, 31.6, 59.34, 86.21, 132.045},
00242 {6.9, 17.92, 32.085, 56.08, 95.95, 132.85, 194.18},
00243 {23.52, 47.625, 74.085, 114.355, 175.72, 229.565, 316.285}};
00244
00245 vector<Period> cfmeu0(&capMaturitiesEU[0], &capMaturitiesEU[LENGTH(capStrikesEU)]);
00246
00247 vector<Rate> cseu0(&capStrikesEU[0], &capStrikesEU[LENGTH(capStrikesEU)]);
00248 vector<Rate> fseu0(&floorStrikesEU[0], &floorStrikesEU[LENGTH(floorStrikesEU)]);
00249
00250 void setup() {
00251 Settings::instance().evaluationDate() = eval;
00252
00253 vector <Real> r;
00254 vector <Date> d;
00255 Size nTimesEUR = LENGTH(timesEUR);
00256 Size nTimesGBP = LENGTH(timesGBP);
00257 for (Size i = 0; i < nTimesEUR; i++) {
00258 r.push_back(ratesEUR[i]);
00259 Size ys = (Size)floor(timesEUR[i]);
00260 Size ds = (Size)((timesEUR[i]-(Real)ys)*365);
00261 Date dd = eval + Period(ys,Years) + Period(ds,Days);
00262 d.push_back( dd );
00263 }
00264
00265 shared_ptr<InterpolatedZeroCurve<Cubic> >
00266 euriborTS(new InterpolatedZeroCurve<Cubic>(d, r, Actual365Fixed()));
00267 Handle<YieldTermStructure> nominalHeur(euriborTS, false);
00268 nominalEUR = nominalHeur;
00269
00270 d.clear();
00271 r.clear();
00272 for (Size i = 0; i < nTimesGBP; i++) {
00273 r.push_back(ratesGBP[i]);
00274 Size ys = (Size)floor(timesGBP[i]);
00275 Size ds = (Size)((timesGBP[i]-(Real)ys)*365);
00276 Date dd = eval + Period(ys,Years) + Period(ds,Days);
00277 d.push_back( dd );
00278 }
00279
00280 shared_ptr<InterpolatedZeroCurve<Cubic> >
00281 gbpLiborTS(new InterpolatedZeroCurve<Cubic>(d, r, Actual365Fixed()));
00282 Handle<YieldTermStructure> nominalHgbp(gbpLiborTS, false);
00283 nominalGBP = nominalHgbp;
00284
00285
00286 d.clear();
00287 r.clear();
00288 Date baseDate = TARGET().advance(eval, -2, Months, ModifiedFollowing);
00289 for (Size i = 0; i < LENGTH(yoyEUrates); i++) {
00290 Date dd = TARGET().advance(baseDate, i, Years, ModifiedFollowing);
00291 d.push_back(dd);
00292 r.push_back(yoyEUrates[i]);
00293 }
00294
00295 bool indexIsInterpolated = true;
00296
00297
00298 shared_ptr<InterpolatedYoYInflationCurve<Linear> >
00299 pYTSEU( new InterpolatedYoYInflationCurve<Linear>(
00300 eval, TARGET(), Actual365Fixed(), Period(2,Months), Monthly,
00301 indexIsInterpolated, nominalGBP, d, r) );
00302 yoyEU.linkTo(pYTSEU);
00303
00304
00305 cStrikesEU.clear();
00306 fStrikesEU.clear();
00307 cfMaturitiesEU.clear();
00308 for(Size i = 0; i < ncStrikesEU; i++) cStrikesEU.push_back(capStrikesEU[i]);
00309 for(Size i = 0; i < nfStrikesEU; i++) fStrikesEU.push_back(floorStrikesEU[i]);
00310 for(Size i = 0; i < ncfMaturitiesEU; i++) cfMaturitiesEU.push_back(capMaturitiesEU[i]);
00311 shared_ptr<Matrix> tcPriceEU(new Matrix(ncStrikesEU, ncfMaturitiesEU));
00312 shared_ptr<Matrix> tfPriceEU(new Matrix(nfStrikesEU, ncfMaturitiesEU));
00313 for(Size i = 0; i < ncStrikesEU; i++) {
00314 for(Size j = 0; j < ncfMaturitiesEU; j++) {
00315 (*tcPriceEU)[i][j] = capPricesEU[i][j];
00316 }
00317 }
00318 for(Size i = 0; i < nfStrikesEU; i++) {
00319 for(Size j = 0; j < ncfMaturitiesEU; j++) {
00320 (*tfPriceEU)[i][j] = floorPricesEU[i][j];
00321 }
00322 }
00323 cPriceEU = tcPriceEU;
00324 fPriceEU = tfPriceEU;
00325 }
00326
00327
00328 void setupPriceSurface() {
00329
00330
00331
00332
00333
00334
00335 Natural fixingDays = 0;
00336 Size lag = 3;
00337 Period yyLag = Period(lag,Months);
00338 Rate baseRate = 1;
00339 DayCounter dc = Actual365Fixed();
00340 TARGET cal;
00341 BusinessDayConvention bdc = ModifiedFollowing;
00342 boost::shared_ptr<QuantLib::YieldTermStructure> pn =
00343 nominalEUR.currentLink();
00344 Handle<QuantLib::YieldTermStructure> n(pn,false);
00345 boost::shared_ptr<InterpolatedYoYCapFloorTermPriceSurface<Bicubic,Cubic> >
00346 cfEUprices(new InterpolatedYoYCapFloorTermPriceSurface<Bicubic,Cubic>(
00347 fixingDays,
00348 yyLag, yoyIndexEU, baseRate,
00349 n, dc,
00350 cal, bdc,
00351 cStrikesEU, fStrikesEU, cfMaturitiesEU,
00352 (*cPriceEU), (*fPriceEU)));
00353
00354 priceSurfEU = cfEUprices;
00355 }
00356
00357 }
00358
00359 BOOST_AUTO_TEST_SUITE (ts)
00360
00361 BOOST_AUTO_TEST_CASE(list)
00362 {
00363 BOOST_TEST_MESSAGE("QuantLib::price::list");
00364
00365 copy(teur0.begin(), teur0.end(), ostream_iterator<Real>(cout, "\n"));
00366 copy(reur0.begin(), reur0.end(), ostream_iterator<Real>(cout, "\n"));
00367
00368 vector <Real> r;
00369 vector <Date> d;
00370
00371 Size nTimesEUR = LENGTH(timesEUR);
00372 Size nTimesGBP = LENGTH(timesGBP);
00373 for (Size i = 0; i < nTimesEUR; i++) {
00374 r.push_back(ratesEUR[i]);
00375 Size ys = (Size)floor(timesEUR[i]);
00376 Size ds = (Size)((timesEUR[i]-(Real)ys)*365);
00377 Date dd = eval + Period(ys,Years) + Period(ds,Days);
00378 d.push_back( dd );
00379 }
00380
00381 copy(d.begin(), d.end(), ostream_iterator<Date>(cout, "\n"));
00382
00383 BOOST_TEST_MESSAGE("array: " << LENGTH(timesEUR) << " vector: " << teur0.size());
00384
00385 BOOST_CHECK( teur0.size() == LENGTH(timesEUR) );
00386 BOOST_CHECK( teur0[teur0.size()-1] == timesEUR[LENGTH(timesEUR) - 1] );
00387
00388
00389
00390 }
00391
00392 BOOST_AUTO_TEST_CASE(ts0)
00393 {
00394 BOOST_TEST_MESSAGE("QuantLib::price::ts - time-series build");
00395
00396 Shifter f2(eval);
00397 vector<Date> dates(teur0.size());
00398 transform(teur0.begin(), teur0.end(),
00399 dates.begin(),
00400 boost::bind(&Shifter::as,boost::ref(f2),_1) );
00401
00402 BOOST_CHECK(dates.size() == LENGTH(timesEUR));
00403 BOOST_CHECK(dates.size() == LENGTH(ratesEUR));
00404 BOOST_CHECK(dates.size() == reur0.size());
00405
00406 #ifndef NDEBUG
00407 copy(dates.begin(), dates.end(), ostream_iterator<Date>(cerr, "\t"));
00408 cerr << endl;
00409 copy(reur0.begin(), reur0.end(), ostream_iterator<Rate>(cerr, "\t"));
00410 cerr << endl;
00411 #endif
00412
00413 TimeSeries<Rate> teur1(dates.begin(), dates.end(), reur0.begin());
00414
00415 BOOST_TEST_MESSAGE( teur1.firstDate() );
00416
00417 BOOST_CHECK(teur1.dates().size() == LENGTH(timesEUR));
00418
00419 #ifndef NDEBUG
00420 std::vector<Date> d0(teur1.dates());
00421 copy(d0.begin(), d0.end(), ostream_iterator<Date>(cerr, "\n"));
00422 #endif
00423 }
00424
00425 BOOST_AUTO_TEST_CASE(ts1)
00426 {
00427 BOOST_TEST_MESSAGE("QuantLib::price::ts - time-series teur1 tgbp1");
00428
00429 TimeSeries<Rate> teur1 = helper1(eval, teur0, reur0);
00430 TimeSeries<Rate> tgbp1 = helper1(eval, tgbp0, rgbp0);
00431
00432 BOOST_CHECK( teur0.size() == teur1.size() );
00433 BOOST_CHECK( tgbp0.size() == tgbp1.size() );
00434
00435 BOOST_CHECK(teur1.size() == teur0.size());
00436 BOOST_CHECK(teur1.size() && tgbp1.size());
00437 BOOST_CHECK(teur1.dates().size() && tgbp1.dates().size());
00438
00439 #ifndef NDEBUG
00440 std::vector<Date> d0(teur1.dates());
00441 copy(d0.begin(),
00442 d0.end(), ostream_iterator<Date>(cout, "\n"));
00443 #endif
00444 }
00445
00446 BOOST_AUTO_TEST_CASE(ts2)
00447 {
00448 BOOST_TEST_MESSAGE("QuantLib::timeseries::ts2");
00449
00450 TimeSeries<Rate> teur1 = helper1(eval, teur0, reur0);
00451 TimeSeries<Rate> tgbp1 = helper1(eval, tgbp0, rgbp0);
00452
00453 vector<string> tags(teur1.size());
00454
00455 std::vector<Date> d0(teur1.dates());
00456 std::vector<Rate> r0(teur1.values());
00457
00458 #ifndef NDEBUG
00459 transform(d0.begin(), d0.end(),
00460 r0.begin(), tags.begin(),
00461 boost::bind(&helper2::ts1,helper2(),_1,_2) );
00462
00463 copy(tags.begin(), tags.end(), ostream_iterator<string>(cout, "\n"));
00464 #endif
00465
00466 shared_ptr<InterpolatedZeroCurve<Cubic> >
00467 euriborTS(new InterpolatedZeroCurve<Cubic>(d0, r0, Actual365Fixed()));
00468 Handle<YieldTermStructure> nominalHeur(euriborTS, false);
00469
00470 shared_ptr<InterpolatedZeroCurve<Cubic> >
00471 gbpLiborTS(new InterpolatedZeroCurve<Cubic>(tgbp1.dates(), tgbp1.values(), Actual365Fixed()));
00472 Handle<YieldTermStructure> nominalHgbp(gbpLiborTS, false);
00473
00474 }
00475
00476 BOOST_AUTO_TEST_CASE(ts3)
00477 {
00478 BOOST_TEST_MESSAGE("QuantLib::timeseries::ts3");
00479
00480 Date baseDate = TARGET().advance(eval, -2, Months, ModifiedFollowing);
00481 Shifter f2(baseDate);
00482
00483 std::vector<Date> dates(yoyEUrates0.size());
00484
00485 generate(dates.begin(), dates.end(), boost::bind(&Shifter::operator Date, boost::ref(f2)) );
00486
00487 #ifndef NDEBUG
00488 copy(dates.begin(), dates.end(), ostream_iterator<Date>(cerr, "\t"));
00489 cerr << endl;
00490 #endif
00491
00492 TimeSeries<Rate> yoyEU(dates.begin(), dates.end(), yoyEUrates0.begin());
00493
00494
00495 bool indexIsInterpolated = true;
00496
00497 InterpolatedYoYInflationCurve<Linear> * p =
00498 new InterpolatedYoYInflationCurve<Linear>(eval, f2.cal, Actual365Fixed(),
00499 Period(2,Months), Monthly,
00500 indexIsInterpolated, nominalGBP,
00501 yoyEU.dates(), yoyEU.values() );
00502 shared_ptr<InterpolatedYoYInflationCurve<Linear> > pYTSEU(p);
00503
00504 }
00505
00506 BOOST_AUTO_TEST_SUITE_END()
00507
00508 BOOST_AUTO_TEST_SUITE(lists)
00509
00510 BOOST_AUTO_TEST_CASE(yceur)
00511 {
00512 BOOST_TEST_MESSAGE("QuantLib::lists::yceur");
00513
00514 TimeSeries<Rate> teur1 = helper1(eval, teur0, reur0);
00515
00516 helper2 as0;
00517
00518 pair<string, string> h0("date", "eur_yc_rate");
00519 as0.write(std::cerr, teur1, h0);
00520 }
00521
00522 BOOST_AUTO_TEST_CASE(ycgbp)
00523 {
00524 BOOST_TEST_MESSAGE("QuantLib::lists::ycgbp");
00525
00526 TimeSeries<Rate> tgbp1 = helper1(eval, tgbp0, rgbp0);
00527
00528 helper2 as0;
00529
00530 pair<string, string> h0("date", "gbp_yc_rate");
00531 as0.write(std::cerr, tgbp1, h0);
00532 }
00533
00534 BOOST_AUTO_TEST_CASE(yoyeur)
00535 {
00536 BOOST_TEST_MESSAGE("QuantLib::lists::yoyeur");
00537
00538 Date baseDate = TARGET().advance(eval, -2, Months, ModifiedFollowing);
00539 Shifter f2(baseDate);
00540
00541 std::vector<Date> dates(yoyEUrates0.size());
00542
00543 generate(dates.begin(), dates.end(), boost::bind(&Shifter::operator Date, boost::ref(f2)) );
00544
00545 helper2 as0;
00546 TimeSeries<Rate> yoyeu1(dates.begin(), dates.end(), yoyEUrates0.begin());
00547 pair<string, string> h1("date", "eur_yoy_rate");
00548 as0.write(cerr, yoyeu1, h1);
00549 }
00550
00551 BOOST_AUTO_TEST_CASE(capseu)
00552 {
00553 BOOST_TEST_MESSAGE("QuantLib::ycs::quotes - cap ");
00554
00555 cerr << "strike,mty,price" << endl;
00556 for(Size i = 0; i < cseu0.size(); i++) {
00557 Real a = cseu0[i];
00558 for(Size j = 0; j < cfmeu0.size(); j++) {
00559 Period b = cfmeu0[j];
00560 cerr << a << "," << b << "," << capPricesEU[i][j] << endl;
00561 }
00562 }
00563 }
00564
00565 BOOST_AUTO_TEST_CASE(floorseu)
00566 {
00567 BOOST_TEST_MESSAGE("QuantLib::ycs::quotes - floor ");
00568
00569 cerr << "strike,mty,price" << endl;
00570 for(Size i = 0; i < fseu0.size(); i++) {
00571 Real a = fseu0[i];
00572 for(Size j = 0; j < cfmeu0.size(); j++) {
00573 Period b = cfmeu0[j];
00574 cerr << a << "," << b << "," << floorPricesEU[i][j] << endl;
00575 }
00576 }
00577 }
00578
00579 BOOST_AUTO_TEST_SUITE_END()
00580
00581 BOOST_AUTO_TEST_SUITE(vol)
00582
00583 BOOST_AUTO_TEST_CASE(vol0)
00584 {
00585 BOOST_TEST_MESSAGE("QuantLib::vol::vol0");
00586 BOOST_TEST_MESSAGE("Testing conversion from YoY price surface to YoY volatility surface...");
00587
00588 SavedSettings backup;
00589
00590 setup();
00591
00592
00593 setupPriceSurface();
00594
00595
00596
00597
00598 boost::shared_ptr<YoYOptionletVolatilitySurface> pVS;
00599 Handle<YoYOptionletVolatilitySurface> hVS(pVS, false);
00600 boost::shared_ptr<YoYInflationUnitDisplacedBlackCapFloorEngine>
00601 yoyPricerUD(new YoYInflationUnitDisplacedBlackCapFloorEngine(yoyIndexEU,hVS));
00602
00603
00604
00605 boost::shared_ptr<YoYOptionletStripper> yoyOptionletStripper(
00606 new InterpolatedYoYOptionletStripper<Linear>() );
00607
00608
00609 Natural settlementDays = 0;
00610 TARGET cal;
00611 BusinessDayConvention bdc = ModifiedFollowing;
00612 DayCounter dc = Actual365Fixed();
00613
00614 boost::shared_ptr<YoYCapFloorTermPriceSurface> capFloorPrices = priceSurfEU;
00615 Period lag = priceSurfEU->observationLag();
00616
00617 Real slope = -0.5;
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628 boost::shared_ptr<KInterpolatedYoYOptionletVolatilitySurface<Linear> > yoySurf(new
00629 KInterpolatedYoYOptionletVolatilitySurface<Linear>(settlementDays,
00630 cal, bdc, dc, lag, capFloorPrices, yoyPricerUD, yoyOptionletStripper,
00631 slope) );
00632
00633
00634 const Real volATyear1[] = {
00635 0.0128, 0.0093, 0.0083, 0.0073, 0.0064,
00636 0.0058, 0.0042, 0.0046, 0.0053, 0.0064,
00637 0.0098
00638 };
00639 const Real volATyear3[] = {
00640 0.0079, 0.0058, 0.0051, 0.0045, 0.0039,
00641 0.0035, 0.0026, 0.0028, 0.0033, 0.0039,
00642 0.0060
00643 };
00644
00645 Date d = yoySurf->baseDate() + Period(1,Years);
00646 pair<vector<Rate>, vector<Volatility> > someSlice;
00647 someSlice = yoySurf->Dslice(d);
00648
00649 Size n = someSlice.first.size();
00650 Real eps = 0.0001;
00651 for(Size i = 0; i < n; i++){
00652 BOOST_TEST_MESSAGE( someSlice.second[i] << " " << volATyear1[i] << " " << volATyear1[i] );
00653 QL_REQUIRE( fabs(someSlice.second[i] - volATyear1[i]) < eps,
00654 " could not recover 1yr vol: " << someSlice.second[i]
00655 << " vs " << volATyear1[i] );
00656 }
00657
00658 d = yoySurf->baseDate() + Period(3,Years);
00659 pair<vector<Rate>, vector<Volatility> >
00660 someOtherSlice = yoySurf->Dslice(d);
00661 n = someOtherSlice.first.size();
00662 for(Size i = 0; i < n; i++){
00663 QL_REQUIRE(fabs(someOtherSlice.second[i]-volATyear3[i]) < eps,
00664 "could not recover 3yr vol: "
00665 << someOtherSlice.second[i]<< " vs " << volATyear3[i] );
00666 }
00667 }
00668
00669 BOOST_AUTO_TEST_CASE(atm)
00670 {
00671 BOOST_TEST_MESSAGE("Testing conversion from YoY cap-floor surface "
00672 "to YoY inflation term structure...");
00673
00674 SavedSettings backup;
00675
00676 setup();
00677
00678 setupPriceSurface();
00679
00680 Date eval = Settings::instance().evaluationDate();
00681
00682 pair<vector<Time>, vector<Rate> > yyATMt = priceSurfEU->atmYoYSwapTimeRates();
00683 pair<vector<Date>, vector<Rate> > yyATMd = priceSurfEU->atmYoYSwapDateRates();
00684
00685
00686 const Real crv[] = {0.024586, 0.0247575, 0.0249396, 0.0252596,
00687 0.0258498, 0.0262883, 0.0267915};
00688 const Real swaps[] = {0.024586, 0.0247575, 0.0249396, 0.0252596,
00689 0.0258498, 0.0262883, 0.0267915};
00690 const Real ayoy[] = {0.0247659, 0.0251437, 0.0255945, 0.0265234,
00691 0.0280457, 0.0285534, 0.0295884};
00692 Real eps = 2e-5;
00693 for(Size i = 0; i < yyATMt.first.size(); i++) {
00694 QL_REQUIRE(fabs( yyATMt.second[i] - crv[i] ) < eps,
00695 "could not recover cached yoy swap curve "
00696 << yyATMt.second[i]<< " vs " << crv[i]);
00697 }
00698
00699 for(Size i = 0; i < yyATMd.first.size(); i++) {
00700 QL_REQUIRE(fabs( priceSurfEU->atmYoYSwapRate(yyATMd.first[i])
00701 - swaps[i] ) < eps,
00702 "could not recover yoy swap curve "
00703 << priceSurfEU->atmYoYSwapRate(yyATMd.first[i])
00704 << " vs " << swaps[i]);
00705 }
00706 for(Size i = 0; i < yyATMd.first.size(); i++) {
00707 QL_REQUIRE(fabs( priceSurfEU->atmYoYRate(yyATMd.first[i]) - ayoy[i] ) < eps,
00708 " could not recover cached yoy curve "
00709 << priceSurfEU->atmYoYRate(yyATMd.first[i]) << " vs " << ayoy[i]
00710 <<" at "<<yyATMd.first[i]);
00711 }
00712
00713 }
00714
00715 BOOST_AUTO_TEST_SUITE_END()