Skip to content

Commit de78c0b

Browse files
pcaspersjenkins
authored andcommitted
QPR-12325 use parametric vol config to build swaption and cap floor sabr surfaces
1 parent ebd405d commit de78c0b

8 files changed

Lines changed: 142 additions & 43 deletions

OREData/ored/configuration/capfloorvolcurveconfig.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,14 +58,16 @@ CapFloorVolatilityCurveConfig::CapFloorVolatilityCurveConfig(
5858
const BusinessDayConvention& businessDayConvention, const std::string& index,
5959
const QuantLib::Period& rateComputationPeriod, const Size onCapSettlementDays, const string& discountCurve,
6060
const string& interpolationMethod, const string& interpolateOn, const string& timeInterpolation,
61-
const string& strikeInterpolation, const vector<string>& atmTenors, const BootstrapConfig& bootstrapConfig, const string& inputType)
61+
const string& strikeInterpolation, const vector<string>& atmTenors, const BootstrapConfig& bootstrapConfig,
62+
const string& inputType, const boost::optional<ParametricSmileConfiguration>& parametricSmileConfiguration)
6263
: CurveConfig(curveID, curveDescription), volatilityType_(volatilityType), extrapolate_(extrapolate),
6364
flatExtrapolation_(flatExtrapolation), includeAtm_(inlcudeAtm), tenors_(tenors), strikes_(strikes),
6465
dayCounter_(dayCounter), settleDays_(settleDays), calendar_(calendar),
6566
businessDayConvention_(businessDayConvention), index_(index), rateComputationPeriod_(rateComputationPeriod),
6667
onCapSettlementDays_(onCapSettlementDays), discountCurve_(discountCurve),
6768
interpolationMethod_(interpolationMethod), interpolateOn_(interpolateOn), timeInterpolation_(timeInterpolation),
68-
strikeInterpolation_(strikeInterpolation), atmTenors_(atmTenors), bootstrapConfig_(bootstrapConfig), inputType_(inputType) {
69+
strikeInterpolation_(strikeInterpolation), atmTenors_(atmTenors), bootstrapConfig_(bootstrapConfig),
70+
inputType_(inputType), parametricSmileConfiguration_(parametricSmileConfiguration) {
6971

7072
// Set extrapolation string. "Linear" just means extrapolation allowed and non-flat.
7173
extrapolation_ = !extrapolate_ ? "None" : (flatExtrapolation_ ? "Flat" : "Linear");
@@ -214,7 +216,13 @@ void CapFloorVolatilityCurveConfig::fromXML(XMLNode* node) {
214216
bootstrapConfig_.fromXML(n);
215217
}
216218

217-
// Optional Input Type
219+
// Optional parametric smile configuration
220+
if(XMLNode* n = XMLUtils::getChildNode(node, "ParametricSmileConfiguration")) {
221+
parametricSmileConfiguration_ = ParametricSmileConfiguration();
222+
parametricSmileConfiguration_->fromXML(n);
223+
}
224+
225+
// Optional Input Type
218226
inputType_ = "TermVolatilities";
219227
if (XMLNode* n = XMLUtils::getChildNode(node, "InputType")) {
220228
inputType_ = XMLUtils::getNodeValue(n);

OREData/ored/configuration/capfloorvolcurveconfig.hpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525

2626
#include <ored/configuration/bootstrapconfig.hpp>
2727
#include <ored/configuration/curveconfig.hpp>
28+
#include <ored/configuration/parametricsmileconfiguration.hpp>
2829
#include <ored/configuration/reportconfig.hpp>
2930
#include <ql/termstructures/volatility/volatilitytype.hpp>
3031
#include <ql/time/calendar.hpp>
@@ -62,7 +63,8 @@ class CapFloorVolatilityCurveConfig : public CurveConfig {
6263
const std::string& interpolationMethod = "BicubicSpline", const std::string& interpolateOn = "TermVolatilities",
6364
const std::string& timeInterpolation = "LinearFlat", const std::string& strikeInterpolation = "LinearFlat",
6465
const std::vector<std::string>& atmTenors = {}, const BootstrapConfig& bootstrapConfig = BootstrapConfig(),
65-
const string& inputType = "TermVolatilities");
66+
const string& inputType = "TermVolatilities",
67+
const boost::optional<ParametricSmileConfiguration>& parametricSmileConfiguration = boost::none);
6668

6769
//! Detailled constructor for proxy config
6870
CapFloorVolatilityCurveConfig(const std::string& curveID, const std::string& curveDescription,
@@ -112,6 +114,10 @@ class CapFloorVolatilityCurveConfig : public CurveConfig {
112114
const QuantLib::Period& proxySourceRateComputationPeriod() const { return proxySourceRateComputationPeriod_; }
113115
const QuantLib::Period& proxyTargetRateComputationPeriod() const { return proxyTargetRateComputationPeriod_; }
114116
//
117+
const boost::optional<ParametricSmileConfiguration> parametricSmileConfiguration() const {
118+
return parametricSmileConfiguration_;
119+
}
120+
//
115121
const ReportConfig& reportConfig() const { return reportConfig_; }
116122
//@}
117123

@@ -151,6 +157,8 @@ class CapFloorVolatilityCurveConfig : public CurveConfig {
151157
QuantLib::Period proxySourceRateComputationPeriod_;
152158
QuantLib::Period proxyTargetRateComputationPeriod_;
153159
//
160+
boost::optional<ParametricSmileConfiguration> parametricSmileConfiguration_;
161+
//
154162
ReportConfig reportConfig_;
155163

156164
//! Populate required curve ids

OREData/ored/configuration/genericyieldvolcurveconfig.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,15 +49,17 @@ GenericYieldVolatilityCurveConfig::GenericYieldVolatilityCurveConfig(
4949
const vector<string>& optionTenors, const vector<string>& underlyingTenors, const DayCounter& dayCounter,
5050
const Calendar& calendar, const BusinessDayConvention& businessDayConvention, const string& shortSwapIndexBase,
5151
const string& swapIndexBase, const vector<string>& smileOptionTenors, const vector<string>& smileUnderlyingTenors,
52-
const vector<string>& smileSpreads)
52+
const vector<string>& smileSpreads,
53+
const boost::optional<ParametricSmileConfiguration>& parametricSmileConfiguration)
5354
: CurveConfig(curveID, curveDescription), underlyingLabel_(underlyingLabel), rootNodeLabel_(rootNodeLabel),
5455
marketDatumInstrumentLabel_(marketDatumInstrumentLabel), qualifierLabel_(qualifierLabel), allowSmile_(true),
5556
requireSwapIndexBases_(false), qualifier_(qualifier), dimension_(dimension), volatilityType_(volatilityType),
5657
interpolation_(interpolation), extrapolation_(extrapolation), optionTenors_(optionTenors),
5758
underlyingTenors_(underlyingTenors), dayCounter_(dayCounter), calendar_(calendar),
5859
businessDayConvention_(businessDayConvention), shortSwapIndexBase_(shortSwapIndexBase),
5960
swapIndexBase_(swapIndexBase), smileOptionTenors_(smileOptionTenors),
60-
smileUnderlyingTenors_(smileUnderlyingTenors), smileSpreads_(smileSpreads) {
61+
smileUnderlyingTenors_(smileUnderlyingTenors), smileSpreads_(smileSpreads),
62+
parametricSmileConfiguration_(parametricSmileConfiguration) {
6163

6264
QL_REQUIRE(dimension == Dimension::ATM || dimension == Dimension::Smile, "Invalid dimension");
6365

@@ -275,6 +277,11 @@ void GenericYieldVolatilityCurveConfig::fromXML(XMLNode* node) {
275277
// optional quote tag to include
276278
quoteTag_ = XMLUtils::getChildValue(node, "QuoteTag", false);
277279

280+
// Optional parametric smile configuration
281+
if(XMLNode* n = XMLUtils::getChildNode(node, "ParametricSmileConfiguration")) {
282+
parametricSmileConfiguration_ = ParametricSmileConfiguration();
283+
parametricSmileConfiguration_->fromXML(n);
284+
}
278285
}
279286

280287
if (auto tmp = XMLUtils::getChildNode(node, "Report")) {

OREData/ored/configuration/genericyieldvolcurveconfig.hpp

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#pragma once
2525

2626
#include <ored/configuration/curveconfig.hpp>
27+
#include <ored/configuration/parametricsmileconfiguration.hpp>
2728
#include <ored/configuration/reportconfig.hpp>
2829
#include <ql/time/calendar.hpp>
2930
#include <ql/time/daycounter.hpp>
@@ -76,19 +77,20 @@ class GenericYieldVolatilityCurveConfig : public CurveConfig {
7677
rootNodeLabel_(rootNodeLabel), marketDatumInstrumentLabel_(marketDatumInstrumentLabel),
7778
qualifierLabel_(qualifierLabel), allowSmile_(allowSmile), requireSwapIndexBases_(requireSwapIndexBases) {}
7879
//! Detailed constructor
79-
GenericYieldVolatilityCurveConfig(const std::string& underlyingLabel, const std::string& rootNodeLabel,
80-
const std::string& marketDatumInstrumentLabel, const std::string& qualifierLabel,
81-
const string& curveID, const string& curveDescription, const string& qualifier,
82-
const Dimension dimension, const VolatilityType volatilityType,
83-
const VolatilityType outputVolatilityType, const Interpolation interpolation,
84-
const Extrapolation extrapolation, const vector<string>& optionTenors,
85-
const vector<string>& underlyingTenors, const DayCounter& dayCounter,
86-
const Calendar& calendar, const BusinessDayConvention& businessDayConvention,
87-
const string& shortSwapIndexBase = "", const string& swapIndexBase = "",
88-
// Only required for smile
89-
const vector<string>& smileOptionTenors = vector<string>(),
90-
const vector<string>& smileUnderlyingTenors = vector<string>(),
91-
const vector<string>& smileSpreads = vector<string>());
80+
GenericYieldVolatilityCurveConfig(
81+
const std::string& underlyingLabel, const std::string& rootNodeLabel,
82+
const std::string& marketDatumInstrumentLabel, const std::string& qualifierLabel, const string& curveID,
83+
const string& curveDescription, const string& qualifier, const Dimension dimension,
84+
const VolatilityType volatilityType, const VolatilityType outputVolatilityType,
85+
const Interpolation interpolation, const Extrapolation extrapolation, const vector<string>& optionTenors,
86+
const vector<string>& underlyingTenors, const DayCounter& dayCounter, const Calendar& calendar,
87+
const BusinessDayConvention& businessDayConvention, const string& shortSwapIndexBase = "",
88+
const string& swapIndexBase = "",
89+
// Only required for smile
90+
const vector<string>& smileOptionTenors = vector<string>(),
91+
const vector<string>& smileUnderlyingTenors = vector<string>(),
92+
const vector<string>& smileSpreads = vector<string>(),
93+
const boost::optional<ParametricSmileConfiguration>& parametricSmileConfiguration = boost::none);
9294
//! Detailed contructor for proxy config
9395
GenericYieldVolatilityCurveConfig(const std::string& underlyingLabel, const std::string& rootNodeLabel,
9496
const std::string& qualifierLabel, const string& curveID,
@@ -134,6 +136,10 @@ class GenericYieldVolatilityCurveConfig : public CurveConfig {
134136
const std::string& proxyTargetShortSwapIndexBase() const { return proxyTargetShortSwapIndexBase_; }
135137
const std::string& proxyTargetSwapIndexBase() const { return proxyTargetSwapIndexBase_; }
136138
//
139+
const boost::optional<ParametricSmileConfiguration> parametricSmileConfiguration() const {
140+
return parametricSmileConfiguration_;
141+
}
142+
//
137143
const ReportConfig& reportConfig() const { return reportConfig_; }
138144
//@}
139145

@@ -187,6 +193,8 @@ class GenericYieldVolatilityCurveConfig : public CurveConfig {
187193
string proxyTargetShortSwapIndexBase_;
188194
string proxyTargetSwapIndexBase_;
189195

196+
boost::optional<ParametricSmileConfiguration> parametricSmileConfiguration_;
197+
190198
ReportConfig reportConfig_;
191199
};
192200

OREData/ored/configuration/parametricsmileconfiguration.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ void ParametricSmileConfiguration::Calibration::fromXML(XMLNode* node) {
4343
XMLUtils::checkNode(node, "Calibration");
4444
maxCalibrationAttempts = parseInteger(XMLUtils::getChildValue(node, "MaxCalibrationAttempts", true));
4545
exitEarlyErrorThreshold = parseReal(XMLUtils::getChildValue(node, "ExitEarlyErrorThreshold", true));
46-
maxAcceptableError = parseBool(XMLUtils::getChildValue(node, "MaxAcceptableError", true));
46+
maxAcceptableError = parseReal(XMLUtils::getChildValue(node, "MaxAcceptableError", true));
4747
}
4848

4949
XMLNode* ParametricSmileConfiguration::Calibration::toXML(XMLDocument& doc) const {
@@ -94,7 +94,7 @@ const ParametricSmileConfiguration::Parameter& ParametricSmileConfiguration::par
9494
auto p =
9595
std::find_if(parameters_.begin(), parameters_.end(), [&name](const Parameter& p) { return p.name == name; });
9696
QL_REQUIRE(p != parameters_.end(), "ParametricSmileConfiguration: parameter '" << name << "' is not present.");
97-
return p->second;
97+
return *p;
9898
}
9999

100100
const ParametricSmileConfiguration::Calibration& ParametricSmileConfiguration::calibration() const {

OREData/ored/configuration/parametricsmileconfiguration.hpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,20 +40,21 @@ class ParametricSmileConfiguration : public XMLSerializable {
4040
ore::data::XMLNode* toXML(ore::data::XMLDocument& doc) const override;
4141

4242
std::string name;
43-
double initialValue;
44-
bool isFixed;
43+
double initialValue = 0.0;
44+
bool isFixed = false;
4545
};
4646

4747
class Calibration : public XMLSerializable {
4848
public:
4949
void fromXML(ore::data::XMLNode* node) override;
5050
ore::data::XMLNode* toXML(ore::data::XMLDocument& doc) const override;
5151

52-
std::size_t maxCalibrationAttempts;
53-
double exitEarlyErrorThreshold;
54-
double maxAcceptableError;
52+
std::size_t maxCalibrationAttempts = 10;
53+
double exitEarlyErrorThreshold = 0.0050;
54+
double maxAcceptableError = 0.05;
5555
};
5656

57+
ParametricSmileConfiguration() {}
5758
ParametricSmileConfiguration(std::vector<Parameter> parameters, Calibration calibration);
5859

5960
//! \name XMLSerializable interface

0 commit comments

Comments
 (0)