20#include <boost/make_shared.hpp>
21#include <boost/test/unit_test.hpp>
23#include <ql/quotes/simplequote.hpp>
24#include <ql/time/calendars/weekendsonly.hpp>
25#include <ql/time/daycounters/actual365fixed.hpp>
30using namespace boost::unit_test_framework;
35BOOST_AUTO_TEST_SUITE(BaseCorrelationTests)
39 std::vector<double> detachmentPoints;
40 std::vector<Period> tenors;
44 : today(22, Sep, 2022), detachmentPoints({0.03, 0.07, 0.15, 1.0}), tenors({3 * Years, 5 * Years}),
45 startDate(20, Sep, 2021) {}
49 Settings::instance().evaluationDate() = cd.today;
54 std::vector<std::vector<double>> correlations{
55 {0.409223169, 0.405249307}, {0.507498351, 0.486937064}, {0.614741119, 0.623673691}, {1.0, 1.0}};
57 std::vector<std::vector<Handle<Quote>>> quotes;
58 for (
const auto& row : correlations) {
59 quotes.push_back(std::vector<Handle<Quote>>());
60 for (
const auto& correl : row) {
61 quotes.back().push_back(Handle<Quote>(QuantLib::ext::make_shared<SimpleQuote>(correl)));
66 0, WeekendsOnly(), ModifiedFollowing, cd.tenors, cd.detachmentPoints, quotes, Actual365Fixed(), cd.startDate,
67 DateGeneration::CDS2015));
78 BOOST_CHECK_EQUAL(curve->dates()[0], Date(20, Dec, 2024));
79 BOOST_CHECK_EQUAL(curve->dates()[1], Date(20, Dec, 2026));
82 BOOST_CHECK_CLOSE(curve->correlation(Date(20, Dec, 2026), 0.03), 0.405249307, 1e-10);
83 BOOST_CHECK_CLOSE(curve->correlation(Date(20, Dec, 2026), 0.07), 0.486937064, 1e-10);
85 BOOST_CHECK_CLOSE(curve->correlation(Date(20, Dec, 2026), 0.05), (0.405249307 + 0.486937064) / 2.0, 1e-10);
87 curve->disableExtrapolation();
88 BOOST_CHECK_THROW(curve->correlation(Date(20, Dec, 2026), 0.01), std::exception);
89 BOOST_CHECK_THROW(curve->correlation(Date(20, Dec, 2021), 0.03), std::exception);
90 curve->enableExtrapolation();
92 BOOST_CHECK_CLOSE(curve->correlation(Date(20, Dec, 2026), 0.01), 0.405249307, 1e-10);
93 BOOST_CHECK_CLOSE(curve->correlation(Date(20, Dec, 2028), 0.05), (0.405249307 + 0.486937064) / 2.0, 1e-10);
94 BOOST_CHECK_CLOSE(curve->correlation(Date(20, Dec, 2022), 0.05), (0.409223169 + 0.507498351) / 2.0, 1e-10);
107 std::vector<std::vector<Handle<Quote>>> shifts;
109 for (Size i = 0; i < cd.detachmentPoints.size(); ++i) {
110 shifts.push_back(std::vector<Handle<Quote>>());
111 for (Size j = 0; j < cd.tenors.size(); ++j) {
112 shifts[i].push_back(Handle<Quote>(QuantLib::ext::make_shared<SimpleQuote>(0.0)));
118 BOOST_CHECK_CLOSE(shiftedCurve.
correlation(Date(20, Dec, 2026), 0.03), 0.405249307, 1e-10);
119 BOOST_CHECK_CLOSE(shiftedCurve.
correlation(Date(20, Dec, 2026), 0.07), 0.486937064, 1e-10);
121 QuantLib::ext::dynamic_pointer_cast<SimpleQuote>(*shifts[0][1])->setValue(0.01);
123 BOOST_CHECK_CLOSE(shiftedCurve.
correlation(Date(20, Dec, 2026), 0.03), 0.415249307, 1e-10);
124 BOOST_CHECK_CLOSE(shiftedCurve.
correlation(Date(20, Dec, 2026), 0.07), 0.486937064, 1e-10);
126 BOOST_CHECK_CLOSE(shiftedCurve.
correlation(Date(20, Dec, 2026), 0.05), (0.415249307 + 0.486937064) / 2.0, 1e-10);
137 auto parallelShift = QuantLib::ext::make_shared<SimpleQuote>(0.0);
139 std::vector<std::vector<Handle<Quote>>> quotes{{Handle<Quote>(parallelShift)}};
141 std::vector<Period> terms{1 * Days};
142 std::vector<double> detachmentPoints{1.0};
144 Size nt = terms.size();
145 Size nd = detachmentPoints.size();
148 terms.push_back(terms[0] + 1 * Days);
149 for (Size i = 0; i < nd; ++i)
150 quotes[i].push_back(quotes[i][0]);
154 quotes.push_back(std::vector<Handle<Quote>>(terms.size()));
155 for (Size j = 0; j < terms.size(); ++j)
156 quotes[1][j] = quotes[0][j];
158 if (detachmentPoints[0] < 1.0 && !QuantLib::close_enough(detachmentPoints[0], 1.0)) {
159 detachmentPoints.push_back(1.0);
161 detachmentPoints.insert(detachmentPoints.begin(), 0.01);
167 BOOST_CHECK_CLOSE(shiftedCurveParallel.
correlation(Date(20, Dec, 2026), 0.03), 0.405249307, 1e-10);
168 BOOST_CHECK_CLOSE(shiftedCurveParallel.
correlation(Date(20, Dec, 2026), 0.07), 0.486937064, 1e-10);
170 parallelShift->setValue(0.01);
172 BOOST_CHECK_CLOSE(shiftedCurveParallel.
correlation(Date(20, Dec, 2026), 0.03), 0.415249307, 1e-10);
173 BOOST_CHECK_CLOSE(shiftedCurveParallel.
correlation(Date(20, Dec, 2026), 0.07), 0.496937064, 1e-10);
174 BOOST_CHECK_CLOSE(shiftedCurveParallel.
correlation(Date(20, Dec, 2026), 1.0), 1.0, 1e-10);
176 BOOST_CHECK_CLOSE(shiftedCurveParallel.
correlation(Date(20, Dec, 2026), 0.05), (0.415249307 + 0.496937064) / 2.0,
179 BOOST_CHECK_THROW(shiftedCurveParallel.
correlation(Date(20, Dec, 2026), 0.01), std::exception);
180 BOOST_CHECK_THROW(shiftedCurveParallel.
correlation(Date(20, Dec, 2028), 0.03), std::exception);
182 shiftedCurveParallel.enableExtrapolation();
183 BOOST_CHECK_THROW(shiftedCurveParallel.
correlation(Date(20, Dec, 2026), 0.01), std::exception);
184 BOOST_CHECK_THROW(shiftedCurveParallel.
correlation(Date(20, Dec, 2028), 0.03), std::exception);
187 shiftedCurveParallel.enableExtrapolation();
188 curve->enableExtrapolation();
189 BOOST_CHECK_NO_THROW(shiftedCurveParallel.
correlation(Date(20, Dec, 2026), 0.01));
190 BOOST_CHECK_NO_THROW(shiftedCurveParallel.
correlation(Date(20, Dec, 2028), 0.03));
193BOOST_AUTO_TEST_SUITE_END()
195BOOST_AUTO_TEST_SUITE_END()
void initializeSettings(CommonData &cd)
BOOST_AUTO_TEST_CASE(testBaseCorrelationCurve)
Handle< QuantExt::BaseCorrelationTermStructure > buildBilinearFlatBaseCorrelationCurve(CommonData &cd)
abstract base correlation structure and an 2d-interpolated base correlation structure
Real correlation(Time t, Real strike=Null< Real >(), bool extrapolate=false) const
Spreaded Base Correlation Curve.
Fixture that can be used at top level.