Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
Functions
todaysmarket.cpp File Reference
#include <boost/test/unit_test.hpp>
#include <ored/configuration/volatilityconfig.hpp>
#include <ored/marketdata/loader.hpp>
#include <ored/marketdata/marketdatumparser.hpp>
#include <ored/marketdata/todaysmarket.hpp>
#include <ored/portfolio/builders/cms.hpp>
#include <ored/portfolio/builders/cmsspread.hpp>
#include <ored/portfolio/builders/swap.hpp>
#include <ored/portfolio/legbuilders.hpp>
#include <ored/portfolio/swap.hpp>
#include <ored/utilities/parsers.hpp>
#include <ored/utilities/to_string.hpp>
#include <oret/toplevelfixture.hpp>
#include <ql/time/calendars/all.hpp>
#include <ql/time/daycounters/actual360.hpp>
#include <ql/utilities/dataformatters.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/assign/list_of.hpp>
#include <map>

Go to the source code of this file.

Functions

 BOOST_AUTO_TEST_CASE (testZeroSpreadedYieldCurve)
 
 BOOST_AUTO_TEST_CASE (testNormalOptionletVolatility)
 
 BOOST_AUTO_TEST_CASE (testEquityCurve)
 
 BOOST_AUTO_TEST_CASE (testEquityVolCurve)
 
 BOOST_AUTO_TEST_CASE (testCommodityCurve)
 
 BOOST_AUTO_TEST_CASE (testCorrelationCurve)
 

Function Documentation

◆ BOOST_AUTO_TEST_CASE() [1/6]

BOOST_AUTO_TEST_CASE ( testZeroSpreadedYieldCurve  )

Definition at line 806 of file todaysmarket.cpp.

806 {
807
808 BOOST_TEST_MESSAGE("Testing zero spreaded yield curve rates...");
809
810 Handle<YieldTermStructure> dts = market->discountCurve("EUR");
811 Handle<YieldTermStructure> dtsLend = market->yieldCurve("EUR_LEND");
812 Handle<YieldTermStructure> dtsBorrow = market->yieldCurve("EUR_BORROW");
813
814 QL_REQUIRE(!dts.empty(), "EUR discount curve not found");
815 QL_REQUIRE(!dtsLend.empty(), "EUR lending curve not found");
816 QL_REQUIRE(!dtsBorrow.empty(), "EUR borrowing curve not found");
817
818 Date today = Settings::instance().evaluationDate();
819 DayCounter dc = Actual365Fixed();
820 Real tolerance = 1.0e-5; // 0.1 bp
821 Real expected1 = 0.005;
822 Real expected2 = -0.001;
823 for (Size i = 1; i <= 120; i++) {
824 Date d = today + i * Months;
825 Real z0 = dts->zeroRate(d, dc, Continuous);
826 Real z1 = dtsLend->zeroRate(d, dc, Continuous);
827 Real z2 = dtsBorrow->zeroRate(d, dc, Continuous);
828 BOOST_CHECK_MESSAGE(fabs(z1 - z0 - expected1) < tolerance, "error in lending spread curve setup");
829 BOOST_CHECK_MESSAGE(fabs(z2 - z0 - expected2) < tolerance, "error in borrowing spread curve setup");
830 }
831}

◆ BOOST_AUTO_TEST_CASE() [2/6]

BOOST_AUTO_TEST_CASE ( testNormalOptionletVolatility  )

Definition at line 833 of file todaysmarket.cpp.

833 {
834
835 BOOST_TEST_MESSAGE("Testing normal optionlet volatilities...");
836
837 Handle<OptionletVolatilityStructure> ovs = market->capFloorVol("USD");
838
839 BOOST_CHECK_MESSAGE(!ovs.empty(), "USD lognormal optionlet volatility structure was not created");
840 BOOST_CHECK_MESSAGE(ovs->volatilityType() == Normal,
841 "USD lognormal capfloor volatility was not converted to Normal optionlet volatility");
842
843 // Test against some expected values
844 Real tolerance = 1.0e-6;
845 vector<Period> tenors{1 * Years, 2 * Years, 5 * Years, 7 * Years, 10 * Years};
846 vector<Rate> strikes{0.005, 0.010, 0.015, 0.020, 0.025, 0.030};
847 // clang-format off
848 vector<vector<Real>> cachedValues{
849 { 0.004336061, 0.004790686, 0.005541127, 0.006411979, 0.007242633, 0.007889790 },
850 { 0.005904299, 0.006478381, 0.006929551, 0.007486301, 0.008139029, 0.008566001 },
851 { 0.008871166, 0.009370956, 0.009723190, 0.010015776, 0.010243227, 0.010492463 },
852 { 0.008517407, 0.008700672, 0.008661611, 0.008631934, 0.008657444, 0.008690871 },
853 { 0.007641226, 0.007821393, 0.007889650, 0.007980682, 0.008075806, 0.008235808 }
854 };
855 // clang-format on
856
857 for (Size i = 0; i < tenors.size(); ++i) {
858 for (Size j = 0; j < strikes.size(); ++j) {
859 Volatility v = ovs->volatility(tenors[i], strikes[j]);
860 Real error = fabs(v - cachedValues[i][j]);
861 // clang-format off
862 BOOST_CHECK_MESSAGE(error < tolerance,
863 "\ncap tenor: " << tenors[i] <<
864 "\nstrike: " << io::rate(strikes[j]) <<
865 "\ncached volatility: " << io::volatility(cachedValues[i][j]) <<
866 "\nvolatility: " << io::volatility(v) <<
867 "\nerror: " << io::rate(error) <<
868 "\ntolerance: " << io::rate(tolerance));
869 // clang-format on
870 }
871 }
872}
Real error
Definition: utilities.cpp:65
vector< Real > strikes

◆ BOOST_AUTO_TEST_CASE() [3/6]

BOOST_AUTO_TEST_CASE ( testEquityCurve  )

Definition at line 874 of file todaysmarket.cpp.

874 {
875
876 BOOST_TEST_MESSAGE("Testing equity curve...");
877
878 Handle<YieldTermStructure> divTs = market->equityDividendCurve("SP5");
879 BOOST_CHECK(divTs.currentLink());
880 Handle<YieldTermStructure> equityIrTs = market->discountCurve("USD");
881 BOOST_CHECK(equityIrTs.currentLink());
882 Handle<Quote> equitySpot = market->equitySpot("SP5");
883 BOOST_CHECK(equitySpot.currentLink());
884 Real spotVal = equitySpot->value();
885 DayCounter divDc = divTs->dayCounter();
886
887 Date today = Settings::instance().evaluationDate();
888 Date d_1y = Date(27, Feb, 2017);
889 Date d_2y = Date(26, Feb, 2018);
890 Rate r_1y = equityIrTs->zeroRate(d_1y, divDc, Continuous);
891 Rate r_2y = equityIrTs->zeroRate(d_2y, divDc, Continuous);
892 Rate q_1y = divTs->zeroRate(d_1y, divDc, Continuous);
893 Rate q_2y = divTs->zeroRate(d_2y, divDc, Continuous);
894 Real f_1y = spotVal * std::exp((r_1y - q_1y) * (divDc.yearFraction(today, d_1y)));
895 Real f_2y = spotVal * std::exp((r_2y - q_2y) * (divDc.yearFraction(today, d_2y)));
896 BOOST_CHECK_CLOSE(1500.00, f_1y, 1.e-10); // hardcoded, to be the same as the input quote
897 BOOST_CHECK_CLOSE(1500.0, f_2y, 1.e-10); // hardcoded, to be the same as the input quote
898
899 // test flat extrapolation of the dividend yield term structure (N.B. NOT FLAT ON FORWARDS!)
900 Rate q_5y = divTs->zeroRate(5.0, Continuous);
901 Rate q_50y = divTs->zeroRate(50.0, Continuous);
902 BOOST_CHECK_CLOSE(q_5y, q_50y, 1.e-10);
903
904 // test that the t=0 forward value is equal to the spot
905 Rate r_0 = equityIrTs->zeroRate(0.0, Continuous);
906 Rate q_0 = divTs->zeroRate(0.0, Continuous);
907 Real fwd_0 = spotVal * std::exp((r_0 - q_0) * 0.0);
908 BOOST_CHECK_EQUAL(spotVal, fwd_0);
909}

◆ BOOST_AUTO_TEST_CASE() [4/6]

BOOST_AUTO_TEST_CASE ( testEquityVolCurve  )

Definition at line 911 of file todaysmarket.cpp.

911 {
912
913 BOOST_TEST_MESSAGE("Testing equity vol curve...");
914
915 Handle<BlackVolTermStructure> eqVol = market->equityVol("SP5");
916 BOOST_CHECK(eqVol.currentLink());
917
918 Date d_1y = Date(27, Feb, 2017);
919 Date d_2y = Date(26, Feb, 2018);
920 Volatility v_1y_atm = eqVol->blackVol(d_1y, 0.0);
921 Volatility v_1y_smile = eqVol->blackVol(d_1y, 2000.0);
922 BOOST_CHECK_EQUAL(v_1y_atm, v_1y_smile); // test ATM flat smile
923 BOOST_CHECK_EQUAL(v_1y_atm, 0.25); // test input = output
924 Volatility v_2y_atm = eqVol->blackVol(d_2y, 0.0);
925 Volatility v_2y_smile = eqVol->blackVol(d_2y, 2000.0);
926 BOOST_CHECK_EQUAL(v_2y_atm, v_2y_smile); // test ATM flat smile
927 BOOST_CHECK_EQUAL(v_2y_atm, 0.35); // test input = output
928
929 // test flat extrapolation
930 Volatility v_5y_atm = eqVol->blackVol(5.0, 0.0);
931 Volatility v_50y_atm = eqVol->blackVol(50.0, 0.0);
932 BOOST_CHECK_CLOSE(v_5y_atm, v_50y_atm, 1.e-10);
933}

◆ BOOST_AUTO_TEST_CASE() [5/6]

BOOST_AUTO_TEST_CASE ( testCommodityCurve  )

Definition at line 935 of file todaysmarket.cpp.

935 {
936
937 BOOST_TEST_MESSAGE("Testing commodity price curve");
938
939 // Just test that the building succeeded - the curve itself has been tested elsewhere
940 Handle<PriceTermStructure> commodityCurve = market->commodityPriceCurve("COMDTY_GOLD_USD");
941 BOOST_CHECK(*commodityCurve);
942}

◆ BOOST_AUTO_TEST_CASE() [6/6]

BOOST_AUTO_TEST_CASE ( testCorrelationCurve  )

Definition at line 944 of file todaysmarket.cpp.

944 {
945
946 BOOST_TEST_MESSAGE("Testing correlation curve");
947
948 // Just test that the building succeeded - the curve itself has been tested elsewhere
949 Handle<QuantExt::CorrelationTermStructure> correlationCurve1 =
950 market->correlationCurve("EUR-CMS-10Y", "EUR-CMS-2Y");
951 Handle<QuantExt::CorrelationTermStructure> correlationCurve2 =
952 market->correlationCurve("USD-CMS-10Y", "USD-CMS-2Y");
953 BOOST_CHECK(*correlationCurve1);
954 BOOST_CHECK(*correlationCurve2);
955
956 Calendar calendar = TARGET();
957 Date qlStartDate = calendar.advance(calendar.advance(market->asofDate(), 2 * Days), 0 * Months);
958 Date qlEndDate1Y = calendar.advance(qlStartDate, 1 * Years, ModifiedFollowing);
959 Date qlEndDate2Y = calendar.advance(qlStartDate, 2 * Years, ModifiedFollowing);
960 string startDate = ore::data::to_string(qlStartDate);
961 string endDate1Y = ore::data::to_string(qlEndDate1Y);
962 string endDate2Y = ore::data::to_string(qlEndDate2Y);
963
964 BOOST_TEST_MESSAGE(startDate);
965 BOOST_TEST_MESSAGE(endDate1Y);
966 BOOST_TEST_MESSAGE(endDate2Y);
967
968 ScheduleData cms1YSchedule(ScheduleRules(startDate, endDate1Y, "3M", "TARGET", "MF", "MF", "Forward", "N"));
969 ScheduleData cms2YSchedule(ScheduleRules(startDate, endDate2Y, "3M", "TARGET", "MF", "MF", "Forward", "N"));
970
971 Real fairSpread1Y = 0.00752401;
972 Real fairSpread2Y = 0.00755509;
973
974 LegData cms1YLeg(QuantLib::ext::make_shared<CMSSpreadLegData>(
975 "USD-CMS-10Y", "USD-CMS-2Y", 2, true, std::vector<Real>(1, 0.0), vector<string>(),
976 std::vector<Real>(1, fairSpread1Y), vector<string>(), vector<double>(), vector<string>(),
977 vector<double>(), vector<string>(), true),
978 false, "USD", cms1YSchedule, "A360", std::vector<Real>(1, 1));
979 vector<LegData> legs1Y;
980 legs1Y.push_back(cms1YLeg);
981
982 LegData cms2YLeg(QuantLib::ext::make_shared<CMSSpreadLegData>(
983 "USD-CMS-10Y", "USD-CMS-2Y", 2, true, std::vector<Real>(1, 0.0), vector<string>(),
984 std::vector<Real>(1, fairSpread2Y), vector<string>(), vector<double>(), vector<string>(),
985 vector<double>(), vector<string>(), true),
986 false, "USD", cms2YSchedule, "A360", std::vector<Real>(1, 1));
987 vector<LegData> legs2Y;
988 legs2Y.push_back(cms2YLeg);
989
990 Envelope env("CP1");
991
992 ore::data::Swap cmsSpread1YCap(env, legs1Y);
993 ore::data::Swap cmsSpread2YCap(env, legs2Y);
994
995 Real expectedNpv1Y = 0.0038614;
996 Real expectedNpv2Y = 0.0105279;
997
998 // Build and price
999 QuantLib::ext::shared_ptr<EngineData> engineData = QuantLib::ext::make_shared<EngineData>();
1000 engineData->model("CMS") = "LinearTSR";
1001 engineData->engine("CMS") = "LinearTSRPricer";
1002
1003 map<string, string> engineparams1;
1004 engineparams1["MeanReversion"] = "0.0";
1005 engineparams1["Policy"] = "RateBound";
1006 engineparams1["LowerRateBoundLogNormal"] = "0.0001";
1007 engineparams1["UpperRateBoundLogNormal"] = "2";
1008 engineparams1["LowerRateBoundNormal"] = "-2";
1009 engineparams1["UpperRateBoundNormal"] = "2";
1010 engineparams1["VegaRatio"] = "0.01";
1011 engineparams1["PriceThreshold"] = "0.0000001";
1012 engineparams1["BsStdDev"] = "3";
1013 engineData->engineParameters("CMS") = engineparams1;
1014
1015 engineData->model("CMSSpread") = "BrigoMercurio";
1016 engineData->engine("CMSSpread") = "Analytic";
1017 map<string, string> engineparams2;
1018 engineparams2["IntegrationPoints"] = "16";
1019 engineData->engineParameters("CMSSpread") = engineparams2;
1020
1021 engineData->model("Swap") = "DiscountedCashflows";
1022 engineData->engine("Swap") = "DiscountingSwapEngine";
1023
1024 QuantLib::ext::shared_ptr<EngineFactory> engineFactory = QuantLib::ext::make_shared<EngineFactory>(engineData, market);
1025
1026 cmsSpread1YCap.build(engineFactory);
1027 cmsSpread2YCap.build(engineFactory);
1028
1029 Real npvCash = cmsSpread1YCap.instrument()->NPV();
1030
1031 BOOST_TEST_MESSAGE("NPV Cash 1Y = " << npvCash);
1032 BOOST_CHECK_SMALL(npvCash - expectedNpv1Y, 0.000001);
1033
1034 npvCash = cmsSpread2YCap.instrument()->NPV();
1035
1036 BOOST_TEST_MESSAGE("NPV Cash 2Y = " << npvCash);
1037
1038 BOOST_CHECK_SMALL(npvCash - expectedNpv2Y, 0.000001);
1039}
Serializable object holding generic trade data, reporting dimensions.
Definition: envelope.hpp:51
Serializable object holding leg data.
Definition: legdata.hpp:844
Serializable schedule data.
Definition: schedule.hpp:202
Serializable object holding schedule Rules data.
Definition: schedule.hpp:37
Serializable Swap, Single and Cross Currency.
Definition: swap.hpp:36
Calendar calendar
Definition: utilities.cpp:441
std::string to_string(const LocationInfo &l)
Definition: ast.cpp:28
+ Here is the call graph for this function: