@@ -280,59 +280,32 @@ QuantLib::Real SimmConfigurationBase::correlation(const RiskType& firstRt, const
280
280
return 1.0 ;
281
281
}
282
282
283
- // Deal with case of different risk types
284
- if ((firstRt != secondRt) && (firstQualifier == secondQualifier)) {
285
- if (((firstRt == RiskType::IRCurve || firstRt == RiskType::Inflation) && secondRt == RiskType::XCcyBasis) ||
286
- (firstRt == RiskType::XCcyBasis && (secondRt == RiskType::IRCurve || secondRt == RiskType::Inflation))) {
287
- // Between xccy basis and any yield or inflation in same currency
288
- return xccyCorr_;
289
- }
290
- if ((firstRt == RiskType::IRCurve && secondRt == RiskType::Inflation) ||
291
- (firstRt == RiskType::Inflation && secondRt == RiskType::IRCurve)) {
292
- // Between any yield and inflation in same currency
293
- return infCorr_;
294
- }
295
- if ((firstRt == RiskType::IRVol && secondRt == RiskType::InflationVol) ||
296
- (firstRt == RiskType::InflationVol && secondRt == RiskType::IRVol)) {
297
- // Between any yield volatility and inflation volatility in same currency
298
- return infVolCorr_;
299
- }
300
- }
283
+ // Deal with Equity correlations
284
+ if ((firstRt == RiskType::Equity && secondRt == RiskType::Equity) ||
285
+ (firstRt == RiskType::EquityVol && secondRt == RiskType::EquityVol)) {
301
286
302
- // Deal with IRCurve and IRVol correlations
303
- if ((firstRt == RiskType::IRCurve && secondRt == RiskType::IRCurve) ||
304
- (firstRt == RiskType::IRVol && secondRt == RiskType::IRVol)) {
287
+ // Get the bucket of each qualifier
288
+ string bucket_1 = simmBucketMapper_-> bucket (firstRt, firstQualifier);
289
+ string bucket_2 = simmBucketMapper_-> bucket ( secondRt, secondQualifier);
305
290
306
- // If the qualifiers, i.e. currencies, are the same
307
- if (firstQualifier == secondQualifier) {
308
- // Label2 level, i.e. sub-curve, correlations
309
- if (firstLabel_2 != secondLabel_2) {
310
- QL_REQUIRE (
311
- firstLabel_1 == " " && secondLabel_1 == " " ,
312
- " When asking for Label2 level correlations, "
313
- << " the Label1 level values should both contain the default parameter i.e. empty string" );
314
- QL_REQUIRE (firstRt != RiskType::IRVol, " There is no correlation at the Label2 level for Risk_IRVol" );
315
- return irSubCurveCorr_;
316
- }
291
+ // Residual is special, 0 correlation inter and intra except if same qualifier
292
+ if (bucket_1 == " Residual" || bucket_2 == " Residual" ) {
293
+ return firstQualifier == secondQualifier ? 1.0 : 0.0 ;
294
+ }
317
295
318
- // Label1 level, i.e. tenor, correlations
319
- RiskType rt = RiskType::IRCurve;
320
- auto label12Key = makeKey (" " , firstLabel_1, secondLabel_1);
321
- if (intraBucketCorrelation_.at (rt).find (label12Key) != intraBucketCorrelation_.at (rt).end ())
322
- return intraBucketCorrelation_.at (rt).at (label12Key);
323
- else
324
- QL_FAIL (" Could not find correlation for risk type " << rt << " and key " << label12Key);
296
+ // Non-residual
297
+ // Get the bucket index of each qualifier
298
+ if (bucket_1 == bucket_2) {
299
+ auto bucketKey = makeKey (bucket_1, " " , " " );
300
+ // If same bucket, return the intra-bucket correlation
301
+ return firstQualifier == secondQualifier ? 1.0 : intraBucketCorrelation_.at (RiskType::Equity).at (bucketKey);
325
302
} else {
326
- // If the qualifiers, i.e. currencies, are not the same
327
- return irInterCurrencyCorr_;
303
+ // If different buckets, return the inter-bucket correlation
304
+ auto label12Key = makeKey (" " , bucket_1, bucket_2);
305
+ return interBucketCorrelation_.at (RiskType::Equity).at (label12Key);
328
306
}
329
307
}
330
308
331
- // Deal with inflation volatility correlations
332
- if (firstRt == RiskType::InflationVol && secondRt == RiskType::InflationVol) {
333
- return 1.0 ;
334
- }
335
-
336
309
// Deal with CreditQ correlations
337
310
if ((firstRt == RiskType::CreditQ && secondRt == RiskType::CreditQ) ||
338
311
(firstRt == RiskType::CreditVol && secondRt == RiskType::CreditVol)) {
@@ -413,32 +386,6 @@ QuantLib::Real SimmConfigurationBase::correlation(const RiskType& firstRt, const
413
386
}
414
387
}
415
388
416
- // Deal with Equity correlations
417
- if ((firstRt == RiskType::Equity && secondRt == RiskType::Equity) ||
418
- (firstRt == RiskType::EquityVol && secondRt == RiskType::EquityVol)) {
419
-
420
- // Get the bucket of each qualifier
421
- string bucket_1 = simmBucketMapper_->bucket (firstRt, firstQualifier);
422
- string bucket_2 = simmBucketMapper_->bucket (secondRt, secondQualifier);
423
-
424
- // Residual is special, 0 correlation inter and intra except if same qualifier
425
- if (bucket_1 == " Residual" || bucket_2 == " Residual" ) {
426
- return firstQualifier == secondQualifier ? 1.0 : 0.0 ;
427
- }
428
-
429
- // Non-residual
430
- // Get the bucket index of each qualifier
431
- if (bucket_1 == bucket_2) {
432
- auto bucketKey = makeKey (bucket_1, " " , " " );
433
- // If same bucket, return the intra-bucket correlation
434
- return firstQualifier == secondQualifier ? 1.0 : intraBucketCorrelation_.at (RiskType::Equity).at (bucketKey);
435
- } else {
436
- // If different buckets, return the inter-bucket correlation
437
- auto label12Key = makeKey (" " , bucket_1, bucket_2);
438
- return interBucketCorrelation_.at (RiskType::Equity).at (label12Key);
439
- }
440
- }
441
-
442
389
// Deal with Commodity correlations
443
390
if ((firstRt == RiskType::Commodity && secondRt == RiskType::Commodity) ||
444
391
(firstRt == RiskType::CommodityVol && secondRt == RiskType::CommodityVol)) {
@@ -458,6 +405,59 @@ QuantLib::Real SimmConfigurationBase::correlation(const RiskType& firstRt, const
458
405
}
459
406
}
460
407
408
+ // Deal with case of different risk types
409
+ if ((firstRt != secondRt) && (firstQualifier == secondQualifier)) {
410
+ if (((firstRt == RiskType::IRCurve || firstRt == RiskType::Inflation) && secondRt == RiskType::XCcyBasis) ||
411
+ (firstRt == RiskType::XCcyBasis && (secondRt == RiskType::IRCurve || secondRt == RiskType::Inflation))) {
412
+ // Between xccy basis and any yield or inflation in same currency
413
+ return xccyCorr_;
414
+ }
415
+ if ((firstRt == RiskType::IRCurve && secondRt == RiskType::Inflation) ||
416
+ (firstRt == RiskType::Inflation && secondRt == RiskType::IRCurve)) {
417
+ // Between any yield and inflation in same currency
418
+ return infCorr_;
419
+ }
420
+ if ((firstRt == RiskType::IRVol && secondRt == RiskType::InflationVol) ||
421
+ (firstRt == RiskType::InflationVol && secondRt == RiskType::IRVol)) {
422
+ // Between any yield volatility and inflation volatility in same currency
423
+ return infVolCorr_;
424
+ }
425
+ }
426
+
427
+ // Deal with IRCurve and IRVol correlations
428
+ if ((firstRt == RiskType::IRCurve && secondRt == RiskType::IRCurve) ||
429
+ (firstRt == RiskType::IRVol && secondRt == RiskType::IRVol)) {
430
+
431
+ // If the qualifiers, i.e. currencies, are the same
432
+ if (firstQualifier == secondQualifier) {
433
+ // Label2 level, i.e. sub-curve, correlations
434
+ if (firstLabel_2 != secondLabel_2) {
435
+ QL_REQUIRE (
436
+ firstLabel_1 == " " && secondLabel_1 == " " ,
437
+ " When asking for Label2 level correlations, "
438
+ << " the Label1 level values should both contain the default parameter i.e. empty string" );
439
+ QL_REQUIRE (firstRt != RiskType::IRVol, " There is no correlation at the Label2 level for Risk_IRVol" );
440
+ return irSubCurveCorr_;
441
+ }
442
+
443
+ // Label1 level, i.e. tenor, correlations
444
+ RiskType rt = RiskType::IRCurve;
445
+ auto label12Key = makeKey (" " , firstLabel_1, secondLabel_1);
446
+ if (intraBucketCorrelation_.at (rt).find (label12Key) != intraBucketCorrelation_.at (rt).end ())
447
+ return intraBucketCorrelation_.at (rt).at (label12Key);
448
+ else
449
+ QL_FAIL (" Could not find correlation for risk type " << rt << " and key " << label12Key);
450
+ } else {
451
+ // If the qualifiers, i.e. currencies, are not the same
452
+ return irInterCurrencyCorr_;
453
+ }
454
+ }
455
+
456
+ // Deal with inflation volatility correlations
457
+ if (firstRt == RiskType::InflationVol && secondRt == RiskType::InflationVol) {
458
+ return 1.0 ;
459
+ }
460
+
461
461
// Deal with FX correlations
462
462
// TODO:
463
463
// For FXVol, qualifier is a currency pair. Is it possible to get here
0 commit comments