Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion QuantLib.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -1698,6 +1698,7 @@
<ClInclude Include="ql\termstructures\defaulttermstructure.hpp" />
<ClInclude Include="ql\termstructures\globalbootstrap.hpp" />
<ClInclude Include="ql\termstructures\globalbootstrapvars.hpp" />
<ClInclude Include="ql\termstructures\multicurve.hpp" />
<ClInclude Include="ql\termstructures\inflation\all.hpp" />
<ClInclude Include="ql\termstructures\inflation\inflationhelpers.hpp" />
<ClInclude Include="ql\termstructures\inflation\inflationtraits.hpp" />
Expand Down Expand Up @@ -2736,7 +2737,9 @@
<ClCompile Include="ql\termstructures\credit\hazardratestructure.cpp" />
<ClCompile Include="ql\termstructures\credit\survivalprobabilitystructure.cpp" />
<ClCompile Include="ql\termstructures\defaulttermstructure.cpp" />
<ClCompile Include="ql\termstructures\globalbootstrap.cpp" />
<ClCompile Include="ql\termstructures\globalbootstrapvars.cpp" />
<ClCompile Include="ql\termstructures\multicurve.cpp" />
<ClCompile Include="ql\termstructures\inflation\inflationhelpers.cpp" />
<ClCompile Include="ql\termstructures\inflation\seasonality.cpp" />
<ClCompile Include="ql\termstructures\inflationtermstructure.cpp" />
Expand Down Expand Up @@ -2891,4 +2894,4 @@
<Import Project=".\Build.props" Condition="Exists('.\Build.props')" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
</Project>
11 changes: 10 additions & 1 deletion QuantLib.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -1974,6 +1974,9 @@
<ClInclude Include="ql\termstructures\localbootstrap.hpp">
<Filter>termstructures</Filter>
</ClInclude>
<ClInclude Include="ql\termstructures\multicurve.hpp">
<Filter>termstructures</Filter>
</ClInclude>
<ClInclude Include="ql\termstructures\voltermstructure.hpp">
<Filter>termstructures</Filter>
</ClInclude>
Expand Down Expand Up @@ -5537,12 +5540,18 @@
<ClCompile Include="ql\termstructures\defaulttermstructure.cpp">
<Filter>termstructures</Filter>
</ClCompile>
<ClCompile Include="ql\termstructures\globalbootstrap.cpp">
<Filter>termstructures</Filter>
</ClCompile>
<ClCompile Include="ql\termstructures\globalbootstrapvars.cpp">
<Filter>termstructures</Filter>
</ClCompile>
<ClCompile Include="ql\termstructures\inflationtermstructure.cpp">
<Filter>termstructures</Filter>
</ClCompile>
<ClCompile Include="ql\termstructures\multicurve.cpp">
<Filter>termstructures</Filter>
</ClCompile>
<ClCompile Include="ql\termstructures\voltermstructure.cpp">
<Filter>termstructures</Filter>
</ClCompile>
Expand Down Expand Up @@ -7346,4 +7355,4 @@
<Filter>pricingengines</Filter>
</ClCompile>
</ItemGroup>
</Project>
</Project>
3 changes: 3 additions & 0 deletions ql/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -818,7 +818,9 @@ set(QL_SOURCES
termstructures/credit/hazardratestructure.cpp
termstructures/credit/survivalprobabilitystructure.cpp
termstructures/defaulttermstructure.cpp
termstructures/globalbootstrap.cpp
termstructures/globalbootstrapvars.cpp
termstructures/multicurve.cpp
termstructures/inflation/inflationhelpers.cpp
termstructures/inflation/seasonality.cpp
termstructures/inflationtermstructure.cpp
Expand Down Expand Up @@ -2078,6 +2080,7 @@ set(QL_HEADERS
termstructures/defaulttermstructure.hpp
termstructures/globalbootstrap.hpp
termstructures/globalbootstrapvars.hpp
termstructures/multicurve.hpp
termstructures/inflation/inflationhelpers.hpp
termstructures/inflation/inflationtraits.hpp
termstructures/inflation/interpolatedyoyinflationcurve.hpp
Expand Down
6 changes: 6 additions & 0 deletions ql/patterns/lazyobject.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ namespace QuantLib {
//@}
/*! Returns true if the instrument is calculated */
bool isCalculated() const;
/*! Set calculated status */
void setCalculated(const bool c) const;
/*! \name Calculations
These methods do not modify the structure of the object
and are therefore declared as <tt>const</tt>. Data members
Expand Down Expand Up @@ -266,6 +268,10 @@ namespace QuantLib {
inline bool LazyObject::isCalculated() const {
return calculated_;
}

inline void LazyObject::setCalculated(const bool c) const {
calculated_ = c;
}
}

#endif
3 changes: 3 additions & 0 deletions ql/termstructures/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,16 @@ this_include_HEADERS = \
interpolatedcurve.hpp \
iterativebootstrap.hpp \
localbootstrap.hpp \
multicurve.hpp \
voltermstructure.hpp \
yieldtermstructure.hpp

cpp_files = \
defaulttermstructure.cpp \
globalbootstrap.cpp \
globalbootstrapvars.cpp \
inflationtermstructure.cpp \
multicurve.cpp \
voltermstructure.cpp \
yieldtermstructure.cpp

Expand Down
111 changes: 111 additions & 0 deletions ql/termstructures/globalbootstrap.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */

/*
Copyright (C) 2019 SoftSolutions! S.r.l.
Copyright (C) 2025 Peter Caspers

This file is part of QuantLib, a free-software/open-source library
for financial quantitative analysts and developers - http://quantlib.org/

QuantLib is free software: you can redistribute it and/or modify it
under the terms of the QuantLib license. You should have received a
copy of the license along with this program; if not, please email
<[email protected]>. The license is also available online at
<http://quantlib.org/license.shtml>.

This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the license for more details.
*/

#include <ql/math/optimization/levenbergmarquardt.hpp>
#include <ql/termstructures/globalbootstrap.hpp>

namespace QuantLib {

MultiCurveBootstrap::MultiCurveBootstrap(Real accuracy) {
optimizer_ = ext::make_shared<LevenbergMarquardt>(accuracy, accuracy, accuracy);
endCriteria_ = ext::make_shared<EndCriteria>(1000, 10, accuracy, accuracy, accuracy);
}

MultiCurveBootstrap::MultiCurveBootstrap(ext::shared_ptr<OptimizationMethod> optimizer,
ext::shared_ptr<EndCriteria> endCriteria)
: optimizer_(std::move(optimizer)), endCriteria_(std::move(endCriteria)) {}

void MultiCurveBootstrap::add(const MultiCurveBootstrapContributor* c) {
contributors_.push_back(c);
c->setParentBootstrapper(shared_from_this());
}

void MultiCurveBootstrap::addObserver(Observer* o) {
observers_.push_back(o);
}

void MultiCurveBootstrap::runMultiCurveBootstrap() {

std::vector<Size> guessSizes;
std::vector<Real> globalGuess;

for (auto const& c : contributors_) {
Array guess = c->setupCostFunction();
globalGuess.insert(globalGuess.end(), guess.begin(), guess.end());
guessSizes.push_back(guess.size());
}

auto fn = [this, &guessSizes](const Array& x) {
// call the contributors' cost functions' set part

std::size_t offset = 0;
for (std::size_t c = 0; c < contributors_.size(); ++c) {
Array tmp(guessSizes[c]);
std::copy(std::next(x.begin(), offset), std::next(x.begin(), offset + guessSizes[c]),
tmp.begin());
offset += guessSizes[c];
contributors_[c]->setCostFunctionArgument(tmp);
}

// update observers
for(auto o: observers_)
o->update();

// collect the contributors' result

std::vector<Array> results;
for (std::size_t c = 0; c < contributors_.size(); ++c) {
results.push_back(contributors_[c]->evaluateCostFunction());
}

// concatenate the contributors' values and return the concatenation as the result

std::size_t resultSize =
std::accumulate(results.begin(), results.end(), 0,
[](std::size_t len, const Array& a) { return len + a.size(); });

Array result(resultSize);

offset = 0;
for (auto const& r : results) {
std::copy(r.begin(), r.end(), std::next(result.begin(), offset));
offset += r.size();
}

return result;
};

SimpleCostFunction<decltype(fn)> costFunction(fn);
NoConstraint noConstraint;
Problem problem(costFunction, noConstraint, Array(globalGuess.begin(), globalGuess.end()));
EndCriteria::Type endType = optimizer_->minimize(problem, *endCriteria_);

QL_REQUIRE(
EndCriteria::succeeded(endType),
"global bootstrap failed to minimize to required accuracy (during multi curve bootstrap): "
<< endType);

// set all contributors to valid

for (auto const& c : contributors_)
c->setToValid();
}

} // namespace QuantLib
Loading
Loading