Yield Curve Interpolation - Bug?

Posted by tibbar on
URL: http://quantlib.414.s1.nabble.com/Yield-Curve-Interpolation-Bug-tp5822.html

I'm passing quantlib the following yield curve (annual compounded)

t Yield
overnight 0.081
1 0.089372797
2 0.086377894
3 0.084186339
4 0.082515528
5 0.081199845
6 0.080134731
7 0.079249397
8 0.07849293
9 0.077826721
10 0.077220006
11 0.076647038
12 0.076085219
13 0.075513845
14 0.074913331
15 0.074264857
16 0.073550462
17 0.072753574
18 0.071859994
19 0.070859193

This is passed into quantlib at quarterly time points, with mid-year values interpolated already, but quarterly time points set to zero (I know this is wrong, but this is how the data arrived, and I'm only interested in using the yield curve at half yearly points in this example).

Now, my program is returning the wrong values for the yield curve after time 3:

C:\QuantLib-0.8.1\yieldCurveExample\DebugExe>yieldCurveExample.exe
Time 1 discount factor 0.0893728
Time 2 discount factor 0.0863779
Time 3 discount factor 0.0841863
Time 4 discount factor 0.0815516
Time 5 discount factor 0.0802518
Time 6 discount factor 0.0791996
Time 7 discount factor 0.078325
Time 8 discount factor 0.0766631
Time 9 discount factor 0.076013
Time 10 discount factor 0.0754209
Time 11 discount factor 0.0748617
Time 12 discount factor 0.0734287
Time 13 discount factor 0.0728779
Time 14 discount factor 0.072299
Time 15 discount factor 0.0716739
Time 16 discount factor 0.0701316
Time 17 discount factor 0.0693729

This is implemented in the following program.  Any ideas what's going wrong here??

int main()
{
        // define yield curve
        double yields[73];

        yields[0] = 0.081; // overnight rate
        yields[1] = 0.; // t = 0.25
        yields[2] = 0.; // t = 0.5
        yields[3] = 0.; // t = 0.75
        yields[4] = 0.0893727967169871; // t = 1
        yields[5] = 0.; // t = 1.25 etc...
        yields[6] = 0.0878753456033826;
        yields[7] = 0.;
        yields[8] = 0.086377894489778;
        yields[9] = 0.;
        yields[10] = 0.0852821166020828;
        yields[11] = 0.;
        yields[12] = 0.0841863387143875;
        yields[13] = 0.;
        yields[14] = 0.0833509333736547;
        yields[15] = 0.;
        yields[16] = 0.0825155280329219;
        yields[17] = 0.;
        yields[18] = 0.0818576865647709;
        yields[19] = 0.;
        yields[20] = 0.0811998450966198;
        yields[21] = 0.;
        yields[22] = 0.080667288190718;
        yields[23] = 0.;
        yields[24] = 0.0801347312848162;
        yields[25] = 0.;
        yields[26] = 0.0796920641182655;
        yields[27] = 0.;
        yields[28] = 0.0792493969517147;
        yields[29] = 0.;
        yields[30] = 0.07887116333164;
        yields[31] = 0.;
        yields[32] = 0.0784929297115653;
        yields[33] = 0.;
        yields[34] = 0.0781598255213465;
        yields[35] = 0.;
        yields[36] = 0.0778267213311277;
        yields[37] = 0.;
        yields[38] = 0.0775233635737845;
        yields[39] = 0.;
        yields[40] = 0.0772200058164414;
        yields[41] = 0.;
        yields[42] = 0.0769335217328198;
        yields[43] = 0.;
        yields[44] = 0.0766470376491981;
        yields[45] = 0.;
        yields[46] = 0.0763661281167078;
        yields[47] = 0.;
        yields[48] = 0.0760852185842174;
        yields[49] = 0.;
        yields[50] = 0.0757995318145382;
        yields[51] = 0.;
        yields[52] = 0.0755138450448589;
        yields[53] = 0.;
        yields[54] = 0.0752135878283849;
        yields[55] = 0.;
        yields[56] = 0.074913330611911;
        yields[57] = 0.;
        yields[58] = 0.0745890939722369;
        yields[59] = 0.;
        yields[60] = 0.0742648573325628;
        yields[61] = 0.;
        yields[62] = 0.0739076595935581;
        yields[63] = 0.;
        yields[64] = 0.0735504618545535;
        yields[65] = 0.;
        yields[66] = 0.0731520181186665;
        yields[67] = 0.;
        yields[68] = 0.0727535743827794;
        yields[69] = 0.;
        yields[70] = 0.0723067839581647;
        yields[71] = 0.;
        yields[72] = 0.07185999353355;

        // set up interest rate points
    std::vector<Real> riskFree;
    std::vector<int> riskFreeDays;
       
        riskFree.push_back(log(1.));
        riskFreeDays.push_back(0);
    for(int i = 1; i < 73; i++){
            riskFree.push_back(log(1 + yields[i]));
            riskFreeDays.push_back(365 * i / 4 );
    }

    std::vector<Date> dates;
        Calendar calendar = NullCalendar();
        Date today = calendar.adjust(Date::todaysDate());

    for(int i = 0; i < 73; i++)
            dates.push_back(today + riskFreeDays.at(i));

        DayCounter dayCount = SimpleDayCounter();
       
    //figures out yield curve, uses linear fit
   
    Handle<YieldTermStructure> termStructure (boost::shared_ptr<YieldTermStructure>(new InterpolatedZeroCurve<Linear>(dates, riskFree, dayCount)));
       
        for(int i = 1; i <= 17; i++){
                Real interestRate = termStructure->zeroRate((Real) i, Compounded);
                cout << "Time " << i << " discount factor " << interestRate << '\n';
        }
        return 0;
}