21#include <boost/test/unit_test.hpp>
22#include <ql/currencies/europe.hpp>
23#include <ql/experimental/callablebonds/callablebond.hpp>
24#include <ql/indexes/ibor/euribor.hpp>
25#include <ql/instruments/callabilityschedule.hpp>
26#include <ql/instruments/creditdefaultswap.hpp>
27#include <ql/math/optimization/levenbergmarquardt.hpp>
28#include <ql/math/randomnumbers/rngtraits.hpp>
29#include <ql/math/statistics/incrementalstatistics.hpp>
30#include <ql/methods/montecarlo/multipathgenerator.hpp>
31#include <ql/methods/montecarlo/pathgenerator.hpp>
32#include <ql/quotes/simplequote.hpp>
33#include <ql/termstructures/credit/flathazardrate.hpp>
34#include <ql/termstructures/yield/flatforward.hpp>
35#include <ql/time/calendars/target.hpp>
36#include <ql/time/daycounters/actual360.hpp>
37#include <ql/time/daycounters/actualactual.hpp>
38#include <ql/time/daycounters/thirty360.hpp>
39#include <ql/pricingengines/credit/midpointcdsengine.hpp>
50#include <boost/make_shared.hpp>
56#if BOOST_VERSION >= 106400
57#include <boost/serialization/array_wrapper.hpp>
59#include <boost/accumulators/accumulators.hpp>
60#include <boost/accumulators/statistics/covariance.hpp>
61#include <boost/accumulators/statistics/density.hpp>
62#include <boost/accumulators/statistics/error_of_mean.hpp>
63#include <boost/accumulators/statistics/mean.hpp>
64#include <boost/accumulators/statistics/stats.hpp>
65#include <boost/accumulators/statistics/variates/covariate.hpp>
66#include <boost/make_shared.hpp>
71using namespace boost::accumulators;
75 CreditModelTestData_flat()
76 : referenceDate(29, July, 2017), dts(
QuantLib::ext::make_shared<FlatHazardRate>(referenceDate, 0.04, ActualActual(ActualActual::ISDA))),
77 yts(
QuantLib::ext::make_shared<FlatForward>(referenceDate, 0.02, ActualActual(ActualActual::ISDA))) {
79 Settings::instance().evaluationDate() = referenceDate;
83 sigma =
sqrt(2 * kappa * theta) - 1E-10;
89 cirParametrization = QuantLib::ext::make_shared<CrCirppConstantWithFellerParametrization>(
90 EURCurrency(), dts, kappa, theta, sigma, y0, shifted);
91 QL_REQUIRE(cirParametrization != NULL,
"CrCirppConstantWithFellerParametrization has null pointer!");
93 model = QuantLib::ext::make_shared<CrCirpp>(cirParametrization);
94 BOOST_TEST_MESSAGE(
"CIR++ parameters: ");
95 BOOST_TEST_MESSAGE(
"Kappa: \t" << model->parametrization()->kappa(0));
96 BOOST_TEST_MESSAGE(
"Theta: \t" << model->parametrization()->theta(0));
97 BOOST_TEST_MESSAGE(
"Sigma: \t" << model->parametrization()->sigma(0));
98 BOOST_TEST_MESSAGE(
"y0: \t" << model->parametrization()->y0(0));
99 BOOST_TEST_MESSAGE(
"Feller condition is (>1 ok) "
100 << 2.0 * model->parametrization()->kappa(0) * model->parametrization()->theta(0) /
101 model->parametrization()->sigma(0) / model->parametrization()->sigma(0));
104 SavedSettings backup;
106 Handle<DefaultProbabilityTermStructure> dts;
107 Handle<YieldTermStructure> yts;
108 Real kappa, theta, sigma, y0;
111 QuantLib::ext::shared_ptr<CrCirppConstantWithFellerParametrization> cirParametrization;
112 QuantLib::ext::shared_ptr<CrCirpp> model;
116BOOST_FIXTURE_TEST_SUITE(QuantExtTestSuite, CreditModelTestData_flat)
118BOOST_AUTO_TEST_SUITE(CrCirppModelTest)
122 BOOST_TEST_MESSAGE(
"Testing martingale property in credit-CIR++ model for Brigo-Alfonsi discretizations...");
124 QuantLib::ext::shared_ptr<StochasticProcess> process = model->stateProcess();
125 QL_REQUIRE(process != NULL,
"process has null pointer!");
140 Size
steps =
static_cast<Size
>(T * 52);
142 TimeGrid grid(T,
steps);
146 accumulator_set<double, stats<tag::mean, tag::error_of<tag::mean>>> meanTest_y;
147 accumulator_set<double, stats<tag::variance, tag::error_of<tag::mean>>> varTest_y;
149 accumulator_set<double, stats<tag::mean, tag::error_of<tag::mean>>> sp;
150 accumulator_set<double, stats<tag::mean, tag::error_of<tag::mean>>> numeraire;
152 accumulator_set<double, stats<tag::density>> histXAcc(tag::density::cache_size = 10000,
153 tag::density::num_bins = 50);
162 for (Size j = 0; j < n; ++j) {
163 Sample<MultiPath> path = pg.
next();
164 Size l = path.value[0].length() - 1;
165 Real y = path.value[0][l];
166 Real num = path.value[1][l];
167 sp(model->survivalProbability(T, T2, y) * num);
205 BOOST_TEST_MESSAGE(
"\nBrigo-Alfonsi:");
210 BOOST_TEST_MESSAGE(
"SP = " << mean(sp) <<
" +- " << error_of<tag::mean>(sp) <<
" vs analytical "
211 << dts->survivalProbability(T2));
212 BOOST_TEST_MESSAGE(
"Num = " << mean(numeraire) <<
" +- " << error_of<tag::mean>(numeraire) <<
" vs analytical "
213 << dts->survivalProbability(T));
216 Real expectedSP = dts->survivalProbability(T);
217 Real expectedCondSP = dts->survivalProbability(T2);
218 if (std::abs(mean(numeraire) - expectedSP) > tol2)
219 BOOST_FAIL(
"Martingale test failed for SP(t) (Brigo-Alfonsi discr.), expected "
220 << expectedSP <<
", got " << mean(numeraire) <<
", tolerance " << tol2);
221 if (std::abs(mean(sp) - expectedCondSP) > tol2)
222 BOOST_FAIL(
"Martingale test failed for SP(t,T) (Brigo-Alfonsi discr.), expected "
223 << expectedCondSP <<
", got " << mean(sp) <<
", tolerance " << tol2);
228BOOST_AUTO_TEST_SUITE_END()
230BOOST_AUTO_TEST_SUITE_END()
CDS option, removed requirements (rec must knock out, no upfront amount), that should be taken care o...
cds option calibration helper
constant CIR ++ parametrization
Instantiation of MultiPathGenerator with standard PseudoRandom traits.
const Sample< MultiPath > & next() const override
CIR++ credit model class.
CIR++ model state process.
base class for multi path generators
RandomVariable sqrt(RandomVariable x)
std::vector< Size > steps
BOOST_AUTO_TEST_CASE(testMartingaleProperty)
Fixture that can be used at top level.
helper macros and methods for tests