386 {
387
388 Date asof(24, Mar, 2020);
389 Settings::instance().evaluationDate() = asof;
390
391 std::vector<ZeroDatum> zero_data = {
392 { "2020-03-25", -0.00710652430814573 },
393 { "2020-04-27", -0.00741014330032008 },
394 { "2020-05-26", -0.00756626445863218 },
395 { "2020-06-26", -0.00757302703270679 },
396 { "2020-09-28", -0.00741005956787566 },
397 { "2020-12-29", -0.00741819259807242 },
398 { "2021-03-26", -0.00745035004912764 },
399 { "2022-03-28", -0.00724972360299359 },
400 { "2023-03-27", -0.00694809582571432 },
401 { "2024-03-26", -0.00639564747668298 },
402 { "2025-03-26", -0.0056924815618794 },
403 { "2026-03-26", -0.00491308147033043 },
404 { "2027-03-30", -0.00428289071011978 },
405 { "2028-03-27", -0.00365173027918575 },
406 { "2029-03-26", -0.00312018815108916 },
407 { "2030-03-26", -0.00266352161484584 },
408 { "2032-03-30", -0.00179856872850126 },
409 { "2035-03-27", -0.000800546649163958 },
410 { "2040-03-26", -0.000821931627955741 },
411 { "2045-03-27", -0.00149953900205779 },
412 { "2050-03-28", -0.00228805321739911 },
413 };
414
416
417 vector<string> quotes(zero_data.size());
418 for (Size i=0; i < zero_data.size(); ++i) {
419 quotes[i] = "ZERO/RATE/CHF/CHF-OIS/A365/" + zero_data[i].date;
420 }
421
423 vector<QuantLib::ext::shared_ptr<YieldCurveSegment>> segments{
424 QuantLib::ext::make_shared<DirectYieldCurveSegment>(
425 "Zero", "CHF-ZERO-CONVENTIONS", quotes)
426 };
427 QuantLib::ext::shared_ptr<YieldCurveConfig> chfYieldConfig =
428 QuantLib::ext::make_shared<YieldCurveConfig>("CHF-OIS", "CHF OIS curve", "CHF",
429 "", segments,
430 "Discount", "LogQuadratic");
431 curveConfigs.add(CurveSpec::CurveType::Yield,
"CHF-OIS", chfYieldConfig);
432
433 QuantLib::ext::shared_ptr<Conventions> conventions = QuantLib::ext::make_shared<Conventions>();;
434 InstrumentConventions::instance().setConventions(conventions);
435
436 QuantLib::ext::shared_ptr<Convention> convention =
437 QuantLib::ext::make_shared<ZeroRateConvention>("CHF-ZERO-CONVENTIONS", "A365",
438 "CHF", "Compounded", "Annual");
439 conventions->add(convention);
440
441 vector<string>
data(zero_data.size());
442 for (Size i=0; i < zero_data.size(); ++i) {
444 data[i] += boost::lexical_cast<std::string>(zero_data[i].zero);
445 }
446
447 MarketDataLoader loader(data);
449
450 BOOST_TEST_MESSAGE("Test zeroRate from YieldCurve against input");
451 for (Size i=0; i < zero_data.size(); ++i) {
452 BOOST_CHECK_CLOSE(
453 chfYieldCurve.handle()->zeroRate(
parseDate(zero_data[i].date),
454 Actual365Fixed(), Compounded,
455 Annual).rate(),
456 zero_data[i].zero, 1e-6
457 );
458 }
459
460
461 std::vector<ExpectedResult> expected = {
462 { "2020-03-25", -0.00705200739223866, 1.00001953963179, -0.00710652430814573 },
463 { "2020-04-02", -0.00721390912158171, 1.0001778751147, -0.00718723002828103 },
464 { "2020-04-10", -0.00738227311346984, 1.00033965887219, -0.00726491951444497 },
465 { "2020-04-18", -0.00749059894111781, 1.0005044904488, -0.00733665761295088 },
466 { "2020-04-27", -0.00760320907581491, 1.00069307015329, -0.00741014330031875 },
467 { "2020-04-09", -0.00737384545779651, 1.00031926101022, -0.00725553005947521 },
468 { "2020-04-25", -0.00758478528252393, 1.0006509032529, -0.00739447534752169 },
469 { "2020-05-10", -0.00769596247521598, 1.00096977382034, -0.00749931157112393 },
470 { "2020-05-26", -0.0076429042339754, 1.00131178328636, -0.0075662644586304 },
471 { "2020-04-17", -0.00748320484351694, 1.00048373351725, -0.00732801995321264 },
472 { "2020-05-10", -0.00769596247521598, 1.00096977382034, -0.00749931157112393 },
473 { "2020-06-02", -0.00758166464153831, 1.00146009211018, -0.00757891880297334 },
474 { "2020-06-26", -0.00736149127903651, 1.00195965381451, -0.00757302703270502 },
475 { "2020-05-10", -0.00769596247521598, 1.00096977382034, -0.00749931157112393 },
476 { "2020-06-26", -0.00736149127903651, 1.00195965381451, -0.00757302703270502 },
477 { "2020-08-12", -0.00711900322939663, 1.002904625853, -0.00748005210315095 },
478 { "2020-09-28", -0.00719031149285065, 1.00383824668103, -0.00741005956787366 },
479 { "2020-06-02", -0.00758166464153831, 1.00146009211018, -0.00757891880297334 },
480 { "2020-08-11", -0.00712099069506866, 1.00288478786826, -0.0074820952971888 },
481 { "2020-10-20", -0.00728829236142925, 1.00428240351543, -0.00739981858935435 },
482 { "2020-12-29", -0.00748148784771807, 1.00572822439311, -0.00741819259807019 },
483 { "2020-06-24", -0.00738797434533645, 1.00191855412792, -0.00757552258803451 },
484 { "2020-09-24", -0.00717170989259053, 1.00375818166182, -0.0074134982804841 },
485 { "2020-12-24", -0.00747585963708053, 1.00562378840629, -0.00741575708517861 },
486 { "2021-03-26", -0.00740455196858392, 1.00754755952054, -0.00745035004912542 },
487 { "2020-09-24", -0.00717170989259053, 1.00375818166182, -0.0074134982804841 },
488 { "2021-03-26", -0.00740455196858392, 1.00754755952054, -0.00745035004912542 },
489 { "2021-09-25", -0.00694048485996968, 1.01122053890473, -0.0073775427951106 },
490 { "2022-03-28", -0.0066863454350452, 1.01473957125551, -0.00724972360299103 },
491 { "2020-12-24", -0.00747585963708053, 1.00562378840629, -0.00741575708517861 },
492 { "2021-09-24", -0.0069414029672199, 1.01120103496917, -0.00737820251647103 },
493 { "2022-06-25", -0.00656498953875317, 1.01640540717996, -0.00719077356299158 },
494 { "2023-03-27", -0.00558871194802357, 1.02119585320621, -0.00694809582571021 },
495 { "2021-03-25", -0.00741094632973116, 1.00752681818474, -0.00745025320516035 },
496 { "2022-03-26", -0.00668750137850616, 1.01470187085395, -0.00725106794125541 },
497 { "2023-03-26", -0.00559392063686381, 1.02117998518244, -0.00694927326429007 },
498 { "2024-03-26", -0.00380047798675509, 1.02605103251001, -0.0063956474766812 },
499 { "2021-06-24", -0.00715202046442265, 1.0093822458995, -0.00743079826559478 },
500 { "2022-09-24", -0.00634232121085709, 1.01806767055031, -0.00712529508658977 },
501 { "2023-12-25", -0.00422742334270421, 1.02499844543564, -0.00655192842032992 },
502 { "2025-03-26", -0.00172999929889617, 1.02900328433957, -0.00569248156188507 },
503 { "2021-09-24", -0.0069414029672199, 1.01120103496917, -0.00737820251647103 },
504 { "2023-03-26", -0.00559392063686381, 1.02117998518244, -0.00694927326429007 },
505 { "2024-09-24", -0.00286665434442224, 1.0277915286893, -0.00606391607397783 },
506 { "2026-03-26", -0.000727524210795139, 1.03003380594845, -0.00491308147034686 },
507 { "2021-12-25", -0.00678779318060929, 1.01297597811044, -0.00731440818226603 },
508 { "2023-09-26", -0.00466377889755343, 1.02385925805364, -0.00669595300436709 },
509 { "2025-06-27", -0.00119318667783475, 1.02938907952551, -0.00548847866962621 },
510 { "2027-03-30", 0.000117832613426572, 1.0305853419039, -0.00428289071016552 },
511 { "2022-03-26", -0.00668750137850616, 1.01470187085395, -0.00725106794125541 },
512 { "2024-03-26", -0.00380047798675509, 1.02605103251001, -0.0063956474766812 },
513 { "2026-03-27", -0.000729929427953913, 1.03003588754858, -0.00491118220370035 },
514 { "2028-03-27", 0.00112613114121807, 1.02975141478671, -0.00365173027928756 },
515 { "2022-06-25", -0.00656498953875317, 1.01640540717996, -0.00719077356299158 },
516 { "2024-09-24", -0.00286665434442224, 1.0277915286893, -0.00606391607397783 },
517 { "2026-12-25", -0.000343853350512902, 1.03054949871623, -0.00444232736548467 },
518 { "2029-03-26", 0.00122363405024473, 1.02856007847337, -0.00312018815121784 },
519 { "2022-09-24", -0.00634232121085709, 1.01806767055031, -0.00712529508658977 },
520 { "2025-03-25", -0.00173674463422646, 1.02899832012865, -0.00569463011016269 },
521 { "2027-09-24", 0.000888320704621748, 1.03030851958745, -0.00396957339826431 },
522 { "2030-03-26", 0.0017355869817326, 1.02705961730745, -0.00266352161503269 },
523 { "2023-03-27", -0.00558871194802357, 1.02119585320621, -0.00694809582571021 },
524 { "2026-03-28", -0.000730525490939549, 1.0300379726323, -0.00490928522291956 },
525 { "2029-03-29", 0.00122749406191502, 1.02854958382202, -0.00311622139684964 },
526 { "2032-03-30", 0.00320650937346123, 1.02188263368199, -0.00179856872876094 },
527 { "2023-12-25", -0.00422742334270421, 1.02499844543564, -0.00655192842032992 },
528 { "2027-09-25", 0.000889730574376024, 1.03030598533069, -0.00396780181172551 },
529 { "2031-06-26", 0.00265730529292796, 1.02419866540126, -0.00212067173766495 },
530 { "2035-03-27", 0.00203153226992825, 1.01209877900331, -0.000800546649511458 },
531 { "2025-03-25", -0.00173674463422646, 1.02899832012865, -0.00569463011016269 },
532 { "2030-03-26", 0.0017355869817326, 1.02705961730745, -0.00266352161503269 },
533 { "2035-03-26", 0.00203563762406489, 1.0121045019654, -0.000801068999449428 },
534 { "2040-03-26", -0.00294180811111211, 1.0165973929348, -0.000821931627935868 },
535 { "2026-06-25", -0.000760135138913043, 1.03023087322183, -0.00474822200738056 },
536 { "2032-09-24", 0.00346788193350989, 1.02019108824174, -0.00159634484187743 },
537 { "2038-12-25", -0.00217162595274267, 1.01327109910735, -0.000702248267447581 },
538 { "2045-03-27", -0.00536047202242429, 1.03826766081024, -0.00149953900098565 },
539 { "2027-09-25", 0.000889730574376024, 1.03030598533069, -0.00396780181172551 },
540 { "2035-03-27", 0.00203153226992825, 1.01209877900331, -0.000800546649511458 },
541 { "2042-09-26", -0.00416154603709362, 1.02580615300844, -0.0011305804441839 },
542 { "2050-03-28", -0.00655222665784105, 1.07121045806809, -0.0022880532151871 }
543 };
544
545 BOOST_TEST_MESSAGE("Test rates from YieldCurve cached result");
546 for (Size i=0; i < expected.size(); ++i) {
547 BOOST_CHECK_CLOSE(
548 chfYieldCurve.handle()->zeroRate(
parseDate(expected[i].date),
549 Actual365Fixed(), Compounded,
550 Annual).rate(),
551 expected[i].zero, 1e-7
552 );
553 BOOST_CHECK_CLOSE(
554 chfYieldCurve.handle()->discount(
parseDate(expected[i].date)),
555 expected[i].discount, 1e-7
556 );
557 }
558 BOOST_TEST_MESSAGE("Test rates from YieldCurve cached result");
559 BOOST_CHECK_EQUAL(chfYieldCurve.handle()->discount(asof), 1);
560}
Date parseDate(const string &s)
Convert std::string to QuantLib::Date.
std::string to_string(const LocationInfo &l)