Login  Register

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");
        }
    }