20#include <boost/test/unit_test.hpp>
26#include <boost/make_shared.hpp>
27#include <boost/math/distributions/chi_squared.hpp>
32using namespace boost::unit_test_framework;
36void test(
const Size dim,
const bool nonzeroDelta,
const bool nonzeroGamma,
const Size seedParam,
const Size seedMc,
39 BOOST_TEST_MESSAGE(
"################ Testing delta gamma VaR, dim=" << dim <<
", delta=" << nonzeroDelta
40 <<
", gamma=" << nonzeroGamma
41 <<
", paths=" << paths <<
"\n");
43 MersenneTwisterUniformRng mt(seedParam);
47 BOOST_TEST_MESSAGE(
"Generate transformation matrix L");
48 Matrix L(dim, dim, 0.0);
51 for (Size i = 0; i < dim; ++i) {
52 for (Size j = 0; j < dim; ++j) {
53 L[i][j] = mt.nextReal();
57 BOOST_TEST_MESSAGE(
"... done, determinant is " << det);
60 Matrix omega = transpose(L) * L;
68 BOOST_TEST_MESSAGE(
"Generate delta");
69 Array delta(dim, 0.0);
71 for (Size i = 0; i < dim; ++i) {
72 delta[i] = mt.nextReal() * 1000.0 - 500.0;
78 BOOST_TEST_MESSAGE(
"Generate gamma");
79 Matrix gamma(dim, dim, 0.0), shift(dim, dim, 0.0);
81 for (Size i = 0; i < dim; ++i) {
82 for (Size j = 0; j < i; ++j) {
83 gamma[i][j] = gamma[j][i] = mt.nextReal() * 1000.0;
85 gamma[i][i] = mt.nextReal() * 1000.0;
89 BOOST_TEST_MESSAGE(
"delta=" << delta);
90 if (gamma.rows() <= 20) {
91 BOOST_TEST_MESSAGE(
"\ngamma=\n" << gamma);
92 BOOST_TEST_MESSAGE(
"omega=\n" << omega);
94 BOOST_TEST_MESSAGE(
"\ngamma= too big to display (" << gamma.rows() <<
"x" << gamma.columns() <<
")");
95 BOOST_TEST_MESSAGE(
"omega= too big to display (" << omega.rows() <<
"x" << omega.columns() <<
")\n");
100 std::vector<Real> quantiles = {0.9, 0.95, 0.99, 0.999, 0.9999};
102 BOOST_TEST_MESSAGE(
"Run MC simulation...");
103 Matrix nullGamma(dim, dim, 0.0);
104 auto mc1All = deltaGammaVarMc<PseudoRandom>(omega, delta, nullGamma, quantiles, paths, seedMc);
105 auto mc2All = deltaGammaVarMc<PseudoRandom>(omega, delta, gamma, quantiles, paths, seedMc);
106 BOOST_TEST_MESSAGE(
"MC simulation Done.");
108 BOOST_TEST_MESSAGE(
" Quantile dVaR(MC) dgVaR(MC) dVaR(Mdl) dgVaR(CF) dgVaR(SD) "
109 "err(CF)% err(SD)%");
110 BOOST_TEST_MESSAGE(
"==============================================================================================="
111 "=================");
114 for (
auto const& q : quantiles) {
116 Real mc1 = mc1All[i];
117 Real mc2 = mc2All[i++];
119 Real dVar =
deltaVar(omega, delta, q);
122 Real errCf = (dgVarCf - mc2) / mc2 * 100.0;
123 Real errSd = (dgVarSd - mc2) / mc2 * 100.0;
125 BOOST_TEST_MESSAGE(std::right << std::setw(14) << q << std::setw(14) << mc1 << std::setw(14) << mc2
126 << std::setw(14) << dVar << std::setw(14) << dgVarCf << std::setw(14) << dgVarSd
127 << std::setw(14) << errCf << std::setw(14) << errSd);
129 BOOST_CHECK_CLOSE(dVar, mc1, 5.0);
130 BOOST_CHECK_CLOSE(dgVarCf, mc2, 15.0);
131 BOOST_CHECK_CLOSE(dgVarSd, mc2, 5.0);
134 BOOST_TEST_MESSAGE(
"==============================================================================================="
135 "===============\n\n");
142BOOST_AUTO_TEST_SUITE(DeltaGammaVarTest)
149 Size n = (Size)400000;
151 test(1,
true,
false, 42, 42, n);
152 test(1,
false,
true, 42, 42, n);
153 test(1,
true,
true, 42, 42, n);
155 test(2,
true,
false, 42, 42, n);
156 test(2,
false,
true, 42, 42, n);
157 test(2,
true,
true, 42, 42, n);
159 test(10,
true,
false, 42, 42, n);
160 test(10,
false,
true, 42, 42, n);
161 test(10,
true,
true, 42, 42, n);
164 test(100,
true,
false, 42, 42, n);
165 test(100,
false,
true, 42, 42, n);
166 test(100,
true,
true, 42, 42, n);
171 BOOST_TEST_MESSAGE(
"Testing delta gamma var for pl = -u^2, u standard normal...");
177 boost::math::chi_squared_distribution<Real> chisq(1.0);
179 Real gamma = -10000.0;
182 Matrix gamma_m(1, 1, gamma);
183 Matrix omega(1, 1, 1.0);
187 Real var_mc = deltaGammaVarMc<PseudoRandom>(omega, delta, gamma_m, p, 1000000, 142);
191 Real refVal = 0.5 * gamma * boost::math::quantile(chisq, 1.0 - p);
193 BOOST_TEST_MESSAGE(
"mc = " << var_mc);
194 BOOST_TEST_MESSAGE(
"cf = " << var_cf);
195 BOOST_TEST_MESSAGE(
"sd = " << var_sd);
196 BOOST_TEST_MESSAGE(
"ref = " << refVal);
199 BOOST_CHECK_SMALL(std::abs(-4707.882 - var_cf), 0.001);
201 BOOST_CHECK_SMALL(std::abs(refVal - var_sd), 0.5);
202 BOOST_CHECK_SMALL(std::abs(refVal - var_mc), 0.5);
207 BOOST_TEST_MESSAGE(
"Running regression test case 001...");
208 std::vector<double> d1{691.043, 8.62406, 9706.97, 0, 0};
209 std::vector<double> d2 = {-13.9605, 0, 0, 0, 0, 0, -0.174223, 0, 0, 0, 0, 0, -196.1,
210 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
211 std::vector<double> d3 = {96.3436, -0.828459, -6.59142, 0.583848, -0.0639266, -0.828459, 97.7309,
212 12.4906, -2.03511, -0.504752, -6.59142, 12.4906, 95.12, 0.800706,
213 0.443861, 0.583848, -2.03511, 0.800706, 2.71239, 0.288881, -0.0639266,
214 -0.504752, 0.443861, 0.288881, 1.42701};
215 Array delta(d1.begin(), d1.end());
216 Matrix gamma(5, 5, d2.begin(), d2.end());
217 Matrix omega(5, 5, d3.begin(), d3.end());
219 Real var_mc = deltaGammaVarMc<PseudoRandom>(omega, delta, gamma, 0.99, 1000000, 42);
220 BOOST_TEST_MESSAGE(
"sd = " << var);
221 BOOST_TEST_MESSAGE(
"mc = " << var_mc);
222 BOOST_CHECK_CLOSE(var, var_mc, 0.5);
227 BOOST_TEST_MESSAGE(
"Running regression test case 002...");
230 boost::math::chi_squared_distribution<Real> chisq(1.0);
233 Matrix gamma(1, 1, 1.0);
234 Matrix omega(1, 1, 1.0E6);
238 Real refVal = 0.5 * 1E6 * boost::math::quantile(chisq, p);
239 Real var_mc = deltaGammaVarMc<PseudoRandom>(omega, delta, gamma, p, 1000000, 42);
241 BOOST_TEST_MESSAGE(
"sd = " << var_sd);
242 BOOST_TEST_MESSAGE(
"mc = " << var_mc);
243 BOOST_TEST_MESSAGE(
"ref = " << refVal);
245 BOOST_CHECK_CLOSE(refVal, var_sd, 1.0);
250 BOOST_TEST_MESSAGE(
"Running regression test case 003...");
254 11.357910440165, 0.301883284121, 1.690565094559, 0.028921366715, 1.445952963717, 2.683104461304,
255 2.975281862097, 0.284778609491, 3.977509941411, 2.700492214606, 3.973616990595, 1.842042909216,
256 4.507630684591, 2.188574976899, 1.839870252197, 1.653581957759, 0.301883284121, 1.545170636908,
257 1.140841711137, 0.011046063984, 0.223680967726, 0.926416050189, 0.637660185458, 1.634591590508,
258 0.328944419108, -0.321306872147, 0.490226761216, -0.228872084003, -0.466954542255, 0.908486575719,
259 1.208420546045, 1.057641385035, 1.690565094559, 1.140841711137, 4.590122578368, 0.016138328046,
260 1.681703229533, 2.722501254257, 2.941664204785, 4.088913570167, 0.753207493946, 0.750845717386,
261 2.327852200648, -0.083383166375, 0.791187240585, 3.432410532424, 4.576488134589, 4.484608491882,
262 0.028921366715, 0.011046063984, 0.016138328046, 0.003321196784, -0.002052702116, 0.015027345216,
263 0.025225956444, 0.009488292952, 0.023036962659, 0.003752073385, 0.025786900243, 0.004902517590,
264 0.017973354395, 0.013380695889, 0.016450708955, 0.015793906816, 1.445952963717, 0.223680967726,
265 1.681703229533, -0.002052702116, 5.051235107717, 1.504449552996, 1.411232675828, -0.066709336186,
266 0.740371793190, 0.922017945905, 1.423545223509, 0.592880234568, 1.318219401490, 1.512119827471,
267 1.709049165903, 1.651695766740, 2.683104461304, 0.926416050189, 2.722501254257, 0.015027345216,
268 1.504449552996, 5.896840384423, 2.736094553275, 2.318419864064, 2.683772279561, 0.869866043995,
269 2.795123680474, 0.233284568353, 1.954971283941, 2.638478800353, 2.962854214006, 2.999498221322,
270 2.975281862097, 0.637660185458, 2.941664204785, 0.025225956444, 1.411232675828, 2.736094553275,
271 3.730376993077, 2.574152890379, 2.332889913708, 1.012628826625, 2.401055859072, 0.425908702537,
272 2.104222769101, 2.846640151863, 3.254007639538, 3.174532782066, 0.284778609491, 1.634591590508,
273 4.088913570167, 0.009488292952, -0.066709336186, 2.318419864064, 2.574152890379, 8.346545067056,
274 0.111146561779, 0.061442388170, 1.440123839301, -0.532880568392, -0.363306461515, 3.164184153356,
275 4.239774387395, 4.222873062980, 3.977509941411, 0.328944419108, 0.753207493946, 0.023036962659,
276 0.740371793190, 2.683772279561, 2.332889913708, 0.111146561779, 7.816500777128, 1.306158501267,
277 1.892772141649, 1.533232314993, 2.966214070512, 1.981467787886, 0.858479274405, 0.688098796909,
278 2.700492214606, -0.321306872147, 0.750845717386, 0.003752073385, 0.922017945905, 0.869866043995,
279 1.012628826625, 0.061442388170, 1.306158501267, 3.255129750500, 1.447265157820, 1.646805443131,
280 2.024131319493, 0.823110422895, 0.661139572160, 0.726470332699, 3.973616990595, 0.490226761216,
281 2.327852200648, 0.025786900243, 1.423545223509, 2.795123680474, 2.401055859072, 1.440123839301,
282 1.892772141649, 1.447265157820, 9.307941714908, 1.003272291798, 2.960270274699, 2.637484069448,
283 2.395034154720, 2.407859255045, 1.842042909216, -0.228872084003, -0.083383166375, 0.004902517590,
284 0.592880234568, 0.233284568353, 0.425908702537, -0.532880568392, 1.533232314993, 1.646805443131,
285 1.003272291798, 2.715163222630, 1.397890009325, 0.370386734188, -0.170205201951, -0.252456813317,
286 4.507630684591, -0.466954542255, 0.791187240585, 0.017973354395, 1.318219401490, 1.954971283941,
287 2.104222769101, -0.363306461515, 2.966214070512, 2.024131319493, 2.960270274699, 1.397890009325,
288 12.145104529503, 1.291504589690, 0.751431588477, 0.731038259921, 2.188574976899, 0.908486575719,
289 3.432410532424, 0.013380695889, 1.512119827471, 2.638478800353, 2.846640151863, 3.164184153356,
290 1.981467787886, 0.823110422895, 2.637484069448, 0.370386734188, 1.291504589690, 3.304040607934,
291 3.654236283615, 3.549318308813, 1.839870252197, 1.208420546045, 4.576488134589, 0.016450708955,
292 1.709049165903, 2.962854214006, 3.254007639538, 4.239774387395, 0.858479274405, 0.661139572160,
293 2.395034154720, -0.170205201951, 0.751431588477, 3.654236283615, 5.109964090288, 4.959183419230,
294 1.653581957759, 1.057641385035, 4.484608491882, 0.015793906816, 1.651695766740, 2.999498221322,
295 3.174532782066, 4.222873062980, 0.688098796909, 0.726470332699, 2.407859255045, -0.252456813317,
296 0.731038259921, 3.549318308813, 4.959183419230, 5.024852085655};
297 Matrix covar(16, 16, data.begin(), data.end());
300 Matrix gamma(16, 16, 0.0);
301 gamma[14][14] = -0.000000000262;
304 Array delta(16, 0.0);
305 delta[14] = -247189.692289613;
310 BOOST_TEST_MESSAGE(
"sdvar=" << sdvar);
313 Real mcvar = deltaGammaVarMc<PseudoRandom>(covar, delta, gamma, p, 1000000, 42);
314 BOOST_TEST_MESSAGE(
"mcvar=" << mcvar);
317 BOOST_CHECK_CLOSE(sdvar, mcvar, 1.0);
320BOOST_AUTO_TEST_SUITE_END()
322BOOST_AUTO_TEST_SUITE_END()
functions to compute delta or delta-gamma VaR numbers
Filter close_enough(const RandomVariable &x, const RandomVariable &y)
Real deltaGammaVarCornishFisher(const Matrix &omega, const Array &delta, const Matrix &gamma, const Real p, const CovarianceSalvage &sal)
Real deltaVar(const Matrix &omega, const Array &delta, const Real p, const CovarianceSalvage &sal)
function that computes a delta VaR
Real deltaGammaVarSaddlepoint(const Matrix &omega, const Array &delta, const Matrix &gamma, const Real p, const CovarianceSalvage &sal)
BOOST_AUTO_TEST_CASE(testDeltaGammaVar)
Fixture that can be used at top level.