1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3/*
4 Copyright (C) 2003 Ferdinando Ametrano
5 Copyright (C) 2003 RiskMap srl
6
7 This file is part of QuantLib, a free-software/open-source library
8 for financial quantitative analysts and developers - http://quantlib.org/
9
10 QuantLib is free software: you can redistribute it and/or modify it
11 under the terms of the QuantLib license. You should have received a
12 copy of the license along with this program; if not, please email
13 <quantlib-dev@lists.sf.net>. The license is also available online at
14 <http://quantlib.org/license.shtml>.
15
16 This program is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18 FOR A PARTICULAR PURPOSE. See the license for more details.
19*/
20
21#include "riskstats.hpp"
22#include "utilities.hpp"
23#include <ql/math/statistics/riskstatistics.hpp>
24#include <ql/math/statistics/incrementalstatistics.hpp>
25#include <ql/math/statistics/sequencestatistics.hpp>
26#include <ql/math/randomnumbers/sobolrsg.hpp>
27#include <ql/math/comparison.hpp>
28
29using namespace QuantLib;
30using namespace boost::unit_test_framework;
31
32void RiskStatisticsTest::testResults() {
33
34 BOOST_TEST_MESSAGE("Testing risk measures...");
35
36 GenericGaussianStatistics<IncrementalStatistics> igs;
37 RiskStatistics s;
38
39 Real averages[] = { -100.0, -1.0, 0.0, 1.0, 100.0 };
40 Real sigmas[] = { 0.1, 1.0, 100.0 };
41 Size i, j, k, N;
42 N = Size(std::pow(x: 2.0,y: 16))-1;
43 Real dataMin, dataMax;
44 std::vector<Real> data(N), weights(N);
45
46 for (i=0; i<LENGTH(averages); i++) {
47 for (j=0; j<LENGTH(sigmas); j++) {
48
49 NormalDistribution normal(averages[i],sigmas[j]);
50 CumulativeNormalDistribution cumulative(averages[i],sigmas[j]);
51 InverseCumulativeNormal inverseCum(averages[i],sigmas[j]);
52
53 SobolRsg rng(1);
54 dataMin = QL_MAX_REAL;
55 dataMax = QL_MIN_REAL;
56 for (k=0; k<N; k++) {
57 data[k] = inverseCum(rng.nextSequence().value[0]);
58 dataMin = std::min(a: dataMin, b: data[k]);
59 dataMax = std::max(a: dataMax, b: data[k]);
60 weights[k]=1.0;
61 }
62
63 igs.addSequence(begin: data.begin(),end: data.end(),wbegin: weights.begin());
64 s.addSequence(begin: data.begin(),end: data.end(),wbegin: weights.begin());
65
66 // checks
67 Real calculated, expected;
68 Real tolerance;
69
70 if (igs.samples() != N)
71 BOOST_FAIL("IncrementalGaussianStatistics: "
72 << "wrong number of samples\n"
73 << " calculated: " << igs.samples() << "\n"
74 << " expected: " << N);
75 if (s.samples() != N)
76 BOOST_FAIL("RiskStatistics: wrong number of samples\n"
77 << " calculated: " << s.samples() << "\n"
78 << " expected: " << N);
79
80
81 // weightSum()
82 tolerance = 1e-10;
83 expected = std::accumulate(first: weights.begin(),last: weights.end(),init: Real(0.0));
84 calculated = igs.weightSum();
85 if (std::fabs(x: calculated-expected) > tolerance)
86 BOOST_FAIL("IncrementalGaussianStatistics: "
87 << "wrong sum of weights\n"
88 << std::setprecision(16)
89 << " calculated: " << calculated << "\n"
90 << " expected: " << expected << "\n"
91 << " tolerance: " << tolerance);
92 calculated = s.weightSum();
93 if (std::fabs(x: calculated-expected) > tolerance)
94 BOOST_FAIL("RiskStatistics: wrong sum of weights\n"
95 << std::setprecision(16)
96 << " calculated: " << calculated << "\n"
97 << " expected: " << expected << "\n"
98 << " tolerance: " << tolerance);
99
100
101 // min
102 tolerance = 1e-12;
103 expected = dataMin;
104 calculated = igs.min();
105 if (std::fabs(x: calculated-expected)>tolerance)
106 BOOST_FAIL("IncrementalGaussianStatistics: "
107 << "wrong minimum value\n"
108 << std::setprecision(16)
109 << " calculated: " << calculated << "\n"
110 << " expected: " << expected << "\n"
111 << " tolerance: " << tolerance);
112 calculated = s.min();
113 if (std::fabs(x: calculated-expected)>tolerance)
114 BOOST_FAIL("RiskStatistics: "
115 << "wrong minimum value\n"
116 << std::setprecision(16)
117 << " calculated: " << calculated << "\n"
118 << " expected: " << expected << "\n"
119 << " tolerance: " << tolerance);
120
121
122 // max
123 expected = dataMax;
124 calculated = igs.max();
125 if (std::fabs(x: calculated-expected)>tolerance)
126 BOOST_FAIL("IncrementalGaussianStatistics: "
127 << "wrong maximum value\n"
128 << std::setprecision(16)
129 << " calculated: " << calculated << "\n"
130 << " expected: " << expected << "\n"
131 << " tolerance: " << tolerance);
132 calculated = s.max();
133 if (std::fabs(x: calculated-expected)>tolerance)
134 BOOST_FAIL("RiskStatistics: "
135 << "wrong maximum value\n"
136 << std::setprecision(16)
137 << " calculated: " << calculated << "\n"
138 << " expected: " << expected << "\n"
139 << " tolerance: " << tolerance);
140
141
142 // mean
143 expected = averages[i];
144 tolerance = (expected == 0.0 ? Real(1.0e-13) :
145 std::fabs(x: expected)*1.0e-13);
146 calculated = igs.mean();
147 if (std::fabs(x: calculated-expected) > tolerance)
148 BOOST_FAIL("IncrementalGaussianStatistics: "
149 << "wrong mean value"
150 << " for N(" << averages[i] << ", "
151 << sigmas[j] << ")\n"
152 << std::setprecision(16)
153 << " calculated: " << calculated << "\n"
154 << " expected: " << expected << "\n"
155 << " tolerance: " << tolerance);
156 calculated = s.mean();
157 if (std::fabs(x: calculated-expected) > tolerance)
158 BOOST_FAIL("RiskStatistics: wrong mean value"
159 << " for N(" << averages[i] << ", "
160 << sigmas[j] << ")\n"
161 << std::setprecision(16)
162 << " calculated: " << calculated << "\n"
163 << " expected: " << expected << "\n"
164 << " tolerance: " << tolerance);
165
166
167 // variance
168 expected = sigmas[j]*sigmas[j];
169 tolerance = expected*1.0e-1;
170 calculated = igs.variance();
171 if (std::fabs(x: calculated-expected) > tolerance)
172 BOOST_FAIL("IncrementalGaussianStatistics: "
173 << "wrong variance"
174 << " for N(" << averages[i] << ", "
175 << sigmas[j] << ")\n"
176 << std::setprecision(16)
177 << " calculated: " << calculated << "\n"
178 << " expected: " << expected << "\n"
179 << " tolerance: " << tolerance);
180 calculated = s.variance();
181 if (std::fabs(x: calculated-expected) > tolerance)
182 BOOST_FAIL("RiskStatistics: wrong variance"
183 << " for N(" << averages[i] << ", "
184 << sigmas[j] << ")\n"
185 << std::setprecision(16)
186 << " calculated: " << calculated << "\n"
187 << " expected: " << expected << "\n"
188 << " tolerance: " << tolerance);
189
190
191 // standardDeviation
192 expected = sigmas[j];
193 tolerance = expected*1.0e-1;
194 calculated = igs.standardDeviation();
195 if (std::fabs(x: calculated-expected) > tolerance)
196 BOOST_FAIL("IncrementalGaussianStatistics: "
197 << "wrong standard deviation"
198 << " for N(" << averages[i] << ", "
199 << sigmas[j] << ")\n"
200 << std::setprecision(16)
201 << " calculated: " << calculated << "\n"
202 << " expected: " << expected << "\n"
203 << " tolerance: " << tolerance);
204 calculated = s.standardDeviation();
205 if (std::fabs(x: calculated-expected) > tolerance)
206 BOOST_FAIL("RiskStatistics: wrong standard deviation"
207 << " for N(" << averages[i] << ", "
208 << sigmas[j] << ")\n"
209 << std::setprecision(16)
210 << " calculated: " << calculated << "\n"
211 << " expected: " << expected << "\n"
212 << " tolerance: " << tolerance);
213
214
215 // missing errorEstimate() test
216
217 // skewness
218 expected = 0.0;
219 tolerance = 1.0e-4;
220 calculated = igs.skewness();
221 if (std::fabs(x: calculated-expected) > tolerance)
222 BOOST_FAIL("IncrementalGaussianStatistics: "
223 << "wrong skewness"
224 << " for N(" << averages[i] << ", "
225 << sigmas[j] << ")\n"
226 << std::setprecision(16)
227 << " calculated: " << calculated << "\n"
228 << " expected: " << expected << "\n"
229 << " tolerance: " << tolerance);
230 calculated = s.skewness();
231 if (std::fabs(x: calculated-expected) > tolerance)
232 BOOST_FAIL("RiskStatistics: wrong skewness"
233 << " for N(" << averages[i] << ", "
234 << sigmas[j] << ")\n"
235 << std::setprecision(16)
236 << " calculated: " << calculated << "\n"
237 << " expected: " << expected << "\n"
238 << " tolerance: " << tolerance);
239
240
241 // kurtosis
242 expected = 0.0;
243 tolerance = 1.0e-1;
244 calculated = igs.kurtosis();
245 if (std::fabs(x: calculated-expected) > tolerance)
246 BOOST_FAIL("IncrementalGaussianStatistics: "
247 << "wrong kurtosis"
248 << " for N(" << averages[i] << ", "
249 << sigmas[j] << ")\n"
250 << std::setprecision(16)
251 << " calculated: " << calculated << "\n"
252 << " expected: " << expected << "\n"
253 << " tolerance: " << tolerance);
254 calculated = s.kurtosis();
255 if (std::fabs(x: calculated-expected) > tolerance)
256 BOOST_FAIL("RiskStatistics: wrong kurtosis"
257 << " for N(" << averages[i] << ", "
258 << sigmas[j] << ")\n"
259 << std::setprecision(16)
260 << " calculated: " << calculated << "\n"
261 << " expected: " << expected << "\n"
262 << " tolerance: " << tolerance);
263
264
265 // percentile
266 expected = averages[i];
267 tolerance = (expected == 0.0 ? Real(1.0e-3) :
268 std::fabs(x: expected*1.0e-3));
269 calculated = igs.gaussianPercentile(percentile: 0.5);
270 if (std::fabs(x: calculated-expected) > tolerance)
271 BOOST_FAIL("IncrementalGaussianStatistics: "
272 << "wrong Gaussian percentile"
273 << " for N(" << averages[i] << ", "
274 << sigmas[j] << ")\n"
275 << std::setprecision(16)
276 << " calculated: " << calculated << "\n"
277 << " expected: " << expected << "\n"
278 << " tolerance: " << tolerance);
279 calculated = s.gaussianPercentile(percentile: 0.5);
280 if (std::fabs(x: calculated-expected) > tolerance)
281 BOOST_FAIL("RiskStatistics: wrong Gaussian percentile"
282 << " for N(" << averages[i] << ", "
283 << sigmas[j] << ")\n"
284 << std::setprecision(16)
285 << " calculated: " << calculated << "\n"
286 << " expected: " << expected << "\n"
287 << " tolerance: " << tolerance);
288 calculated = s.percentile(y: 0.5);
289 if (std::fabs(x: calculated-expected) > tolerance)
290 BOOST_FAIL("RiskStatistics: wrong percentile"
291 << " for N(" << averages[i] << ", "
292 << sigmas[j] << ")\n"
293 << std::setprecision(16)
294 << " calculated: " << calculated << "\n"
295 << " expected: " << expected << "\n"
296 << " tolerance: " << tolerance);
297
298
299
300 // potential upside
301 Real upper_tail = averages[i]+2.0*sigmas[j],
302 lower_tail = averages[i]-2.0*sigmas[j];
303 Real twoSigma = cumulative(upper_tail);
304
305 expected = std::max<Real>(a: upper_tail,b: 0.0);
306 tolerance = (expected == 0.0 ? Real(1.0e-3) :
307 std::fabs(x: expected*1.0e-3));
308 calculated = igs.gaussianPotentialUpside(percentile: twoSigma);
309 if (std::fabs(x: calculated-expected) > tolerance)
310 BOOST_FAIL("IncrementalGaussianStatistics: "
311 << "wrong Gaussian potential upside"
312 << " for N(" << averages[i] << ", "
313 << sigmas[j] << ")\n"
314 << std::setprecision(16)
315 << " calculated: " << calculated << "\n"
316 << " expected: " << expected << "\n"
317 << " tolerance: " << tolerance);
318 calculated = s.gaussianPotentialUpside(percentile: twoSigma);
319 if (std::fabs(x: calculated-expected) > tolerance)
320 BOOST_FAIL("RiskStatistics: wrong Gaussian potential upside"
321 << " for N(" << averages[i] << ", "
322 << sigmas[j] << ")\n"
323 << std::setprecision(16)
324 << " calculated: " << calculated << "\n"
325 << " expected: " << expected << "\n"
326 << " tolerance: " << tolerance);
327 calculated = s.potentialUpside(centile: twoSigma);
328 if (std::fabs(x: calculated-expected) > tolerance)
329 BOOST_FAIL("RiskStatistics: wrong potential upside"
330 << " for N(" << averages[i] << ", "
331 << sigmas[j] << ")\n"
332 << std::setprecision(16)
333 << " calculated: " << calculated << "\n"
334 << " expected: " << expected << "\n"
335 << " tolerance: " << tolerance);
336
337
338 // just to check that GaussianStatistics<StatsHolder> does work
339 StatsHolder h(s.mean(), s.standardDeviation());
340 GenericGaussianStatistics<StatsHolder> test(h);
341 expected = s.gaussianPotentialUpside(percentile: twoSigma);
342 calculated = test.gaussianPotentialUpside(percentile: twoSigma);
343 if (!close(x: calculated,y: expected))
344 BOOST_FAIL("GenericGaussianStatistics<StatsHolder> fails"
345 << std::setprecision(16)
346 << "\n calculated: " << calculated
347 << "\n expected: " << expected);
348
349 // value-at-risk
350 expected = -std::min<Real>(a: lower_tail,b: 0.0);
351 tolerance = (expected == 0.0 ? Real(1.0e-3) :
352 std::fabs(x: expected*1.0e-3));
353 calculated = igs.gaussianValueAtRisk(percentile: twoSigma);
354 if (std::fabs(x: calculated-expected) > tolerance)
355 BOOST_FAIL("IncrementalGaussianStatistics: "
356 << "wrong Gaussian value-at-risk"
357 << " for N(" << averages[i] << ", "
358 << sigmas[j] << ")\n"
359 << std::setprecision(16)
360 << " calculated: " << calculated << "\n"
361 << " expected: " << expected << "\n"
362 << " tolerance: " << tolerance);
363 calculated = s.gaussianValueAtRisk(percentile: twoSigma);
364 if (std::fabs(x: calculated-expected) > tolerance)
365 BOOST_FAIL("RiskStatistics: wrong Gaussian value-at-risk"
366 << " for N(" << averages[i] << ", "
367 << sigmas[j] << ")\n"
368 << std::setprecision(16)
369 << " calculated: " << calculated << "\n"
370 << " expected: " << expected << "\n"
371 << " tolerance: " << tolerance);
372 calculated = s.valueAtRisk(centile: twoSigma);
373 if (std::fabs(x: calculated-expected) > tolerance)
374 BOOST_FAIL("RiskStatistics: wrong value-at-risk"
375 << " for N(" << averages[i] << ", "
376 << sigmas[j] << ")\n"
377 << std::setprecision(16)
378 << " calculated: " << calculated << "\n"
379 << " expected: " << expected << "\n"
380 << " tolerance: " << tolerance);
381
382 if (averages[i] > 0.0 && sigmas[j] < averages[i]) {
383 // no data will miss the targets:
384 // skip the rest of this iteration
385 igs.reset();
386 s.reset();
387 continue;
388 }
389
390
391 // expected shortfall
392 expected = -std::min<Real>(a: averages[i]
393 - sigmas[j]*sigmas[j]
394 * normal(lower_tail)/(1.0-twoSigma),
395 b: 0.0);
396 tolerance = (expected == 0.0 ? Real(1.0e-4)
397 : std::fabs(x: expected)*1.0e-2);
398 calculated = igs.gaussianExpectedShortfall(percentile: twoSigma);
399 if (std::fabs(x: calculated-expected) > tolerance)
400 BOOST_FAIL("IncrementalGaussianStatistics: "
401 << "wrong Gaussian expected shortfall"
402 << " for N(" << averages[i] << ", "
403 << sigmas[j] << ")\n"
404 << std::setprecision(16)
405 << " calculated: " << calculated << "\n"
406 << " expected: " << expected << "\n"
407 << " tolerance: " << tolerance);
408 calculated = s.gaussianExpectedShortfall(percentile: twoSigma);
409 if (std::fabs(x: calculated-expected) > tolerance)
410 BOOST_FAIL("RiskStatistics: wrong Gaussian expected shortfall"
411 << " for N(" << averages[i] << ", "
412 << sigmas[j] << ")\n"
413 << std::setprecision(16)
414 << " calculated: " << calculated << "\n"
415 << " expected: " << expected << "\n"
416 << " tolerance: " << tolerance);
417 calculated = s.expectedShortfall(centile: twoSigma);
418 if (std::fabs(x: calculated-expected) > tolerance)
419 BOOST_FAIL("RiskStatistics: wrong expected shortfall"
420 << " for N(" << averages[i] << ", "
421 << sigmas[j] << ")\n"
422 << std::setprecision(16)
423 << " calculated: " << calculated << "\n"
424 << " expected: " << expected << "\n"
425 << " tolerance: " << tolerance);
426
427
428 // shortfall
429 expected = 0.5;
430 tolerance = (expected == 0.0 ? Real(1.0e-3) :
431 std::fabs(x: expected*1.0e-3));
432 calculated = igs.gaussianShortfall(target: averages[i]);
433 if (std::fabs(x: calculated-expected) > tolerance)
434 BOOST_FAIL("IncrementalGaussianStatistics: "
435 << "wrong Gaussian shortfall"
436 << " for N(" << averages[i] << ", "
437 << sigmas[j] << ")\n"
438 << std::setprecision(16)
439 << " calculated: " << calculated << "\n"
440 << " expected: " << expected << "\n"
441 << " tolerance: " << tolerance);
442 calculated = s.gaussianShortfall(target: averages[i]);
443 if (std::fabs(x: calculated-expected) > tolerance)
444 BOOST_FAIL("RiskStatistics: wrong Gaussian shortfall"
445 << " for N(" << averages[i] << ", "
446 << sigmas[j] << ")\n"
447 << std::setprecision(16)
448 << " calculated: " << calculated << "\n"
449 << " expected: " << expected << "\n"
450 << " tolerance: " << tolerance);
451 calculated = s.shortfall(target: averages[i]);
452 if (std::fabs(x: calculated-expected) > tolerance)
453 BOOST_FAIL("RiskStatistics: wrong shortfall"
454 << " for N(" << averages[i] << ", "
455 << sigmas[j] << ")\n"
456 << std::setprecision(16)
457 << " calculated: " << calculated << "\n"
458 << " expected: " << expected << "\n"
459 << " tolerance: " << tolerance);
460
461
462 // average shortfall
463 expected = sigmas[j]/std::sqrt(x: 2.0*M_PI)*2.0;
464 tolerance = expected*1.0e-3;
465 calculated = igs.gaussianAverageShortfall(target: averages[i]);
466 if (std::fabs(x: calculated-expected) > tolerance)
467 BOOST_FAIL("IncrementalGaussianStatistics: "
468 << "wrong Gaussian average shortfall"
469 << " for N(" << averages[i] << ", "
470 << sigmas[j] << ")\n"
471 << std::setprecision(16)
472 << " calculated: " << calculated << "\n"
473 << " expected: " << expected << "\n"
474 << " tolerance: " << tolerance);
475 calculated = s.gaussianAverageShortfall(target: averages[i]);
476 if (std::fabs(x: calculated-expected) > tolerance)
477 BOOST_FAIL("RiskStatistics: wrong Gaussian average shortfall"
478 << " for N(" << averages[i] << ", "
479 << sigmas[j] << ")\n"
480 << std::setprecision(16)
481 << " calculated: " << calculated << "\n"
482 << " expected: " << expected << "\n"
483 << " tolerance: " << tolerance);
484 calculated = s.averageShortfall(target: averages[i]);
485 if (std::fabs(x: calculated-expected) > tolerance)
486 BOOST_FAIL("RiskStatistics: wrong average shortfall"
487 << " for N(" << averages[i] << ", "
488 << sigmas[j] << ")\n"
489 << std::setprecision(16)
490 << " calculated: " << calculated << "\n"
491 << " expected: " << expected << "\n"
492 << " tolerance: " << tolerance);
493
494
495 // regret
496 expected = sigmas[j]*sigmas[j];
497 tolerance = expected*1.0e-1;
498 calculated = igs.gaussianRegret(target: averages[i]);
499 if (std::fabs(x: calculated-expected) > tolerance)
500 BOOST_FAIL("IncrementalGaussianStatistics: "
501 << "wrong Gaussian regret(" << averages[i] << ") "
502 << "for N(" << averages[i] << ", "
503 << sigmas[j] << ")\n"
504 << std::setprecision(16)
505 << " calculated: " << calculated << "\n"
506 << " expected: " << expected << "\n"
507 << " tolerance: " << tolerance);
508 calculated = s.gaussianRegret(target: averages[i]);
509 if (std::fabs(x: calculated-expected) > tolerance)
510 BOOST_FAIL("RiskStatistics: "
511 << "wrong Gaussian regret(" << averages[i] << ") "
512 << "for N(" << averages[i] << ", "
513 << sigmas[j] << ")\n"
514 << std::setprecision(16)
515 << " calculated: " << calculated << "\n"
516 << " expected: " << expected << "\n"
517 << " tolerance: " << tolerance);
518 calculated = s.regret(target: averages[i]);
519 if (std::fabs(x: calculated-expected) > tolerance)
520 BOOST_FAIL("RiskStatistics: "
521 << "wrong regret(" << averages[i] << ") "
522 << "for N(" << averages[i] << ", "
523 << sigmas[j] << ")\n"
524 << std::setprecision(16)
525 << " calculated: " << calculated << "\n"
526 << " expected: " << expected << "\n"
527 << " tolerance: " << tolerance);
528
529
530 // downsideVariance
531 expected = s.downsideVariance();
532 tolerance = (expected == 0.0 ? Real(1.0e-3) :
533 std::fabs(x: expected*1.0e-3));
534 calculated = igs.downsideVariance();
535 if (std::fabs(x: calculated-expected) > tolerance)
536 BOOST_FAIL("IncrementalGaussianStatistics: "
537 << "wrong downside variance"
538 << "for N(" << averages[i] << ", "
539 << sigmas[j] << ")\n"
540 << std::setprecision(16)
541 << " calculated: " << calculated << "\n"
542 << " expected: " << expected << "\n"
543 << " tolerance: " << tolerance);
544 calculated = igs.gaussianDownsideVariance();
545 if (std::fabs(x: calculated-expected) > tolerance)
546 BOOST_FAIL("IncrementalGaussianStatistics: "
547 << "wrong Gaussian downside variance"
548 << "for N(" << averages[i] << ", "
549 << sigmas[j] << ")\n"
550 << std::setprecision(16)
551 << " calculated: " << calculated << "\n"
552 << " expected: " << expected << "\n"
553 << " tolerance: " << tolerance);
554
555 // downsideVariance
556 if (averages[i]==0.0) {
557 expected = sigmas[j]*sigmas[j];
558 tolerance = expected*1.0e-3;
559 calculated = igs.downsideVariance();
560 if (std::fabs(x: calculated-expected) > tolerance)
561 BOOST_FAIL("IncrementalGaussianStatistics: "
562 << "wrong downside variance"
563 << "for N(" << averages[i] << ", "
564 << sigmas[j] << ")\n"
565 << std::setprecision(16)
566 << " calculated: " << calculated << "\n"
567 << " expected: " << expected << "\n"
568 << " tolerance: " << tolerance);
569 calculated = igs.gaussianDownsideVariance();
570 if (std::fabs(x: calculated-expected) > tolerance)
571 BOOST_FAIL("IncrementalGaussianStatistics: "
572 << "wrong Gaussian downside variance"
573 << "for N(" << averages[i] << ", "
574 << sigmas[j] << ")\n"
575 << std::setprecision(16)
576 << " calculated: " << calculated << "\n"
577 << " expected: " << expected << "\n"
578 << " tolerance: " << tolerance);
579 calculated = s.downsideVariance();
580 if (std::fabs(x: calculated-expected) > tolerance)
581 BOOST_FAIL("RiskStatistics: wrong downside variance"
582 << "for N(" << averages[i] << ", "
583 << sigmas[j] << ")\n"
584 << std::setprecision(16)
585 << " calculated: " << calculated << "\n"
586 << " expected: " << expected << "\n"
587 << " tolerance: " << tolerance);
588 calculated = s.gaussianDownsideVariance();
589 if (std::fabs(x: calculated-expected) > tolerance)
590 BOOST_FAIL("RiskStatistics: wrong Gaussian downside variance"
591 << "for N(" << averages[i] << ", "
592 << sigmas[j] << ")\n"
593 << std::setprecision(16)
594 << " calculated: " << calculated << "\n"
595 << " expected: " << expected << "\n"
596 << " tolerance: " << tolerance);
597 }
598
599 igs.reset();
600 s.reset();
601
602 }
603 }
604}
605
606
607test_suite* RiskStatisticsTest::suite() {
608 auto* suite = BOOST_TEST_SUITE("Risk statistics tests");
609 suite->add(QUANTLIB_TEST_CASE(&RiskStatisticsTest::testResults));
610 return suite;
611}
612
613

source code of quantlib/test-suite/riskstats.cpp