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"); } } |
On 08/26/2005 08:46:56 AM, Aurelien Chanudet wrote:
> 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. You're right. I applied your patch to the repository. Thanks, Luigi ---------------------------------------- Flon's Law: There is not now, and never will be, a language in which it is the least bit difficult to write bad programs. |
Free forum by Nabble | Edit this page |