Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
quadraticinterpolation.cpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2021 Skandinaviska Enskilda Banken AB (publ)
3 All rights reserved.
4
5 This file is part of ORE, a free-software/open-source library
6 for transparent pricing and risk analysis - http://opensourcerisk.org
7 ORE is free software: you can redistribute it and/or modify it
8 under the terms of the Modified BSD License. You should have received a
9 copy of the license along with this program.
10 The license is also available online at <http://opensourcerisk.org>
11 This program is distributed on the basis that it will form a useful
12 contribution to risk analytics and model standardisation, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the license for more details.
15 */
16
17 #include "toplevelfixture.hpp"
18 #include <boost/test/unit_test.hpp>
19 #include <ql/termstructures/yield/discountcurve.hpp>
21
22 #include <boost/make_shared.hpp>
23
24 using namespace boost::unit_test_framework;
25 using namespace QuantExt;
26 using namespace QuantLib;
27
28 BOOST_FIXTURE_TEST_SUITE(QuantExtTestSuite, qle::test::TopLevelFixture)
29
30 BOOST_AUTO_TEST_SUITE(QuadraticInterpolationTest)
31
32 BOOST_AUTO_TEST_CASE(testQuadraticInterpolation) {
33
34 BOOST_TEST_MESSAGE("Testing QuantExt Log-/QuadraticInterpolation");
35
36 std::vector<Time> t = { 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0 };
37 std::vector<Real> l = {
38 0.00747391, 0.00755479, 0.0185543, 0.0228824, 0.0237791,
39 0.0252718, 0.0338208, 0.0391517, 0.0395441, 0.0495399
40 };
41
42 std::vector<Real> expected_lambda = {
43 0.103514, // lambda_0
44 59.2299, -82.6916, 56.1263, -16.8334, 15.9315,
45 -32.2953, 12.8415, 32.2534, -44.2813,
46 16.9836 // lambda_N
47 };
48
49 std::vector<DiscountFactor> dfs(l.size(), 0.0);
50 for (Size i = 0; i < l.size(); ++i) {
51 dfs[i] = std::exp(-l[i]);
52 }
53 LogQuadraticInterpolation q(t.begin(), t.end(), dfs.begin(), 1, 0, -1, 0);
54
55 BOOST_TEST_MESSAGE("Interpolation should be exact at pillars");
56 for (Size i = 0; i < l.size(); ++i) {
57 BOOST_CHECK_CLOSE(q(t[i]), dfs[i], 0.0001);
58 }
59
60 BOOST_TEST_MESSAGE("Test calculated lambdas against cached values");
61 std::vector<Real> calculated_lambdas = q.lambdas<
62 std::vector<QuantLib::Real>::iterator,
63 std::vector<QuantLib::Real>::iterator>();
64 for (Size i = 0; i < calculated_lambdas.size(); ++i) {
65 BOOST_CHECK_CLOSE(calculated_lambdas[i], expected_lambda[i], 0.01);
66 }
67
68 BOOST_TEST_MESSAGE("Test lambdas consistency");
69 Real expected_lambda_N = 0;
70 for (Size i = 1; i < calculated_lambdas.size() - 1; ++i) {
71 expected_lambda_N += -calculated_lambdas[i] * t[i - 1] / t.back();
72 }
73 BOOST_CHECK_CLOSE(expected_lambda_N, expected_lambda.back(), 0.1);
74
75 BOOST_TEST_MESSAGE("Test interpolated values against cached values");
76 std::vector<Real> expected_df = {
77 0.992554, 0.992500, 0.992798, 0.993115, 0.993118,
78 0.992474, 0.990959, 0.988792, 0.986298, 0.983799,
79 0.981617, 0.979994, 0.978880, 0.978154, 0.977693,
80 0.977377, 0.977108, 0.976875, 0.976689, 0.976560,
81 0.976501, 0.976502, 0.976470, 0.976292, 0.975854,
82 0.975045, 0.973794, 0.972198, 0.970399, 0.968535,
83 0.966745, 0.965148, 0.963798, 0.962733, 0.961989,
84 0.961605, 0.961576, 0.961734, 0.961868, 0.961770,
85 0.961228, 0.960090, 0.958433, 0.956389, 0.954090,
86 0.951667
87 };
88
89 Time j = t.front();
90 for (Size i = 0; i < expected_df.size(); ++i) {
91 BOOST_CHECK_CLOSE(q(j), expected_df[i], 1e-4);
92 j += 0.02;
93 }
94
95 }
96
97 BOOST_AUTO_TEST_CASE(testInterpolatedDiscountCurve) {
98
99 BOOST_TEST_MESSAGE("Testing QuantExt "
100 "InterpolatedDiscountCurve<LogQuadratic>");
101
102 SavedSettings backup;
103 Settings::instance().evaluationDate() = Date(8, Dec, 2016);
104 Date today = Settings::instance().evaluationDate();
105
106 std::vector<Date> dates = {
107 Date(8, Dec, 2016), Date(8, Jun, 2017),
108 Date(8, Dec, 2017), Date(8, Dec, 2018)
109 };
110 std::vector<DiscountFactor> dfs = { 1.00, 0.99, 0.95, 0.97 };
111 std::vector<Real> params = { 1, 0.01, -1, 0.01 };
112
114 Actual365Fixed(), LogQuadratic(params[0], params[1],
115 params[2], params[3]));
116
117 std::vector<Time> times(dates.size());
118 for(Size i = 0; i < dates.size(); ++i)
119 times[i] = Actual365Fixed().yearFraction(today, dates[i]);
120 LogQuadraticInterpolation q(times.begin(), times.end(), dfs.begin(),
121 params[0], params[1], params[2], params[3]);
122
123 BOOST_TEST_MESSAGE("Interpolation should be exact at pillars");
124 for (Size i = 0; i < dfs.size(); ++i) {
125 BOOST_CHECK_CLOSE(curve.discount(dates[i]), dfs[i], 0.0000001);
126 BOOST_CHECK_CLOSE(curve.discount(times[i]), dfs[i], 0.0000001);
127 }
128
129 BOOST_TEST_MESSAGE("Test lambdas consistency between "
130 "InterpolatedDiscountCurve<LogQuadratic> "
131 "and LogQuadraticInterpolation");
132 for (Time i = 0; i < times.back(); i += 0.01) {
133 BOOST_CHECK_CLOSE(q(i, true), curve.discount(i, true), 0.0001);
134 }
135 }
136 BOOST_AUTO_TEST_SUITE_END()
137
138 BOOST_AUTO_TEST_SUITE_END()
InterpolatedDiscountCurve based on loglinear interpolation of DiscountFactors.
log-quadratic interpolation factory and traits
log-quadratic interpolation between discrete points
log-quadratic interpolation between discrete points
BOOST_AUTO_TEST_CASE(testQuadraticInterpolation)
Fixture that can be used at top level.