Yield Curve Interpolation - Bug?

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

Yield Curve Interpolation - Bug?

tibbar
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;
}
Reply | Threaded
Open this post in threaded view
|

Re: Yield Curve Interpolation - Bug?

tibbar
Here's a clearer example of the problem, I define the yield curve at annual time steps:

        yields[1] = 0.0893727967169871;
        yields[2] = 0.086377894489778;
        yields[3] = 0.0841863387143875;
        yields[4] = 0.0825155280329219;
        yields[5] = 0.0811998450966198;
        yields[6] = 0.0801347312848162;
        yields[7] = 0.0792493969517147;
        yields[8] = 0.0784929297115653;
        yields[9] = 0.0778267213311277;
        yields[10] = 0.0772200058164414;
        yields[11] = 0.0766470376491981;
        yields[12] = 0.0760852185842174;
        yields[13] = 0.0755138450448589;
        yields[14] = 0.074913330611911;
        yields[15] = 0.0742648573325628;
        yields[16] = 0.0735504618545535;
        yields[17] = 0.0727535743827794;

and the interpolated yield curve comes out as:

Time 1 discount factor 0.0893728
Time 2 discount factor 0.0863779
Time 3 discount factor 0.0841863
Time 4 discount factor 0.0825119
Time 5 discount factor 0.0811969
Time 6 discount factor 0.0801323
Time 7 discount factor 0.0792473
Time 8 discount factor 0.0784892
Time 9 discount factor 0.0778233
Time 10 discount factor 0.0772168
Time 11 discount factor 0.0766439
Time 12 discount factor 0.0760805
Time 13 discount factor 0.0755088
Time 14 discount factor 0.0749079
Time 15 discount factor 0.0742589
Time 16 discount factor 0.0735416
Time 17 discount factor 0.0727436

These are close but there is no reason I can see why they differ to the input rates.  Does anyone know what is going wrong here?

The program is:

#include <ql/quantlib.hpp>
#include <vector>
#include <math.h>
#include <iomanip>
#include <iostream>
#include <boost/timer.hpp>

using namespace std;
using namespace QuantLib;


int main(int, char* [])
{
        // define yield curve
        double yields[19];
        yields[0] = 0.;
        yields[1] = 0.0893727967169871;
        yields[2] = 0.086377894489778;
        yields[3] = 0.0841863387143875;
        yields[4] = 0.0825155280329219;
        yields[5] = 0.0811998450966198;
        yields[6] = 0.0801347312848162;
        yields[7] = 0.0792493969517147;
        yields[8] = 0.0784929297115653;
        yields[9] = 0.0778267213311277;
        yields[10] = 0.0772200058164414;
        yields[11] = 0.0766470376491981;
        yields[12] = 0.0760852185842174;
        yields[13] = 0.0755138450448589;
        yields[14] = 0.074913330611911;
        yields[15] = 0.0742648573325628;
        yields[16] = 0.0735504618545535;
        yields[17] = 0.0727535743827794;
        yields[18] = 0.07185999353355;

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

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

    for(int i = 0; i < 19; 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;
}


tibbar wrote
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;
}
Reply | Threaded
Open this post in threaded view
|

Re: Yield Curve Interpolation - Bug?

Luigi Ballabio
On Tue, 2008-03-18 at 15:23 -0700, tibbar wrote:

> DayCounter dayCount = SimpleDayCounter();
>
> for(int i = 1; i <= 17; i++){
> Real interestRate = termStructure->zeroRate((Real) i, Compounded);
> cout << "Time " << i << " discount factor " << interestRate << '\n';
> }

Tibbar,
        you'll probably need to use Actual365Fixed() as the day count,
otherwise the date today+365*i won't correspond to the time (Real) i.

Luigi


--

Newton's Law of Gravitation:
What goes up must come down. But don't expect it to come down
where you can find it. Murphy's Law applies to Newton's.



-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
QuantLib-users mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/quantlib-users