In a previous post I discussed the abstract class `TermStructure`

that defines methods common to any kind of term structure. It was pointed out that many classes inherit from the `TermStructure`

class, including a class called `YieldTermStructure`

. This class is, again, an abstract class and it defines the base for any yield curves. A yield curve is defined by a list of quotes together with a list of jump dates. These are passed to `YieldTermStructure`

in the constructor and are then stored internally. There are three different constructors which correspond to the three constructors defined in `TermStructure`

.

YieldTermStructure( const DayCounter& dc = DayCounter(), const std::vector<Handle<Quote> >& jumps = std::vector<Handle<Quote> >(), const std::vector<Date>& jumpDates = std::vector<Date>()); YieldTermStructure( const Date& referenceDate, const Calendar& cal = Calendar(), const DayCounter& dc = DayCounter(), const std::vector<Handle<Quote> >& jumps = std::vector<Handle<Quote> >(), const std::vector<Date>& jumpDates = std::vector<Date>()); YieldTermStructure(Natural settlementDays, const Calendar& cal, const DayCounter& dc = DayCounter(), const std::vector<Handle<Quote> >& jumps = std::vector<Handle<Quote> >(), const std::vector<Date>& jumpDates = std::vector<Date>());

All three constructors take two additional arguments, a `std::vector`

of `Quote`

handles and a `std::vector`

of jump dates. These two vectors define the data for the interest rate term structure. If the `jumpDates`

array is left empty, the jumps are assumed to occur annually at 31 Dec every year, starting in the year of the reference date. For the meaning of the remaining arguments and the difference between the constructors, see the documentation of the TermStructure class.

Two inspector methods give access to the jump dates.

const std::vector<Date>& jumpDates() const; const std::vector<Time>& jumpTimes() const;

The method `jumpDates`

returns vector of Date objects while `jumpTimes`

returns a vector of times. Recall that `Time`

is just a `Real`

number. Times are expressed in fractions of a year from the reference date and are evaluated using the day counter. They are calculated using the `timeFromReference`

method of `TermStructure`

.

`YieldTermStructure`

also overrides the `update`

method that it inherited from the Observer interface. Whenever the reference date changes, the jump times have to be recalculated.

Two methods return the discount factor from an arbitrary date to the reference date.

DiscountFactor discount(const Date& d, bool extrapolate = false) const; DiscountFactor discount(Time t, bool extrapolate = false) const;

The two methods differ in the way that the date is passed to them. The first version takes a date, while the second version takes a time measured in fractions of a year. This time should be calculated using the same day counting convention that is used in the `YieldTermStructure`

. In fact, the first method is just a convenience method which converts the `Date`

into `Time`

using `TermStrucure::timeFromReference`

and then calls the second version of the `discount`

method.

The discount is calculated by multiplying all the jumps that fall in the period from the reference date to the date passed to the discount() method and then multiplying this with the result of `discountImpl`

, discussed later. The `extrapolate`

flag indicates whether the discount factor should be extrapolated if it falls outside of the date range of the term structure.

The `discount`

method is used internally in a number of convenience methods. `zeroRate`

calculates the implied zero-coupon interest rate for a given time interval.

InterestRate zeroRate(const Date& d, const DayCounter& resultDayCounter, Compounding comp, Frequency freq = Annual, bool extrapolate = false) const; InterestRate zeroRate(Time t, Compounding comp, Frequency freq = Annual, bool extrapolate = false) const;

As before, the two methods differ in the way that the date is passed to them. The first version takes a specific date. This version allows passing a different day counter than the one used in the term structure. The `InterestRate`

that is returned uses the new day counter, compounding rule and frequency. The second version takes a time interval which has to be calculated using the same day counter as the one used in `YieldTermStructure`

. Internally, both methods first calculate the compound rate as the reciprocal of the discount rate, *a=1/d*. Then an `InterestRate`

is generated by calling `InterestRate::impliedRate()`

with the correct arguments. The extrapolate flag indicates whether the discount factor should be extrapolated for dates outside of the term structure’s range.

The implied forward rates can be obtained in a similar way.

InterestRate forwardRate(const Date& d1, const Date& d2, const DayCounter& resultDayCounter, Compounding comp, Frequency freq = Annual, bool extrapolate = false) const; InterestRate forwardRate(const Date& d, const Period& p, const DayCounter& resultDayCounter, Compounding comp, Frequency freq = Annual, bool extrapolate = false) const; InterestRate forwardRate(Time t1, Time t2, Compounding comp, Frequency freq = Annual, bool extrapolate = false) const;

For the forward rate there are three methods available, each taking the time interval in a different form. It can be given by two dates, by a date and a time period, or by two floating point numbers representing the time intervals. The behaviour is equivalent to the `zeroRate`

methods. For the first two methods, a separate day counter can be specified for the resulting `InterestRate`

. For the last version, the day counter of the term structure is used.

The forward rate is evaluated by calculating a compound rate using the ratio of the two discount rates, *a=d _{1}/d_{2}*. The interest rate is then generated by calling

`InterestRate::impliedRate()`

with the compound rate.As promised above, I have to now talk about the actual implementation of the discount factor calculation. This should be handled in the method `discountImpl`

which is declared abstract.

virtual DiscountFactor discountImpl(Time) const = 0;

Any concrete implementation of `YieldTermStructure`

must implement this method and return the discount factor for a specific time. When discountImpl() is called, the conversions from dates to units of time has already been done. The `enabled`

flag that was passed to the `discount`

method has been checked. This means that `discountImpl`

must assume that the discount factor has to be extrapolated if the time does not fall within the time for which the term structure can return values, i.e. if it is larger than the value returned by `maxTime`

.

Follow the author