Max date of a PiecewiseYieldCurve term structure

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

Max date of a PiecewiseYieldCurve term structure

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


Reply | Threaded
Open this post in threaded view
|

Re: Max date of a PiecewiseYieldCurve term structure

Luigi Ballabio
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.