Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
60f9172
add multicurve bootstrap
pcaspers Oct 11, 2025
bd1eaf8
update msvc files
pcaspers Oct 11, 2025
654f421
fix
pcaspers Oct 12, 2025
e4df62a
remove debug output
pcaspers Oct 12, 2025
d7f10e5
make ctor explicit
pcaspers Oct 12, 2025
70d83d5
add inspector
pcaspers Oct 25, 2025
126d40f
simplify
pcaspers Oct 25, 2025
0443b4e
add multicurve
pcaspers Oct 25, 2025
aa33668
add unit test
pcaspers Oct 25, 2025
56adfa9
init members
pcaspers Oct 25, 2025
b6f3538
should be explicit
pcaspers Oct 25, 2025
41f0b95
fix test setup
pcaspers Oct 25, 2025
c2e2f07
make class final
pcaspers Oct 26, 2025
e25269b
merge setupCostFunction() and guess() into one method
pcaspers Oct 26, 2025
c698c94
tbd, simplify interface, but undefined behavior possible
pcaspers Oct 26, 2025
4a2638b
use dynamic cast
pcaspers Oct 28, 2025
ea31f6d
simplify observability
pcaspers Oct 28, 2025
e3966ee
fix
pcaspers Oct 29, 2025
21808cd
not needed
pcaspers Oct 29, 2025
a8095fd
do we need this?
pcaspers Oct 29, 2025
f6e7a59
attempt to resolve compile and weak_ptr issues
pcaspers Oct 29, 2025
c3e3fee
Revert "attempt to resolve compile and weak_ptr issues"
pcaspers Oct 29, 2025
d353587
back to original code, does the order matter?
pcaspers Oct 29, 2025
0497ccd
handle thread safe observer build
pcaspers Oct 29, 2025
139b5e3
Make safer
eltoder Oct 28, 2025
42bdd82
not needed any more
pcaspers Oct 29, 2025
1e8c557
allow to add observers to multicurve bootstrap
pcaspers Oct 30, 2025
262bce1
make MultiCurveBootstrap internal to MultiCurve
pcaspers Nov 23, 2025
03db67c
Simplify usage
eltoder Oct 28, 2025
330285f
handle case where base class enables shared from this
pcaspers Nov 23, 2025
2d71ab5
fix
pcaspers Nov 25, 2025
a9a3092
compile issue
pcaspers Nov 25, 2025
66b5513
add unit test for cycle of zero spreaded and pw curve
pcaspers Nov 29, 2025
9d2fe99
remove QuantLib namespace qualification
pcaspers Nov 29, 2025
04019bd
add non-pw curve
pcaspers Nov 29, 2025
ce8a571
Revert "Simplify usage"
pcaspers Nov 29, 2025
7358039
fix
pcaspers Nov 29, 2025
a806e43
formatting
pcaspers Nov 29, 2025
e103123
formatting
pcaspers Nov 29, 2025
a91e6dc
use rvalue ref
pcaspers Nov 29, 2025
20ab3cb
refactor and rename
pcaspers Nov 30, 2025
04d3317
udpate documentation
pcaspers Dec 1, 2025
313f6c3
improve doc
pcaspers Dec 1, 2025
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
117 changes: 117 additions & 0 deletions ql/termstructures/globalbootstrap.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
/* -*- 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)) {
constexpr Real accuracy = 1E-10;
if (optimizer_ == nullptr)
optimizer_ = ext::make_shared<LevenbergMarquardt>(accuracy, accuracy, accuracy);
if (endCriteria_ == nullptr)
endCriteria_ = ext::make_shared<EndCriteria>(1000, 10, accuracy, accuracy, accuracy);
}

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