20#include <boost/test/unit_test.hpp>
25#include <oret/toplevelfixture.hpp>
26#include <ql/currencies/america.hpp>
27#include <ql/math/comparison.hpp>
28#include <ql/time/calendars/austria.hpp>
29#include <ql/time/calendars/chile.hpp>
30#include <ql/time/calendars/france.hpp>
31#include <ql/time/calendars/jointcalendar.hpp>
32#include <ql/time/calendars/thailand.hpp>
33#include <ql/time/daycounters/all.hpp>
43using namespace boost::unit_test_framework;
54struct test_daycounter_data {
59static struct test_daycounter_data daycounter_data[] = {
60 {
"A360", Actual360()},
61 {
"Actual/360", Actual360()},
62 {
"ACT/360", Actual360()},
63 {
"A365", Actual365Fixed()},
64 {
"A365F", Actual365Fixed()},
65 {
"Actual/365 (Fixed)", Actual365Fixed()},
66 {
"ACT/365", Actual365Fixed()},
67 {
"T360", Thirty360(Thirty360::USA)},
68 {
"30/360", Thirty360(Thirty360::USA)},
69 {
"30/360 (Bond Basis)", Thirty360(Thirty360::BondBasis)},
70 {
"ACT/nACT", Thirty360(Thirty360::USA)},
71 {
"30E/360 (Eurobond Basis)", Thirty360(Thirty360::European)},
72 {
"30E/360", Thirty360(Thirty360::European)},
73 {
"30/360 (Italian)", Thirty360(Thirty360::Italian)},
74 {
"ActActISDA", ActualActual(ActualActual::ISDA)},
75 {
"Actual/Actual (ISDA)", ActualActual(ActualActual::ISDA)},
76 {
"ACT/ACT", ActualActual(ActualActual::ISDA)},
77 {
"ACT29", ActualActual(ActualActual::AFB)},
78 {
"ACT", ActualActual(ActualActual::ISDA)},
79 {
"ActActISMA", ActualActual(ActualActual::ISMA)},
80 {
"Actual/Actual (ISMA)", ActualActual(ActualActual::ISMA)},
81 {
"ActActAFB", ActualActual(ActualActual::AFB)},
82 {
"Actual/Actual (AFB)", ActualActual(ActualActual::AFB)},
83 {
"1/1", OneDayCounter()},
84 {
"BUS/252", Business252()},
85 {
"Business/252", Business252()},
86 {
"Actual/365 (No Leap)", Actual365Fixed(Actual365Fixed::NoLeap)},
87 {
"Act/365 (NL)", Actual365Fixed(Actual365Fixed::NoLeap)},
88 {
"NL/365", Actual365Fixed(Actual365Fixed::NoLeap)},
89 {
"Actual/365 (JGB)", Actual365Fixed(Actual365Fixed::NoLeap)},
90 {
"Actual/364", Actual364()}};
92struct test_freq_data {
97static struct test_freq_data freq_data[] = {{
"Z", Once},
102 {
"Semiannual", Semiannual},
104 {
"Quarterly", Quarterly},
106 {
"Bimonthly", Bimonthly},
108 {
"Monthly", Monthly},
109 {
"L", EveryFourthWeek},
110 {
"Lunarmonth", EveryFourthWeek},
116struct test_comp_data {
121static struct test_comp_data comp_data[] = {
123 {
"Compounded", Compounded},
124 {
"Continuous", Continuous},
125 {
"SimpleThenCompounded", SimpleThenCompounded},
128void checkStrikeParser(
const std::string& s,
const ore::data::Strike::Type expectedType,
const Real expectedValue) {
130 BOOST_FAIL(
"unexpected strike type parsed from input string " << s);
133 BOOST_FAIL(
"unexpected strike value parsed from input string " << s);
138void checkCalendars(
const std::set<Date>& expectedHolidays,
const std::vector<Date>& testHolidays) {
140 for (
auto eh : expectedHolidays) {
141 if (std::find(testHolidays.begin(), testHolidays.end(), eh) == testHolidays.end())
142 BOOST_FAIL(
"expected holiday was " << eh <<
" not found ");
148BOOST_FIXTURE_TEST_SUITE(OREDataTestSuite, ore::test::TopLevelFixture)
150BOOST_AUTO_TEST_SUITE(ParserTests)
154 BOOST_TEST_MESSAGE(
"Testing day counter parsing...");
156 Size len =
sizeof(daycounter_data) /
sizeof(daycounter_data[0]);
157 for (Size i = 0; i < len; ++i) {
158 string str(daycounter_data[i].str);
159 QuantLib::DayCounter d;
164 BOOST_FAIL(
"Day Counter Parser failed to parse " << str);
166 if (d.empty() || d != daycounter_data[i].dc) {
167 BOOST_FAIL(
"Day Counter Parser(" << str <<
") returned day counter " << d <<
" expected "
168 << daycounter_data[i].dc);
170 BOOST_TEST_MESSAGE(
"Parsed \"" << str <<
"\" and got " << d);
177 BOOST_TEST_MESSAGE(
"Testing frequency parsing...");
179 Size len =
sizeof(freq_data) /
sizeof(freq_data[0]);
180 for (Size i = 0; i < len; ++i) {
181 string str(freq_data[i].str);
186 if (f != freq_data[i].freq)
187 BOOST_FAIL(
"Frequency Parser(" << str <<
") returned frequency " << f <<
" expected "
188 << freq_data[i].freq);
189 BOOST_TEST_MESSAGE(
"Parsed \"" << str <<
"\" and got " << f);
192 BOOST_FAIL(
"Frequency Parser failed to parse " << str);
199 BOOST_TEST_MESSAGE(
"Testing Compounding parsing...");
201 Size len =
sizeof(comp_data) /
sizeof(comp_data[0]);
202 for (Size i = 0; i < len; ++i) {
203 string str(comp_data[i].str);
208 if (c != comp_data[i].comp)
209 BOOST_FAIL(
"Compounding Parser(" << str <<
") returned Compounding " << c <<
" expected "
210 << comp_data[i].comp);
211 BOOST_TEST_MESSAGE(
"Parsed \"" << str <<
"\" and got " << c);
214 BOOST_FAIL(
"Compounding Parser failed to parse " << str);
221 BOOST_TEST_MESSAGE(
"Testing Strike parsing...");
266 BOOST_TEST_MESSAGE(
"Testing Date and Period parsing...");
314 BOOST_CHECK(isDate && d == Date(5, Jun, 2017));
316 BOOST_CHECK(!isDate && p == 3 * Years);
318 BOOST_CHECK(!isDate && p == 3 * Months);
320 BOOST_CHECK(!isDate && p == 3 * Weeks);
322 BOOST_CHECK(!isDate && p == 3 * Days);
324 BOOST_CHECK(!isDate && p == 1 * Years + 6 * Months);
326 BOOST_CHECK(!isDate && p == 20170605 * Days);
338 BOOST_TEST_MESSAGE(
"Testing market datum parsing...");
340 BOOST_TEST_MESSAGE(
"Testing cap/floor market datum parsing...");
343 Date d(1, Jan, 1990);
346 string input =
"CAPFLOOR/RATE_NVOL/USD/5Y/3M/0/0/0";
350 BOOST_CHECK(datum->asofDate() == d);
351 BOOST_CHECK(datum->quote()->value() ==
value);
355 QuantLib::ext::shared_ptr<ore::data::CapFloorQuote> capfloorVolDatum =
356 QuantLib::ext::dynamic_pointer_cast<ore::data::CapFloorQuote>(datum);
358 BOOST_CHECK(capfloorVolDatum->ccy() ==
"USD");
359 BOOST_CHECK(capfloorVolDatum->term() == Period(5, Years));
360 BOOST_CHECK(capfloorVolDatum->underlying() == Period(3, Months));
361 BOOST_CHECK(capfloorVolDatum->atm() ==
false);
362 BOOST_CHECK(capfloorVolDatum->relative() ==
false);
363 BOOST_CHECK_CLOSE(capfloorVolDatum->strike(), 0.0, 1e-12);
367 Date d(1, Jan, 1990);
370 string input =
"CAPFLOOR/RATE_SLNVOL/JPY/EYTIBOR/5Y/3M/1/1/0.0075";
374 BOOST_CHECK(datum->asofDate() == d);
375 BOOST_CHECK(datum->quote()->value() ==
value);
379 QuantLib::ext::shared_ptr<ore::data::CapFloorQuote> capfloorVolDatum =
380 QuantLib::ext::dynamic_pointer_cast<ore::data::CapFloorQuote>(datum);
382 BOOST_CHECK(capfloorVolDatum->ccy() ==
"JPY");
383 BOOST_CHECK(capfloorVolDatum->indexName() ==
"EYTIBOR");
384 BOOST_CHECK(capfloorVolDatum->term() == Period(5, Years));
385 BOOST_CHECK(capfloorVolDatum->underlying() == Period(3, Months));
386 BOOST_CHECK(capfloorVolDatum->atm() ==
true);
387 BOOST_CHECK(capfloorVolDatum->relative() ==
true);
388 BOOST_CHECK_CLOSE(capfloorVolDatum->strike(), 0.0075, 1e-12);
392 Date d(1, Jan, 1990);
395 string input =
"CAPFLOOR/SHIFT/USD/5Y";
399 BOOST_CHECK(datum->asofDate() == d);
400 BOOST_CHECK(datum->quote()->value() ==
value);
404 QuantLib::ext::shared_ptr<ore::data::CapFloorShiftQuote> capfloorShiftDatum =
405 QuantLib::ext::dynamic_pointer_cast<ore::data::CapFloorShiftQuote>(datum);
407 BOOST_CHECK(capfloorShiftDatum->ccy() ==
"USD");
408 BOOST_CHECK(capfloorShiftDatum->indexTenor() == Period(5, Years));
412 Date d(1, Jan, 1990);
415 string input =
"CAPFLOOR/SHIFT/JPY/EYTIBOR/5Y";
419 BOOST_CHECK(datum->asofDate() == d);
420 BOOST_CHECK(datum->quote()->value() ==
value);
424 QuantLib::ext::shared_ptr<ore::data::CapFloorShiftQuote> capfloorShiftDatum =
425 QuantLib::ext::dynamic_pointer_cast<ore::data::CapFloorShiftQuote>(datum);
427 BOOST_CHECK(capfloorShiftDatum->ccy() ==
"JPY");
428 BOOST_CHECK(capfloorShiftDatum->indexName() ==
"EYTIBOR");
429 BOOST_CHECK(capfloorShiftDatum->indexTenor() == Period(5, Years));
433 Date d(1, Jan, 1990);
436 string input =
"CAPFLOOR/PRICE/USD/5Y/3M/0/0/0/C";
440 BOOST_CHECK(datum->asofDate() == d);
441 BOOST_CHECK(datum->quote()->value() ==
value);
445 QuantLib::ext::shared_ptr<ore::data::CapFloorQuote> capfloorPremiumDatum =
446 QuantLib::ext::dynamic_pointer_cast<ore::data::CapFloorQuote>(datum);
448 BOOST_CHECK(capfloorPremiumDatum->ccy() ==
"USD");
449 BOOST_CHECK(capfloorPremiumDatum->term() == Period(5, Years));
450 BOOST_CHECK(capfloorPremiumDatum->underlying() == Period(3, Months));
451 BOOST_CHECK(capfloorPremiumDatum->atm() ==
false);
452 BOOST_CHECK(capfloorPremiumDatum->relative() ==
false);
453 BOOST_CHECK_CLOSE(capfloorPremiumDatum->strike(), 0.0, 1e-12);
454 BOOST_CHECK(capfloorPremiumDatum->isCap() ==
true);
458 Date d(1, Jan, 1990);
461 string input =
"CAPFLOOR/PRICE/JPY/EYTIBOR/5Y/3M/1/1/-0.0075/F";
465 BOOST_CHECK(datum->asofDate() == d);
466 BOOST_CHECK(datum->quote()->value() ==
value);
470 QuantLib::ext::shared_ptr<ore::data::CapFloorQuote> capfloorVolDatum =
471 QuantLib::ext::dynamic_pointer_cast<ore::data::CapFloorQuote>(datum);
473 BOOST_CHECK(capfloorVolDatum->ccy() ==
"JPY");
474 BOOST_CHECK(capfloorVolDatum->indexName() ==
"EYTIBOR");
475 BOOST_CHECK(capfloorVolDatum->term() == Period(5, Years));
476 BOOST_CHECK(capfloorVolDatum->underlying() == Period(3, Months));
477 BOOST_CHECK(capfloorVolDatum->atm() ==
true);
478 BOOST_CHECK(capfloorVolDatum->relative() ==
true);
479 BOOST_CHECK_CLOSE(capfloorVolDatum->strike(), -0.0075, 1e-12);
480 BOOST_CHECK(capfloorVolDatum->isCap() ==
false);
484 Date d(3, Mar, 2018);
506 BOOST_TEST_MESSAGE(
"Testing swaption market datum parsing...");
509 Date d(1, Jan, 1990);
512 string input =
"SWAPTION/RATE_NVOL/EUR/10Y/30Y/ATM";
519 QuantLib::ext::shared_ptr<ore::data::SwaptionQuote> swaptionVolDatum =
520 QuantLib::ext::dynamic_pointer_cast<ore::data::SwaptionQuote>(datum);
522 BOOST_CHECK(swaptionVolDatum->ccy() ==
"EUR");
523 BOOST_CHECK(swaptionVolDatum->expiry() == Period(10, Years));
524 BOOST_CHECK(swaptionVolDatum->term() == Period(30, Years));
525 BOOST_CHECK(swaptionVolDatum->dimension() ==
"ATM");
526 BOOST_CHECK_CLOSE(swaptionVolDatum->strike(), 0.0, 1e-12);
527 BOOST_CHECK(swaptionVolDatum->quoteTag() ==
"");
531 Date d(1, Jan, 1990);
534 string input =
"SWAPTION/RATE_NVOL/EUR/EURIBOR/10Y/30Y/Smile/-0.0025";
541 QuantLib::ext::shared_ptr<ore::data::SwaptionQuote> swaptionVolDatum =
542 QuantLib::ext::dynamic_pointer_cast<ore::data::SwaptionQuote>(datum);
544 BOOST_CHECK(swaptionVolDatum->ccy() ==
"EUR");
545 BOOST_CHECK(swaptionVolDatum->expiry() == Period(10, Years));
546 BOOST_CHECK(swaptionVolDatum->term() == Period(30, Years));
547 BOOST_CHECK(swaptionVolDatum->dimension() ==
"Smile");
548 BOOST_CHECK_CLOSE(swaptionVolDatum->strike(), -0.0025, 1e-12);
549 BOOST_CHECK(swaptionVolDatum->quoteTag() ==
"EURIBOR");
553 Date d(1, Jan, 1990);
556 string input =
"SWAPTION/RATE_SLNVOL/EUR/EURIBOR/10Y/30Y/Smile/-0.0025";
560 BOOST_CHECK(datum->asofDate() == d);
561 BOOST_CHECK(datum->quote()->value() ==
value);
565 QuantLib::ext::shared_ptr<ore::data::SwaptionQuote> swaptionVolDatum =
566 QuantLib::ext::dynamic_pointer_cast<ore::data::SwaptionQuote>(datum);
568 BOOST_CHECK(swaptionVolDatum->ccy() ==
"EUR");
569 BOOST_CHECK(swaptionVolDatum->expiry() == Period(10, Years));
570 BOOST_CHECK(swaptionVolDatum->term() == Period(30, Years));
571 BOOST_CHECK(swaptionVolDatum->dimension() ==
"Smile");
572 BOOST_CHECK_CLOSE(swaptionVolDatum->strike(), -0.0025, 1e-12);
573 BOOST_CHECK(swaptionVolDatum->quoteTag() ==
"EURIBOR");
577 Date d(1, Jan, 1990);
580 string input =
"SWAPTION/SHIFT/EUR/EURIBOR/30Y";
587 QuantLib::ext::shared_ptr<ore::data::SwaptionShiftQuote> swaptionShiftDatum =
588 QuantLib::ext::dynamic_pointer_cast<ore::data::SwaptionShiftQuote>(datum);
590 BOOST_CHECK(swaptionShiftDatum->ccy() ==
"EUR");
591 BOOST_CHECK(swaptionShiftDatum->term() == Period(30, Years));
592 BOOST_CHECK(swaptionShiftDatum->quoteTag() ==
"EURIBOR");
596 Date d(1, Jan, 1990);
599 string input =
"SWAPTION/PRICE/EUR/10Y/30Y/ATM/P";
606 QuantLib::ext::shared_ptr<ore::data::SwaptionQuote> swaptionPremiumDatum =
607 QuantLib::ext::dynamic_pointer_cast<ore::data::SwaptionQuote>(datum);
609 BOOST_CHECK(swaptionPremiumDatum->ccy() ==
"EUR");
610 BOOST_CHECK(swaptionPremiumDatum->expiry() == Period(10, Years));
611 BOOST_CHECK(swaptionPremiumDatum->term() == Period(30, Years));
612 BOOST_CHECK(swaptionPremiumDatum->dimension() ==
"ATM");
613 BOOST_CHECK_CLOSE(swaptionPremiumDatum->strike(), 0.0, 1e-12);
614 BOOST_CHECK(swaptionPremiumDatum->quoteTag() ==
"");
615 BOOST_CHECK(swaptionPremiumDatum->isPayer() ==
true);
619 Date d(1, Jan, 1990);
622 string input =
"SWAPTION/PRICE/EUR/EURIBOR/10Y/30Y/Smile/-0.0025/R";
629 QuantLib::ext::shared_ptr<ore::data::SwaptionQuote> swaptionPremiumDatum =
630 QuantLib::ext::dynamic_pointer_cast<ore::data::SwaptionQuote>(datum);
632 BOOST_CHECK(swaptionPremiumDatum->ccy() ==
"EUR");
633 BOOST_CHECK(swaptionPremiumDatum->expiry() == Period(10, Years));
634 BOOST_CHECK(swaptionPremiumDatum->term() == Period(30, Years));
635 BOOST_CHECK(swaptionPremiumDatum->dimension() ==
"Smile");
636 BOOST_CHECK_CLOSE(swaptionPremiumDatum->strike(), -0.0025, 1e-12);
637 BOOST_CHECK(swaptionPremiumDatum->quoteTag() ==
"EURIBOR");
638 BOOST_CHECK(swaptionPremiumDatum->isPayer() ==
false);
658 BOOST_TEST_MESSAGE(
"Testing correlation market datum parsing...");
661 Date d(1, Jan, 1990);
664 string input =
"CORRELATION/RATE/INDEX1/INDEX2/1Y/ATM";
668 BOOST_CHECK(datum->asofDate() == d);
669 BOOST_CHECK(datum->quote()->value() ==
value);
673 QuantLib::ext::shared_ptr<ore::data::CorrelationQuote> spreadDatum =
674 QuantLib::ext::dynamic_pointer_cast<ore::data::CorrelationQuote>(datum);
676 BOOST_CHECK(spreadDatum->index1() ==
"INDEX1");
677 BOOST_CHECK(spreadDatum->index2() ==
"INDEX2");
678 BOOST_CHECK(spreadDatum->expiry() ==
"1Y");
679 BOOST_CHECK(spreadDatum->strike() ==
"ATM");
683 Date d(3, Mar, 2018);
686 string input =
"CORRELATION/PRICE/INDEX1/INDEX2/1Y/0.1";
690 BOOST_CHECK(datum->asofDate() == d);
691 BOOST_CHECK(datum->quote()->value() ==
value);
695 QuantLib::ext::shared_ptr<ore::data::CorrelationQuote> spreadDatum =
696 QuantLib::ext::dynamic_pointer_cast<ore::data::CorrelationQuote>(datum);
698 BOOST_CHECK(spreadDatum->index1() ==
"INDEX1");
699 BOOST_CHECK(spreadDatum->index2() ==
"INDEX2");
700 BOOST_CHECK(spreadDatum->expiry() ==
"1Y");
701 BOOST_CHECK(spreadDatum->strike() ==
"0.1");
705 Date d(3, Mar, 2018);
714 BOOST_TEST_MESSAGE(
"Testing commodity spot market datum parsing...");
718 Date d(29, Jul, 2019);
721 string input =
"COMMODITY/PRICE/PM:XAUUSD/USD";
723 QuantLib::ext::shared_ptr<MarketDatum> datum = parseMarketDatum(d, input,
value);
725 BOOST_CHECK(datum->asofDate() == d);
726 BOOST_CHECK(datum->quote()->value() ==
value);
730 QuantLib::ext::shared_ptr<CommoditySpotQuote> q = QuantLib::ext::dynamic_pointer_cast<CommoditySpotQuote>(datum);
732 BOOST_CHECK(q->commodityName() ==
"PM:XAUUSD");
733 BOOST_CHECK(q->quoteCurrency() ==
"USD");
738 Date d(29, Jul, 2019);
741 BOOST_CHECK_THROW(parseMarketDatum(d,
"COMMODITY_SPOT/PRICE/PM:XAUUSD/USD",
value), Error);
742 BOOST_CHECK_THROW(parseMarketDatum(d,
"COMMODITY/RATE/PM:XAUUSD/USD",
value), Error);
743 BOOST_CHECK_THROW(parseMarketDatum(d,
"COMMODITY/PRICE/USD",
value), Error);
746 BOOST_TEST_MESSAGE(
"Testing commodity forward market datum parsing...");
750 Date d(29, Jul, 2019);
751 Real
value = 300.16535;
754 string input =
"COMMODITY_FWD/PRICE/PM:XAUUSD/USD/1M";
755 QuantLib::ext::shared_ptr<MarketDatum> datum = parseMarketDatum(d, input,
value);
757 BOOST_CHECK(datum->asofDate() == d);
758 BOOST_CHECK(datum->quote()->value() ==
value);
762 QuantLib::ext::shared_ptr<CommodityForwardQuote> q = QuantLib::ext::dynamic_pointer_cast<CommodityForwardQuote>(datum);
763 BOOST_CHECK(q->commodityName() ==
"PM:XAUUSD");
764 BOOST_CHECK(q->quoteCurrency() ==
"USD");
765 BOOST_CHECK(q->tenorBased());
766 BOOST_CHECK(q->expiryDate() == Date());
767 BOOST_CHECK(q->tenor() == 1 * Months);
768 BOOST_CHECK(q->startTenor() == boost::none);
771 input =
"COMMODITY_FWD/PRICE/PM:XAUUSD/USD/2019-08-30";
772 datum = parseMarketDatum(d, input,
value);
773 q = QuantLib::ext::dynamic_pointer_cast<CommodityForwardQuote>(datum);
774 BOOST_CHECK(q->commodityName() ==
"PM:XAUUSD");
775 BOOST_CHECK(q->quoteCurrency() ==
"USD");
776 BOOST_CHECK(!q->tenorBased());
777 BOOST_CHECK(q->expiryDate() == Date(30, Aug, 2019));
778 BOOST_CHECK(q->tenor() == Period());
779 BOOST_CHECK(q->startTenor() == boost::none);
784 input =
"COMMODITY_FWD/PRICE/PM:XAUUSD/USD/ON";
785 datum = parseMarketDatum(d, input,
value);
786 q = QuantLib::ext::dynamic_pointer_cast<CommodityForwardQuote>(datum);
787 BOOST_CHECK(q->tenorBased());
788 BOOST_CHECK(q->expiryDate() == Date());
789 BOOST_CHECK(q->tenor() == 1 * Days);
790 BOOST_CHECK(q->startTenor() == 0 * Days);
793 input =
"COMMODITY_FWD/PRICE/PM:XAUUSD/USD/TN";
794 datum = parseMarketDatum(d, input,
value);
795 q = QuantLib::ext::dynamic_pointer_cast<CommodityForwardQuote>(datum);
796 BOOST_CHECK(q->tenorBased());
797 BOOST_CHECK(q->expiryDate() == Date());
798 BOOST_CHECK(q->tenor() == 1 * Days);
799 BOOST_CHECK(q->startTenor() == 1 * Days);
802 input =
"COMMODITY_FWD/PRICE/PM:XAUUSD/USD/SN";
803 datum = parseMarketDatum(d, input,
value);
804 q = QuantLib::ext::dynamic_pointer_cast<CommodityForwardQuote>(datum);
805 BOOST_CHECK(q->tenorBased());
806 BOOST_CHECK(q->expiryDate() == Date());
807 BOOST_CHECK(q->tenor() == 1 * Days);
808 BOOST_CHECK(q->startTenor() == boost::none);
813 Date d(29, Jul, 2019);
814 Real
value = 300.16535;
816 BOOST_CHECK_THROW(parseMarketDatum(d,
"COMMODITY_FORWARD/PRICE/PM:XAUUSD/USD/1M",
value), Error);
817 BOOST_CHECK_THROW(parseMarketDatum(d,
"COMMODITY_FWD/RATE/PM:XAUUSD/USD/1M",
value), Error);
818 BOOST_CHECK_THROW(parseMarketDatum(d,
"COMMODITY_FWD/PRICE/USD/1M",
value), Error);
819 BOOST_CHECK_THROW(parseMarketDatum(d,
"COMMODITY_FWD/PRICE/PM:XAUUSD/USD/2019-12",
value), Error);
822 BOOST_TEST_MESSAGE(
"Testing fx option market datum parsing...");
826 Date d(29, Jul, 2019);
830 string input =
"FX_OPTION/RATE_LNVOL/EUR/USD/1M/ATM";
831 QuantLib::ext::shared_ptr<MarketDatum> datum = parseMarketDatum(d, input,
value);
833 BOOST_CHECK(datum->asofDate() == d);
834 BOOST_CHECK(datum->quote()->value() ==
value);
838 QuantLib::ext::shared_ptr<FXOptionQuote> q = QuantLib::ext::dynamic_pointer_cast<FXOptionQuote>(datum);
839 BOOST_CHECK(q->unitCcy() ==
"EUR");
840 BOOST_CHECK(q->ccy() ==
"USD");
841 BOOST_CHECK(q->expiry() == Period(1, Months));
842 BOOST_CHECK(q->strike() ==
"ATM");
845 input =
"FX_OPTION/RATE_LNVOL/EUR/USD/2M/25BF";
846 datum = parseMarketDatum(d, input,
value);
847 q = QuantLib::ext::dynamic_pointer_cast<FXOptionQuote>(datum);
848 BOOST_CHECK(q->unitCcy() ==
"EUR");
849 BOOST_CHECK(q->ccy() ==
"USD");
850 BOOST_CHECK(q->expiry() == Period(2, Months));
851 BOOST_CHECK(q->strike() ==
"25BF");
853 input =
"FX_OPTION/RATE_LNVOL/EUR/USD/2M/10BF";
854 datum = parseMarketDatum(d, input,
value);
855 q = QuantLib::ext::dynamic_pointer_cast<FXOptionQuote>(datum);
856 BOOST_CHECK(q->unitCcy() ==
"EUR");
857 BOOST_CHECK(q->ccy() ==
"USD");
858 BOOST_CHECK(q->expiry() == Period(2, Months));
859 BOOST_CHECK(q->strike() ==
"10BF");
862 input =
"FX_OPTION/RATE_LNVOL/EUR/USD/2M/25RR";
863 datum = parseMarketDatum(d, input,
value);
864 q = QuantLib::ext::dynamic_pointer_cast<FXOptionQuote>(datum);
865 BOOST_CHECK(q->unitCcy() ==
"EUR");
866 BOOST_CHECK(q->ccy() ==
"USD");
867 BOOST_CHECK(q->expiry() == Period(2, Months));
868 BOOST_CHECK(q->strike() ==
"25RR");
870 input =
"FX_OPTION/RATE_LNVOL/EUR/USD/2M/10RR";
871 datum = parseMarketDatum(d, input,
value);
872 q = QuantLib::ext::dynamic_pointer_cast<FXOptionQuote>(datum);
873 BOOST_CHECK(q->unitCcy() ==
"EUR");
874 BOOST_CHECK(q->ccy() ==
"USD");
875 BOOST_CHECK(q->expiry() == Period(2, Months));
876 BOOST_CHECK(q->strike() ==
"10RR");
879 input =
"FX_OPTION/RATE_LNVOL/EUR/USD/2M/10C";
880 datum = parseMarketDatum(d, input,
value);
881 q = QuantLib::ext::dynamic_pointer_cast<FXOptionQuote>(datum);
882 BOOST_CHECK(q->unitCcy() ==
"EUR");
883 BOOST_CHECK(q->ccy() ==
"USD");
884 BOOST_CHECK(q->expiry() == Period(2, Months));
885 BOOST_CHECK(q->strike() ==
"10C");
887 input =
"FX_OPTION/RATE_LNVOL/EUR/USD/2M/20P";
888 datum = parseMarketDatum(d, input,
value);
889 q = QuantLib::ext::dynamic_pointer_cast<FXOptionQuote>(datum);
890 BOOST_CHECK(q->unitCcy() ==
"EUR");
891 BOOST_CHECK(q->ccy() ==
"USD");
892 BOOST_CHECK(q->expiry() == Period(2, Months));
893 BOOST_CHECK(q->strike() ==
"20P");
897 Date d(29, Jul, 2019);
898 Real
value = 300.16535;
900 BOOST_CHECK_THROW(parseMarketDatum(d,
"FX_OPTION/RATE_LNVOL/EUR/USD/1M/ATMF",
value), Error);
901 BOOST_CHECK_THROW(parseMarketDatum(d,
"FX_OPTION/RATE_LNVOL/EUR/USD/1M/BBFF",
value), Error);
902 BOOST_CHECK_THROW(parseMarketDatum(d,
"FX_OPTION/RATE_LNVOL/EUR/USD/1M/1LRR",
value), Error);
903 BOOST_CHECK_THROW(parseMarketDatum(d,
"FX_OPTION/RATE_LNVOL/EUR/USD/1M/10D",
value), Error);
904 BOOST_CHECK_THROW(parseMarketDatum(d,
"FX_OPTION/RATE_LNVOL/EUR/USD/1M",
value), Error);
905 BOOST_CHECK_THROW(parseMarketDatum(d,
"FX_OPTION/RATE_LNVOL/EUR/USD/2019-12",
value), Error);
912 std::vector<Calendar> cals;
913 std::set<Date> expectedHolidays;
915 expectedHolidays.insert(Date(1, January, 2018));
916 expectedHolidays.insert(Date(29, March, 2018));
917 expectedHolidays.insert(Date(30, March, 2018));
918 expectedHolidays.insert(Date(1, May, 2018));
919 expectedHolidays.insert(Date(29, June, 2018));
920 expectedHolidays.insert(Date(27, July, 2018));
921 expectedHolidays.insert(Date(30, August, 2018));
922 expectedHolidays.insert(Date(31, August, 2018));
923 expectedHolidays.insert(Date(8, October, 2018));
924 expectedHolidays.insert(Date(1, November, 2018));
925 expectedHolidays.insert(Date(2, November, 2018));
926 expectedHolidays.insert(Date(25, December, 2018));
930 cals.push_back(peru);
931 Calendar joint1 = QuantLib::JointCalendar(cals);
933 std::vector<Date> hol = joint1.holidayList(Date(1, January, 2018), Date(31, December, 2018));
934 BOOST_CHECK(hol.size() == expectedHolidays.size());
939 expectedHolidays.insert(Date(1, January, 2018));
940 expectedHolidays.insert(Date(8, January, 2018));
941 expectedHolidays.insert(Date(19, March, 2018));
942 expectedHolidays.insert(Date(29, March, 2018));
943 expectedHolidays.insert(Date(30, March, 2018));
944 expectedHolidays.insert(Date(1, May, 2018));
945 expectedHolidays.insert(Date(14, May, 2018));
946 expectedHolidays.insert(Date(4, June, 2018));
947 expectedHolidays.insert(Date(11, June, 2018));
948 expectedHolidays.insert(Date(2, July, 2018));
949 expectedHolidays.insert(Date(20, July, 2018));
950 expectedHolidays.insert(Date(7, August, 2018));
951 expectedHolidays.insert(Date(20, August, 2018));
952 expectedHolidays.insert(Date(15, October, 2018));
953 expectedHolidays.insert(Date(5, November, 2018));
954 expectedHolidays.insert(Date(12, November, 2018));
955 expectedHolidays.insert(Date(25, December, 2018));
959 Calendar joint2 = QuantLib::JointCalendar(cals);
961 hol = joint2.holidayList(Date(1, January, 2018), Date(31, December, 2018));
962 BOOST_CHECK(hol.size() == expectedHolidays.size());
966 expectedHolidays.insert(Date(1, January, 2018));
967 expectedHolidays.insert(Date(2, January, 2018));
968 expectedHolidays.insert(Date(29, March, 2018));
969 expectedHolidays.insert(Date(30, March, 2018));
970 expectedHolidays.insert(Date(9, April, 2018));
971 expectedHolidays.insert(Date(1, May, 2018));
972 expectedHolidays.insert(Date(12, June, 2018));
973 expectedHolidays.insert(Date(21, August, 2018));
974 expectedHolidays.insert(Date(27, August, 2018));
975 expectedHolidays.insert(Date(1, November, 2018));
976 expectedHolidays.insert(Date(30, November, 2018));
977 expectedHolidays.insert(Date(25, December, 2018));
978 expectedHolidays.insert(Date(31, December, 2018));
981 cals.push_back(phil);
982 Calendar joint3 = QuantLib::JointCalendar(cals);
984 hol = joint3.holidayList(Date(1, January, 2018), Date(31, December, 2018));
985 BOOST_CHECK(hol.size() == expectedHolidays.size());
989 expectedHolidays.insert(Date(1, January, 2018));
990 expectedHolidays.insert(Date(2, January, 2018));
991 expectedHolidays.insert(Date(1, March, 2018));
992 expectedHolidays.insert(Date(6, April, 2018));
993 expectedHolidays.insert(Date(13, April, 2018));
994 expectedHolidays.insert(Date(16, April, 2018));
995 expectedHolidays.insert(Date(1, May, 2018));
996 expectedHolidays.insert(Date(29, May, 2018));
997 expectedHolidays.insert(Date(27, July, 2018));
998 expectedHolidays.insert(Date(30, July, 2018));
999 expectedHolidays.insert(Date(13, August, 2018));
1000 expectedHolidays.insert(Date(15, October, 2018));
1001 expectedHolidays.insert(Date(23, October, 2018));
1002 expectedHolidays.insert(Date(5, December, 2018));
1003 expectedHolidays.insert(Date(10, December, 2018));
1004 expectedHolidays.insert(Date(31, December, 2018));
1006 Calendar thai = Thailand();
1007 cals.push_back(thai);
1008 Calendar joint4 = QuantLib::JointCalendar(cals);
1010 hol = joint4.holidayList(Date(1, January, 2018), Date(31, December, 2018));
1011 BOOST_CHECK(hol.size() == expectedHolidays.size());
1015 expectedHolidays.insert(Date(1, January, 2018));
1016 expectedHolidays.insert(Date(1, February, 2018));
1017 expectedHolidays.insert(Date(1, May, 2018));
1018 expectedHolidays.insert(Date(31, August, 2018));
1019 expectedHolidays.insert(Date(17, September, 2018));
1020 expectedHolidays.insert(Date(25, December, 2018));
1023 cals.push_back(mal);
1024 Calendar joint5 = QuantLib::JointCalendar(cals);
1026 hol = joint5.holidayList(Date(1, January, 2018), Date(31, December, 2018));
1027 BOOST_CHECK(hol.size() == expectedHolidays.size());
1031 expectedHolidays.insert(Date(1, January, 2018));
1032 expectedHolidays.insert(Date(30, March, 2018));
1033 expectedHolidays.insert(Date(1, May, 2018));
1034 expectedHolidays.insert(Date(21, May, 2018));
1035 expectedHolidays.insert(Date(2, July, 2018));
1036 expectedHolidays.insert(Date(16, July, 2018));
1037 expectedHolidays.insert(Date(15, August, 2018));
1038 expectedHolidays.insert(Date(17, September, 2018));
1039 expectedHolidays.insert(Date(18, September, 2018));
1040 expectedHolidays.insert(Date(19, September, 2018));
1041 expectedHolidays.insert(Date(15, October, 2018));
1042 expectedHolidays.insert(Date(1, November, 2018));
1043 expectedHolidays.insert(Date(2, November, 2018));
1044 expectedHolidays.insert(Date(25, December, 2018));
1046 Calendar chil = Chile();
1047 cals.push_back(chil);
1048 Calendar joint6 = QuantLib::JointCalendar(cals);
1050 hol = joint6.holidayList(Date(1, January, 2018), Date(31, December, 2018));
1051 BOOST_CHECK(hol.size() == expectedHolidays.size());
1055 expectedHolidays.insert(Date(1, January, 2018));
1056 expectedHolidays.insert(Date(30, March, 2018));
1057 expectedHolidays.insert(Date(2, April, 2018));
1058 expectedHolidays.insert(Date(27, April, 2018));
1059 expectedHolidays.insert(Date(10, May, 2018));
1060 expectedHolidays.insert(Date(21, May, 2018));
1061 expectedHolidays.insert(Date(25, December, 2018));
1062 expectedHolidays.insert(Date(26, December, 2018));
1065 cals.push_back(net);
1066 Calendar joint7 = QuantLib::JointCalendar(cals);
1068 hol = joint7.holidayList(Date(1, January, 2018), Date(31, December, 2018));
1069 BOOST_CHECK(hol.size() == expectedHolidays.size());
1073 expectedHolidays.insert(Date(1, January, 2018));
1074 expectedHolidays.insert(Date(30, March, 2018));
1075 expectedHolidays.insert(Date(2, April, 2018));
1076 expectedHolidays.insert(Date(1, May, 2018));
1077 expectedHolidays.insert(Date(8, May, 2018));
1078 expectedHolidays.insert(Date(10, May, 2018));
1079 expectedHolidays.insert(Date(21, May, 2018));
1080 expectedHolidays.insert(Date(15, August, 2018));
1081 expectedHolidays.insert(Date(1, November, 2018));
1082 expectedHolidays.insert(Date(25, December, 2018));
1083 expectedHolidays.insert(Date(26, December, 2018));
1086 cals.push_back(fre);
1087 Calendar joint8 = QuantLib::JointCalendar(cals);
1089 hol = joint8.holidayList(Date(1, January, 2018), Date(31, December, 2018));
1090 BOOST_CHECK(hol.size() == expectedHolidays.size());
1096 BOOST_TEST_MESSAGE(
"Testing parsing of Boost::Any...");
1100 boost::any any_array = boost::any_cast<Array>(arr);
1101 std::pair<std::string, std::string> result;
1103 BOOST_CHECK_EQUAL(result.first,
"array");
1104 BOOST_CHECK_EQUAL(result.second,
"[ 3; 3; 3; 3; 3 ]");
1109 BOOST_TEST_MESSAGE(
"Testing parsing of Boost::Any...");
1111 Currency usd = USDCurrency();
1112 std::pair<std::string, std::string> result;
1114 BOOST_CHECK_EQUAL(result.first,
"currency");
1115 BOOST_CHECK_EQUAL(result.second,
"USD");
1118BOOST_AUTO_TEST_SUITE_END()
1120BOOST_AUTO_TEST_SUITE_END()
Commodity forward quote class.
Commodity spot quote class.
SafeStack< ValueType > value
QuantLib::ext::shared_ptr< MarketDatum > parseMarketDatum(const Date &asof, const string &datumName, const Real &value)
Function to parse a market datum.
Strike parseStrike(const std::string &s)
Convert text to Strike.
pair< string, string > parseBoostAny(const boost::any &anyType, Size precision)
Date parseDate(const string &s)
Convert std::string to QuantLib::Date.
boost::variant< QuantLib::Date, QuantLib::Period > parseDateOrPeriod(const string &s)
Convert text to QuantLib::Period or QuantLib::Date.
Period parsePeriod(const string &s)
Convert text to QuantLib::Period.
Frequency parseFrequency(const string &s)
Convert text to QuantLib::Frequency.
Compounding parseCompounding(const string &s)
Convert text to QuantLib::Compounding;.
DayCounter parseDayCounter(const string &s)
Convert text to QuantLib::DayCounter.
Filter close_enough(const RandomVariable &x, const RandomVariable &y)
void checkCalendars(const std::vector< Date > &expectedHolidays, const std::vector< Date > &testHolidays)
BOOST_AUTO_TEST_CASE(testDayCounterParsing)
Map text representations to QuantLib/QuantExt types.