24#ifndef quantlib_local_bootstrap_hpp
25#define quantlib_local_bootstrap_hpp
39 template <
class Curve>
41 typedef typename Curve::traits_type
Traits;
42 typedef typename Traits::helper
helper;
44 typename std::vector< ext::shared_ptr<helper> >::const_iterator
84 template <
class Curve>
86 typedef typename Curve::traits_type
Traits;
90 bool forcePositive =
true,
92 void setup(Curve* ts);
107 template <
class Curve>
109 : ts_(nullptr), localisation_(localisation), forcePositive_(forcePositive),
110 accuracy_(accuracy) {}
112 template <
class Curve>
117 Size n = ts_->instruments_.size();
119 "not enough instruments: " <<
n <<
" provided, " <<
120 Interpolator::requiredPoints <<
" required");
123 "not enough instruments: " <<
n <<
" provided, " <<
124 localisation_ <<
" required.");
126 for (
Size i=0; i<
n; ++i){
127 ts_->registerWithObservables(ts_->instruments_[i]);
131 template <
class Curve>
135 Size nInsts = ts_->instruments_.size();
138 std::sort(ts_->instruments_.begin(), ts_->instruments_.end(),
142 for (
Size i=1; i<nInsts; ++i) {
143 Date m1 = ts_->instruments_[i-1]->pillarDate(),
144 m2 = ts_->instruments_[i]->pillarDate();
146 "two instruments have the same pillar date ("<<m1<<
")");
150 for (
Size i=0; i<nInsts; ++i)
151 QL_REQUIRE(ts_->instruments_[i]->quote()->isValid(),
153 ts_->instruments_[i]->maturityDate() <<
", pillar: " <<
154 ts_->instruments_[i]->pillarDate() <<
155 ") has an invalid quote");
158 for (
Size i=0; i<nInsts; ++i) {
162 ts_->instruments_[i]->setTermStructure(
const_cast<Curve*
>(ts_));
167 "dimension mismatch: expected " << nInsts+1 <<
168 ", actual " << ts_->data_.size());
170 ts_->data_ = std::vector<Rate>(nInsts+1);
171 ts_->data_[0] = Traits::initialValue(ts_);
175 ts_->dates_ = std::vector<Date>(nInsts+1);
176 ts_->times_ = std::vector<Time>(nInsts+1);
177 ts_->dates_[0] = Traits::initialDate(ts_);
178 ts_->times_[0] = ts_->timeFromReference(ts_->dates_[0]);
179 for (
Size i=0; i<nInsts; ++i) {
180 ts_->dates_[i+1] = ts_->instruments_[i]->pillarDate();
181 ts_->times_[i+1] = ts_->timeFromReference(ts_->dates_[i+1]);
183 ts_->data_[i+1] = ts_->data_[i];
186 Real accuracy = accuracy_ !=
Null<Real>() ? accuracy_ : ts_->accuracy_;
191 EndCriteria endCriteria(100, 10, 0.00, accuracy, 0.00);
194 Constraint& solverConstraint = forcePositive_ ?
199 Size iInst = localisation_-1;
201 Size dataAdjust = Curve::interpolator_type::dataSizeAdjustment;
204 Size initialDataPt = iInst+1-localisation_+dataAdjust;
205 Array startArray(localisation_+1-dataAdjust);
206 for (
Size j = 0; j < startArray.
size()-1; ++j)
207 startArray[j] = ts_->
data_[initialDataPt+j];
216 ts_->interpolation_ =
217 ts_->interpolator_.localInterpolate(
219 ts_->times_.begin()+(iInst + 2),
225 if (iInst >= localisation_) {
226 startArray[localisation_-dataAdjust] =
227 Traits::guess(iInst, ts_,
false, 0);
229 startArray[localisation_-dataAdjust] = ts_->
data_[0];
235 ts_->instruments_.begin() + ((iInst+1) - localisation_),
236 ts_->instruments_.begin() + (iInst+1));
238 Problem toSolve(currentCost, solverConstraint, startArray);
245 "Unable to strip yieldcurve to required accuracy " );
247 }
while ( iInst < nInsts );
252 template <
class Curve>
254 Size i = initialIndex_;
256 while (guessIt != x.
end()) {
257 Traits::updateGuess(
curve_->data_, *guessIt, i);
266 while (instIt != rateHelpersEnd_) {
267 Real quoteError = (*instIt)->quoteError();
268 penalty += std::fabs(quoteError);
274 template <
class Curve>
277 Size i = initialIndex_;
278 while (guessIt != x.
end()) {
279 Traits::updateGuess(
curve_->data_, *guessIt, i);
286 Array penalties(localisation_);
289 while (instIt != rateHelpersEnd_) {
290 Real quoteError = (*instIt)->quoteError();
291 *penIt = std::fabs(quoteError);
Armijo line-search class.
base helper class used for bootstrapping
ZeroSpreadedTermStructure curve_
1-D array used in linear algebra.
const Real * const_iterator
std::unique_ptr< Real[]> data_
const_iterator end() const
Size size() const
dimension of the array
const_iterator begin() const
Cost function abstract class for optimization problem.
Criteria to end optimization process:
@ StationaryFunctionValue
@ StationaryFunctionAccuracy
Levenberg-Marquardt optimization method.
EndCriteria::Type minimize(Problem &P, const EndCriteria &endCriteria) override
minimize the optimization problem P
Localised-term-structure bootstrapper for most curve types.
LocalBootstrap(Size localisation=2, bool forcePositive=true, Real accuracy=Null< Real >())
Curve::interpolator_type Interpolator
Curve::traits_type Traits
template class providing a null value for a given type.
std::vector< ext::shared_ptr< helper > >::const_iterator helper_iterator
Real value(const Array &x) const override
method to overload to compute the cost function value in x
helper_iterator rateHelpersEnd_
helper_iterator rateHelpersStart_
Curve::traits_type Traits
PenaltyFunction(Curve *curve, Size initialIndex, helper_iterator rateHelpersStart, helper_iterator rateHelpersEnd)
Array values(const Array &x) const override
method to overload to compute the cost function values in x
Constraint imposing positivity to all arguments
Constrained optimization problem.
Abstract constraint class.
Optimization cost function class.
#define QL_ENSURE(condition, message)
throw an error if the given post-condition is not verified
#define QL_REQUIRE(condition, message)
throw an error if the given pre-condition is not verified
detail::ordinal_holder ordinal(Size)
outputs naturals as 1st, 2nd, 3rd...
std::size_t Size
size of a container
Levenberg-Marquardt optimization method.
Abstract optimization problem class.
Maps shared_ptr to either the boost or std implementation.