Max date of a PiecewiseYieldCurve term structure
Posted by Aurelien Chanudet on Aug 26, 2005; 12:48am
URL: http://quantlib.414.s1.nabble.com/Max-date-of-a-PiecewiseYieldCurve-term-structure-tp10858.html
Hi,
It looks like the max date of a PiecewiseYieldCurve term structure
whose reference date depends on the global evaluation date isn't
properly updated when modifying the global evaluation date.
The reason for this is that the max date (dates_.back()) of such a
curve is set *before* the rate helpers get a chance to know about the
change of evaluation date. The following patch apparently fixes the
issue. This patch doesn't cause any error in the testsuite.
Is there something I'm overlooking ?
Cheers,
Aurelien
template <class C, class I>
void PiecewiseYieldCurve<C,I>::performCalculations() const {
// setup vectors
Size n = instruments_.size();
for (Size i=0 ; i < n ; i++) {
// don't try this at home!
instruments_[i]->setTermStructure(
const_cast<PiecewiseYieldCurve<C,I>*>(this));
}
this->dates_ = std::vector<Date>(n+1);
this->times_ = std::vector<Time>(n+1);
this->data_ = std::vector<Real>(n+1);
this->dates_[0] = this->referenceDate();
this->times_[0] = 0.0;
this->data_[0] = C::initialValue();
for (Size i=0; i<n; i++) {
this->dates_[i+1] = instruments_[i]->latestDate();
this->times_[i+1] = this->timeFromReference(this->dates_[i+1]);
this->data_[i+1] = this->data_[i];
}
Brent solver;
Size maxIterations = 25;
// bootstrapping loop
for (Size iteration = 0; ; iteration++) {
std::vector<Real> previousData = this->data_;
Size i;
for (i=1; i<n+1; i++) {
if (iteration == 0) {
// extend interpolation a point at a time
if (I::global && i < 2) {
// not enough points for splines
this->interpolation_ = Linear().interpolate(
this->times_.begin(),
this->times_.begin()+i+1,
this->data_.begin());
} else {
this->interpolation_ = this->interpolator_.interpolate(
this->times_.begin(),
this->times_.begin()+i+1,
this->data_.begin());
}
}
boost::shared_ptr<RateHelper> instrument = instruments_[i-1];
// don't try this at home!
// instrument->setTermStructure(
//
const_cast<PiecewiseYieldCurve<C,I>*>(this));
Real guess;
if (iteration > 0) {
// use perturbed value from previous loop
guess = 0.99*this->data_[i];
} else if (i > 1) {
// extrapolate
guess = C::guess(this,this->dates_[i]);
} else {
guess = C::initialGuess();
}
// bracket
Real min = C::minValueAfter(i, this->data_);
Real max = C::maxValueAfter(i, this->data_);
if (guess <= min || guess >= max)
guess = (min+max)/2.0;
this->data_[i] =
solver.solve(ObjectiveFunction(this,instrument,i),
accuracy_,guess,min,max);
}
// check exit conditions
if (!I::global)
break; // no need for convergence loop
Real improvement = 0.0;
for (i=1; i<n+1; i++)
improvement += std::abs(this->data_[i]-previousData[i]);
if (improvement <= n*accuracy_) // convergence reached
break;
if (iteration > maxIterations)
QL_FAIL("convergence not reached after "
<< maxIterations << " iterations");
}
}