33#include <ql/math/functional.hpp>
34#include <ql/quotes/derivedquote.hpp>
35#include <ql/termstructures/credit/flathazardrate.hpp>
36#include <ql/termstructures/volatility/equityfx/blackconstantvol.hpp>
37#include <ql/termstructures/yield/flatforward.hpp>
47 const std::string&
id,
const std::string& ccy,
const std::string& creditCurveId,
const bool hasCreditRisk,
48 const std::string& securityId,
const std::string& referenceCurveId,
const bool isExchangeable,
49 QuantLib::ext::shared_ptr<QuantExt::EquityIndex2> equity,
const QuantLib::ext::shared_ptr<QuantExt::FxIndex>& fx,
50 const std::string& equityCreditCurveId,
const QuantLib::Date& startDate,
const QuantLib::Date& maturityDate) {
55 const std::string&
id,
const std::string& ccy,
const std::string& creditCurveId,
const bool hasCreditRisk,
56 const std::string& securityId,
const std::string& referenceCurveId,
const bool isExchangeable,
57 QuantLib::ext::shared_ptr<QuantExt::EquityIndex2> equity,
const QuantLib::ext::shared_ptr<QuantExt::FxIndex>& fx,
58 const std::string& equityCreditCurveId,
const QuantLib::Date& startDate,
const QuantLib::Date& maturityDate) {
71 auto modelMesherConcentrationStr =
engineParameter(
"Bootstrap.MesherConcentration", {},
false,
"");
72 Real modelMesherConcentration = Null<Real>();
73 if (!modelMesherConcentrationStr.empty())
74 modelMesherConcentration =
parseReal(modelMesherConcentrationStr);
77 if (bootstrapModeStr ==
"Alternating") {
78 bootstrapMode = DefaultableEquityJumpDiffusionModelBuilder::BootstrapMode::Alternating;
79 }
else if (bootstrapModeStr ==
"Simultaneously") {
80 bootstrapMode = DefaultableEquityJumpDiffusionModelBuilder::BootstrapMode::Simultaneously;
82 QL_FAIL(
"invalid Bootstrap.Mode, expected Alternating or Simultaneously");
88 std::vector<Real> conversionRatioDiscretisationGrid =
98 bool treatSecuritySpreadAsCreditSpread =
103 std::string equityName;
104 Handle<BlackVolTermStructure> volatility;
106 if (equity !=
nullptr) {
107 equityName = equity->name();
108 volatility =
market_->equityVol(equityName, config);
112 equity = QuantLib::ext::make_shared<QuantExt::EquityIndex2>(
113 "dummyFamily", NullCalendar(), fx ==
nullptr ?
parseCurrency(ccy) : fx->sourceCurrency(),
114 Handle<Quote>(QuantLib::ext::make_shared<SimpleQuote>(1.0)),
115 Handle<YieldTermStructure>(QuantLib::ext::make_shared<FlatForward>(0, NullCalendar(), 0.0, Actual365Fixed())),
116 Handle<YieldTermStructure>(QuantLib::ext::make_shared<FlatForward>(0, NullCalendar(), 0.0, Actual365Fixed())));
118 volatility = Handle<BlackVolTermStructure>(QuantLib::ext::make_shared<BlackConstantVol>(
119 0, NullCalendar(), Handle<Quote>(QuantLib::ext::make_shared<SimpleQuote>(0.0)), Actual365Fixed()));
124 Handle<YieldTermStructure> referenceCurve;
125 if (adjustDiscounting)
126 referenceCurve =
market_->yieldCurve(referenceCurveId, config);
128 Handle<DefaultProbabilityTermStructure> creditCurve;
129 Real creditCurveRecovery = 0.0;
130 if (!creditCurveId.empty() && hasCreditRisk) {
132 creditCurveRecovery =
market_->recoveryRate(creditCurveId, config)->value();
134 if (!creditCurveId.empty()) {
136 market_->recoveryRate(creditCurveId, config)->value();
138 creditCurve = Handle<DefaultProbabilityTermStructure>(
139 QuantLib::ext::make_shared<FlatHazardRate>(0, NullCalendar(), 0.0, Actual365Fixed()));
144 Handle<Quote> recovery;
145 if (!zeroRecoveryOverwrite) {
147 recovery =
market_->recoveryRate(securityId, config);
149 if (!creditCurveId.empty() && hasCreditRisk) {
150 recovery =
market_->recoveryRate(creditCurveId, config);
151 }
else if (!creditCurveId.empty()) {
152 market_->recoveryRate(creditCurveId, config);
159 Handle<Quote> spread;
160 if (adjustDiscounting || treatSecuritySpreadAsCreditSpread) {
162 spread =
market_->securitySpread(securityId, config);
164 spread = Handle<Quote>(QuantLib::ext::make_shared<SimpleQuote>(0.0));
170 Handle<DefaultProbabilityTermStructure> equityCreditCurve;
171 Real equityCreditCurveRecovery = 0.0;
172 if (isExchangeable) {
173 if (!equityCreditCurveId.empty() && hasCreditRisk) {
174 equityCreditCurve =
market_->defaultCurve(equityCreditCurveId, config)->curve();
175 equityCreditCurveRecovery =
market_->recoveryRate(equityCreditCurveId, config)->value();
177 if (!equityCreditCurveId.empty()) {
178 market_->defaultCurve(equityCreditCurveId, config);
179 market_->recoveryRate(equityCreditCurveId, config)->value();
181 equityCreditCurve = Handle<DefaultProbabilityTermStructure>(
182 QuantLib::ext::make_shared<FlatHazardRate>(0, NullCalendar(), 0.0, Actual365Fixed()));
188 if (adjustCreditSpreadToRR) {
189 Real rr = recovery.empty() ? 0.0 : recovery->value();
190 creditCurve = Handle<DefaultProbabilityTermStructure>(QuantLib::ext::make_shared<AdjustedDefaultCurve>(
191 creditCurve, Handle<Quote>(QuantLib::ext::make_shared<SimpleQuote>((1.0 - creditCurveRecovery) / (1.0 - rr)))));
192 if (!equityCreditCurve.empty()) {
193 equityCreditCurve = Handle<DefaultProbabilityTermStructure>(QuantLib::ext::make_shared<AdjustedDefaultCurve>(
195 Handle<Quote>(QuantLib::ext::make_shared<SimpleQuote>((1.0 - equityCreditCurveRecovery) / (1.0 - rr)))));
201 if (treatSecuritySpreadAsCreditSpread) {
202 Real rr = recovery.empty() ? 0.0 : recovery->value();
203 auto m = [rr](Real x) {
return x / ( 1.0 -rr); };
204 Handle<Quote> scaledSecuritySpread(QuantLib::ext::make_shared<DerivedQuote<
decltype(m)>>(spread, m));
205 creditCurve = Handle<DefaultProbabilityTermStructure>(
206 QuantLib::ext::make_shared<HazardSpreadedDefaultTermStructure>(creditCurve, scaledSecuritySpread));
207 if (!equityCreditCurve.empty()) {
208 equityCreditCurve = Handle<DefaultProbabilityTermStructure>(
209 QuantLib::ext::make_shared<HazardSpreadedDefaultTermStructure>(equityCreditCurve, scaledSecuritySpread));
216 auto fxVol =
market_->fxVol(equity->currency().code() + ccy, config);
217 QuantLib::Handle<QuantExt::CorrelationTermStructure> corrCurve(
218 QuantLib::ext::make_shared<FlatCorrelation>(0, NullCalendar(), 0.0, Actual365Fixed()));
220 corrCurve =
market_->correlationCurve(
"FX-GENERIC-" + equity->currency().code() +
"-" + ccy,
221 "EQ-" + equity->name());
223 WLOG(
"correlation curve for FX-GENERIC-" + equity->currency().code()
224 <<
", EQ-" << equity->name() <<
" not found, fall back to zero correlation.");
226 equity = QuantLib::ext::make_shared<CompoEquityIndex>(equity, fx, startDate);
227 volatility = Handle<BlackVolTermStructure>(QuantLib::ext::make_shared<BlackTriangulationATMVolTermStructure>(
234 std::vector<Real> calibrationTimes;
235 Date today = Settings::instance().evaluationDate();
236 for (Size i = 0; i < calibrationDates.size(); ++i) {
237 if (calibrationDates[i] < maturityDate) {
238 calibrationTimes.push_back(!volatility.empty() ? volatility->timeFromReference(calibrationDates[i])
239 : Actual365Fixed().yearFraction(today, calibrationDates[i]));
242 calibrationTimes.push_back(!volatility.empty() ? volatility->timeFromReference(maturityDate)
243 : Actual365Fixed().yearFraction(today, maturityDate));
247 bool calibrate =
true;
253 bool generateAdditionalResults =
false;
256 generateAdditionalResults =
parseBool(genAddParam->second);
261 auto modelBuilder = QuantLib::ext::make_shared<DefaultableEquityJumpDiffusionModelBuilder>(
262 calibrationTimes, equity, volatility, isExchangeable ? equityCreditCurve : creditCurve, p, eta, staticMesher,
263 modelTimeStepsPerYear, modelStateGridPoints, modelMesherEpsilon, modelMesherScaling, modelMesherConcentration,
264 bootstrapMode,
false, calibrate, adjustEquityVolatility, adjustEquityForward);
268 return QuantLib::ext::make_shared<FdDefaultableEquityJumpDiffusionConvertibleBondEngine>(
269 modelBuilder->model(), referenceCurve, treatSecuritySpreadAsCreditSpread ? Handle<Quote>() : spread,
270 isExchangeable ? creditCurve : Handle<DefaultProbabilityTermStructure>(), recovery, Handle<FxIndex>(fx),
271 staticMesher, engineTimeStepsPerYear, engineStateGridPoints, engineMesherEpsilon, engineMesherScaling,
272 conversionRatioDiscretisationGrid, generateAdditionalResults);
std::string keyImpl(const std::string &id, const std::string &ccy, const std::string &creditCurveId, const bool hasCreditRisk, const std::string &securityId, const std::string &referenceCurveId, const bool isExchangeable, QuantLib::ext::shared_ptr< QuantExt::EquityIndex2 > equity, const QuantLib::ext::shared_ptr< QuantExt::FxIndex > &fx, const std::string &equityCreditCurveId, const QuantLib::Date &startDate, const QuantLib::Date &maturityDate) override
QuantLib::ext::shared_ptr< QuantExt::PricingEngine > engineImpl(const std::string &id, const std::string &ccy, const std::string &creditCurveId, const bool hasCreditRisk, const std::string &securityId, const std::string &referenceCurveId, const bool isExchangeable, QuantLib::ext::shared_ptr< QuantExt::EquityIndex2 > equity, const QuantLib::ext::shared_ptr< QuantExt::FxIndex > &fx, const std::string &equityCreditCurveId, const QuantLib::Date &startDate, const QuantLib::Date &maturityDate) override
const std::vector< QuantLib::Date > & dates() const
QuantLib::ext::shared_ptr< Market > market_
std::string modelParameter(const std::string &p, const std::vector< std::string > &qualifiers={}, const bool mandatory=true, const std::string &defaultValue="") const
std::string engineParameter(const std::string &p, const std::vector< std::string > &qualifiers={}, const bool mandatory=true, const std::string &defaultValue="") const
const string & configuration(const MarketContext &key)
Return a configuration (or the default one if key not found)
set< std::pair< string, QuantLib::ext::shared_ptr< QuantExt::ModelBuilder > > > modelBuilders_
std::map< std::string, std::string > globalParameters_
Currency parseCurrency(const string &s)
Convert text to QuantLib::Currency.
bool parseBool(const string &s)
Convert text to bool.
Real parseReal(const string &s)
Convert text to Real.
Integer parseInteger(const string &s)
Convert text to QuantLib::Integer.
leg data model and serialization
#define WLOG(text)
Logging Macro (Level = Warning)
market data related utilties
QuantLib::Handle< QuantExt::CreditCurve > securitySpecificCreditCurve(const QuantLib::ext::shared_ptr< Market > &market, const std::string &securityId, const std::string &creditCurveId, const std::string &configuration)
Serializable Credit Default Swap.