Skip to content

Commit 04dccaf

Browse files
pcaspersjenkins
authored andcommitted
align
1 parent de12bef commit 04dccaf

40 files changed

Lines changed: 1889 additions & 1610 deletions

Docker/.env

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ DEBIAN_TAG=11.7
22

33
# it's recommended to include CMAKE_BUILD_TYPE and BOOST_VARIANT in QL_TAG, ORE_TAG, BOOST_TAG
44
# to distinguish a release build from a debug build
5-
QL_TAG=1.38_81c5850b6
5+
QL_TAG=1.38_2546e8e82
66
ORE_TAG=latest
77

88
# debug or release

Docs/UserGuide/parameterisation/curveconfig.tex

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1195,6 +1195,7 @@ \subsubsection{Bootstrap Configuration}
11951195
<MaxFactor>...</MaxFactor>
11961196
<MinFactor>...</MinFactor>
11971197
<DontThrowSteps>...</DontThrowSteps>
1198+
<Global>...<Global>
11981199
</BootstrapConfig>
11991200
\end{minted}
12001201
\caption{\lstinline!BootstrapConfig! node outline}
@@ -1203,8 +1204,10 @@ \subsubsection{Bootstrap Configuration}
12031204
12041205
The meaning of each of the elements is:
12051206
\begin{itemize}
1206-
\item \lstinline!Accuracy! [Optional]:
1207-
The accuracy with which the implied quote must match the market quote for each instrument in the curve bootstrap. This node should hold a positive real number. If omitted, the default value is \num[scientific-notation=true]{1.0e-12}.
1207+
\item \lstinline!Accuracy! [Optional]: The accuracy with which the implied quote must match the market quote for each
1208+
instrument in the curve bootstrap (iterative bootstrap) or the accuracy of the global optimizer (global
1209+
bootstrap). This node should hold a positive real number. If omitted, the default value is
1210+
\num[scientific-notation=true]{1.0e-12}.
12081211
12091212
\item \lstinline!GlobalAccuracy! [Optional]:
12101213
If the interpolation method in the bootstrap is global, e.g. cubic spline, the bootstrap routine needs to perform multiple iterative bootstraps of the curve to converge. After each such bootstrap of the full curve, the absolute value of the change between the current bootstrap and previous bootstrap for the curve value at each pillar is calculated. The global bootstrap is deemed to have converged if the maximum of these changes is less than the global accuracy or the accuracy from the \lstinline!Accuracy! node. This node should hold a positive real number. If omitted, the global accuracy is set equal to the accuracy from the \lstinline!Accuracy! node. This node is useful in some cases where a slightly less restrictive accuracy, than that given by the \lstinline!Accuracy! node, is needed for the global bootstrap.
@@ -1224,6 +1227,12 @@ \subsubsection{Bootstrap Configuration}
12241227
\item \lstinline!DontThrowSteps! [Optional]:
12251228
This node is used only if \lstinline!DontThrow! is \lstinline!true!. The meaning of this node is given in the description of the \lstinline!DontThrow! node. This node should hold a positive integer. If omitted, the default value is 10.
12261229
1230+
\item \lstinline!Global! [Optional]: This nodes specifies whether the curve should use a global bootstrap over all
1231+
instruments of the curve (true) or iterative bootstrap (false, default value). If global boostrap is used, only the
1232+
Accuracy field of the BootstrapConfig is relevant and specifies the accuracy of the global optimizer. If a cycle is
1233+
present in the dependency graph of the curves, all members of the cycle must use global bootstrap, in this case a
1234+
global optimization is run over all instrument of all members of the cycle simultaneously.
1235+
12271236
\end{itemize}
12281237
12291238
\subsubsection{One Dimensional Solver Configuration}

OREAnalytics/test/testmarket.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -108,9 +108,10 @@ parRateCurveHelpers(const string& ccy, const vector<string>& parInst, const vect
108108
QuantLib::ext::shared_ptr<OisConvention> oisConv = QuantLib::ext::dynamic_pointer_cast<OisConvention>(conv);
109109
BOOST_ASSERT(oisConv);
110110
rateHelper = QuantLib::ext::make_shared<QuantExt::OISRateHelper>(
111-
oisConv->spotLag(), tenor, parRateQuote, oisConv->index(), oisConv->fixedDayCounter(),
111+
oisConv->spotLag(), tenor, parRateQuote, oisConv->index(), false, oisConv->fixedDayCounter(),
112112
oisConv->fixedCalendar(), oisConv->paymentLag(), oisConv->eom(), oisConv->fixedFrequency(),
113-
oisConv->fixedConvention(), oisConv->fixedPaymentConvention(), oisConv->rule(), exDiscount, true);
113+
oisConv->fixedConvention(), oisConv->fixedPaymentConvention(), oisConv->rule(), exDiscount,
114+
!exDiscount.empty(), true);
114115
} else if (parInst[i] == "FXF") {
115116
QuantLib::ext::shared_ptr<Convention> conv = conventions->get(ccy + "-FX-CONVENTIONS");
116117
QuantLib::ext::shared_ptr<FXConvention> fxConv = QuantLib::ext::dynamic_pointer_cast<FXConvention>(conv);
@@ -147,8 +148,8 @@ parRateCurveHelpers(const string& ccy, const vector<string>& parInst, const vect
147148
bool flatIsDomestic = true; // assumes fxSpot is in form 1*BaseCcy = X*Ccy
148149
rateHelper = QuantLib::ext::make_shared<CrossCcyBasisSwapHelper>(
149150
parRateQuote, fxSpot, basisConv->settlementDays(), basisConv->settlementCalendar(), tenor,
150-
basisConv->rollConvention(), flatIndex, spreadIndex, fgnDiscount, exDiscount, basisConv->eom(),
151-
flatIsDomestic);
151+
basisConv->rollConvention(), flatIndex, spreadIndex, fgnDiscount, exDiscount, true, true, true, false,
152+
basisConv->eom(), flatIsDomestic);
152153
} else {
153154
BOOST_ERROR("Unrecognised par rate instrument in curve construction - " << i);
154155
}

OREData/ored/configuration/bootstrapconfig.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,10 @@ namespace ore {
2525
namespace data {
2626

2727
BootstrapConfig::BootstrapConfig(Real accuracy, Real globalAccuracy, bool dontThrow, Size maxAttempts, Real maxFactor,
28-
Real minFactor, Size dontThrowSteps)
28+
Real minFactor, Size dontThrowSteps, bool global)
2929
: accuracy_(accuracy), globalAccuracy_(globalAccuracy == Null<Real>() ? accuracy_ : globalAccuracy),
3030
dontThrow_(dontThrow), maxAttempts_(maxAttempts), maxFactor_(maxFactor), minFactor_(minFactor),
31-
dontThrowSteps_(dontThrowSteps) {}
31+
dontThrowSteps_(dontThrowSteps), global_(global) {}
3232

3333
void BootstrapConfig::fromXML(XMLNode* node) {
3434

@@ -74,6 +74,11 @@ void BootstrapConfig::fromXML(XMLNode* node) {
7474
QL_REQUIRE(dontThrowSteps > 0, "DontThrowSteps (" << dontThrowSteps << ") must be a positive integer");
7575
dontThrowSteps_ = static_cast<Size>(dontThrowSteps);
7676
}
77+
78+
global_ = false;
79+
if (XMLNode* n = XMLUtils::getChildNode(node, "Global")) {
80+
global_ = parseBool(XMLUtils::getNodeValue(n));
81+
}
7782
}
7883

7984
XMLNode* BootstrapConfig::toXML(XMLDocument& doc) const {
@@ -86,6 +91,7 @@ XMLNode* BootstrapConfig::toXML(XMLDocument& doc) const {
8691
XMLUtils::addChild(doc, node, "MaxFactor", maxFactor_);
8792
XMLUtils::addChild(doc, node, "MinFactor", minFactor_);
8893
XMLUtils::addChild(doc, node, "DontThrowSteps", static_cast<int>(dontThrowSteps_));
94+
XMLUtils::addChild(doc, node, "Global", global_);
8995

9096
return node;
9197
}

OREData/ored/configuration/bootstrapconfig.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ class BootstrapConfig : public XMLSerializable {
3737
//! Constructor
3838
BootstrapConfig(QuantLib::Real accuracy = 1.0e-12, QuantLib::Real globalAccuracy = QuantLib::Null<QuantLib::Real>(),
3939
bool dontThrow = false, QuantLib::Size maxAttempts = 5, QuantLib::Real maxFactor = 2.0,
40-
QuantLib::Real minFactor = 2.0, QuantLib::Size dontThrowSteps = 10);
40+
QuantLib::Real minFactor = 2.0, QuantLib::Size dontThrowSteps = 10, bool global = false);
4141

4242
//! \name XMLSerializable interface
4343
//@{
@@ -54,6 +54,7 @@ class BootstrapConfig : public XMLSerializable {
5454
QuantLib::Real maxFactor() const { return maxFactor_; }
5555
QuantLib::Real minFactor() const { return minFactor_; }
5656
QuantLib::Size dontThrowSteps() const { return dontThrowSteps_; }
57+
bool global() const { return global_; }
5758
//@}
5859

5960
private:
@@ -64,6 +65,7 @@ class BootstrapConfig : public XMLSerializable {
6465
QuantLib::Real maxFactor_;
6566
QuantLib::Real minFactor_;
6667
QuantLib::Size dontThrowSteps_;
68+
bool global_;
6769
};
6870

6971
} // namespace data

OREData/ored/configuration/curveconfigurations.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,7 @@ CurveConfigurations::requiredCurveIds(const CurveSpec::CurveType& type, const st
455455
}
456456

457457
bool CurveConfigurations::hasYieldCurveConfig(const string& curveID) const { return has(CurveSpec::CurveType::Yield, curveID); }
458+
458459
QuantLib::ext::shared_ptr<YieldCurveConfig> CurveConfigurations::yieldCurveConfig(const string& curveID) const {
459460
QuantLib::ext::shared_ptr<CurveConfig> cc = get(CurveSpec::CurveType::Yield, curveID);
460461
return QuantLib::ext::dynamic_pointer_cast<YieldCurveConfig>(cc);

OREData/ored/marketdata/commoditycurve.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -339,13 +339,15 @@ void CommodityCurve::buildCrossCurrencyPriceCurve(
339339
<< config->curveID());
340340

341341
// Look up the two yield curves in the yieldCurves map
342-
auto baseYtsIt = yieldCurves.find(YieldCurveSpec(baseConfig->currency(), config->baseYieldCurveId()).name());
342+
auto baseYtsKey = YieldCurveSpec(baseConfig->currency(), config->baseYieldCurveId()).name();
343+
auto baseYtsIt = yieldCurves.find(baseYtsKey);
343344
QL_REQUIRE(baseYtsIt != yieldCurves.end(),
344345
"Could not find base yield curve with id "
345346
<< config->baseYieldCurveId() << " and currency " << baseConfig->currency()
346347
<< " required in the building of commodity curve with id " << config->curveID());
347348

348-
auto ytsIt = yieldCurves.find(YieldCurveSpec(config->currency(), config->yieldCurveId()).name());
349+
auto ytsKey = YieldCurveSpec(config->currency(), config->yieldCurveId()).name();
350+
auto ytsIt = yieldCurves.find(ytsKey);
349351
QL_REQUIRE(ytsIt != yieldCurves.end(), "Could not find yield curve with id "
350352
<< config->yieldCurveId() << " and currency " << config->currency()
351353
<< " required in the building of commodity curve with id "
@@ -357,7 +359,7 @@ void CommodityCurve::buildCrossCurrencyPriceCurve(
357359
// Populate the commodityPriceCurve_ member
358360
commodityPriceCurve_ = QuantLib::ext::make_shared<CrossCurrencyPriceTermStructure>(
359361
asof, QuantLib::Handle<PriceTermStructure>(commIt->second->commodityPriceCurve()), fxSpot,
360-
baseYtsIt->second->handle(), ytsIt->second->handle(), parseCurrency(config->currency()));
362+
baseYtsIt->second->handle(baseYtsKey), ytsIt->second->handle(ytsKey), parseCurrency(config->currency()));
361363
}
362364

363365
void CommodityCurve::buildBasisPriceCurve(const Date& asof, const CommodityCurveConfig& config,

OREData/ored/marketdata/commodityvolcurve.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1755,7 +1755,7 @@ void CommodityVolCurve::populateCurves(const CommodityVolatilityConfig& config,
17551755
if (!ytsId.empty()) {
17561756
auto itYts = yieldCurves.find(ytsId);
17571757
if (itYts != yieldCurves.end()) {
1758-
yts_ = itYts->second->handle();
1758+
yts_ = itYts->second->handle(ytsId);
17591759
} else if (!dontThrow) {
17601760
QL_FAIL("CommodityVolCurve: can't find yield curve with id " << ytsId);
17611761
}

OREData/ored/marketdata/correlationcurve.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ void CorrelationCurve::calibrateCMSSpreadCorrelations(
111111
Handle<YieldTermStructure> yts;
112112
auto it2 = yieldCurves.find(dc);
113113
if (it2 != yieldCurves.end()) {
114-
yts = it2->second->handle();
114+
yts = it2->second->handle(dc);
115115
} else {
116116
QL_FAIL("The discount curve not found, " << dc);
117117
}

OREData/ored/marketdata/defaultcurve.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,7 @@ void DefaultCurve::buildCdsCurve(const std::string& curveID, const DefaultCurveC
324324
QL_REQUIRE(it != yieldCurves.end(), "The discount curve, " << config.discountCurveID()
325325
<< ", required in the building of the curve, "
326326
<< spec.name() << ", was not found.");
327-
Handle<YieldTermStructure> discountCurve = it->second->handle();
327+
Handle<YieldTermStructure> discountCurve = it->second->handle(config.discountCurveID());
328328

329329
// Get the CDS spread / price curve quotes
330330
set<QuoteData> quotes = getConfiguredQuotes(curveID, config, asof, loader);
@@ -643,9 +643,9 @@ void DefaultCurve::buildBenchmarkCurve(const std::string& curveID, const Default
643643
Date spot = cal.advance(asof, spotLag * Days);
644644
for (Size i = 0; i < pillars.size(); ++i) {
645645
dates.push_back(cal.advance(spot, pillars[i]));
646-
Real tmp = dates[i] == asof
647-
? 1.0
648-
: sourceCurve->handle()->discount(dates[i]) / benchmarkCurve->handle()->discount(dates[i]);
646+
Real tmp = dates[i] == asof ? 1.0
647+
: sourceCurve->handle(config.sourceCurveID())->discount(dates[i]) /
648+
benchmarkCurve->handle(config.benchmarkCurveID())->discount(dates[i]);
649649
// if a non-zero recovery rate is given, we adjust the implied surv probability according to a market value
650650
// recovery model (see the documentation of the benchmark curve in the user guide for more details)
651651
impliedSurvProb.push_back(std::pow(tmp, 1.0 / (1.0 - recoveryRate_)));

0 commit comments

Comments
 (0)