• No results found

Interest Rate Modeling: A Matlab Implementation

N/A
N/A
Protected

Academic year: 2021

Share "Interest Rate Modeling: A Matlab Implementation"

Copied!
41
0
0

Loading.... (view fulltext now)

Full text

(1)

Quaderni SEMeQ

Quaderno n. 13/2007

Daniele Marazzina

Interest Rate Modelling: A MATLAB

Implementation

(2)

Stampato in proprio presso la Segreteria del Dipartimento di Scienze Economiche e

Metodi Quantitativi, Università degli Studi del Piemonte Orientale “A. Avogadro”

I Lavori pubblicati nella collana riflettono esclusivamente le opinioni degli autori e

non impegnano la responsabilità del Dipartimento SEMeQ.

Dipartimento di Scienze Economiche e Metodi Quantitativi

Via E. Perrone 18 – 28100 Novara

Tel. 39 (0) 321- 375310 Fax 39 (0) 321 - 375305

e-mail: [email protected]

(3)

Interest Rate Modeling: A M

ATLAB

Implementation

Daniele Marazzina

SEMeQ Department, Università del Piemonte Orientale Via Perrone 18, 28100 Novara, Italy

e-mail: [email protected] Avanade Italy

Corso Venezia 46, 20121 Milano, Italy e-mail: [email protected]

Abstract

The aim of this work is to present a MATLABimplementation of different methods for estimating the term structure of interest rate. More precisely, we implement the exponential functional form of Nelson-Siegel and polynomial spline methods (with or without penalty term), considering both coupon bonds, like Italian Btp, and Libor and Swap interest rates. Furthermore, we compare the models’performances, considering both computational costs and approximation results.

1

Introduction

An important tool in the development and testing of financial theory is the term structure of interest rate as it provides a characterization of interest rates as a function of maturity. The yield curve, or term structure of interest rate, is the set of interest rates for different investment periods or maturities. Yield curve can display a wide variety of shapes. Typically, a yield curve will slope upwards, with longer term rates being higher, although there are plenty of examples of inverted term structures where long rates are less then short rates.

In the bond markets the yield curve is found from bond data, while in the money market the yield curve is derived from the prices of a variety of different types of instrument. Cash rates provide information about the short term rates, from one week to about 18 months. These are investments or borrowings where the entire sum of interest plus principal is due at the end of the period, with no interim payments. After about two-year point, Swaps become the dominant instrument: from there it is possible to derive the yield curve until 15-year point. After that, bond can be used. See [5] for further details.

Information about the yield curve becomes steadily more sparse as the maturity increases. A good interest rate curve is the most basic requirement for pricing interest rate derivatives: if the curve is bad, the prices it returns will be bad (see [1]). The objective in empirical fitting of the term structure is to find a curve that fits the data sufficiently well and it is a sufficiently smooth function: the second requirement is at least as important as the first, even if it is less quantifiable (see, for example, [12]).

In this paper we consider the methodology of fitting the discount function d (or related function, as, for example, the instantaneous forward rate function) by the exponential model of Nelson-Siegel (see [9] and [11]) and polynomial spline methods (see [6] and [7]) with or without penalty term (see [2] and [4]). Moreover, we consider a MATLAB[13] code written for both Italian Btp data and Libor and Swap data in order to obtain the curves.

The outline of the paper is the following: in Section 2 we describe how we can extract the necessary data from coupon bonds and Libor and Swap rates; in Section 3 we introduce the data-fitting techniques: more precisely, we describe the Nelson-Siegel model and some methods based on cubic spline. In Sec-tion 4 we explain how our MATLAB code works using the theoretical results introduced in the previous

(4)

sections. Finally, Section 5 deals with the models’performances, considering both computational cost and approximation results.

2

The Discount Function

The term structure of interest rate can be identified with any of a number of related concepts. In this section we consider the discount function d(t), which describes the present value of 1 Euro repayable in t years. The aim of the algorithm described in this paper is to extract the term structure from a set of coupon bonds (such as the Italian Btp considered), whose prices are largely determined by the present value of their stated payments (see [2]), or a set of Libor and Swap rates. More precisely, in this section we show a way to obtain the values of the discount function at the payments’dates for both kind of data. For further details, see the examples reported in Appendix A.

2.1

Coupon Bonds

Following [2] and [8], let P (i) be the price of a coupon bond i at a fixed date t (value date) and A(i, j) be its jthpayment made at time BP (i, j); moreover, let m

ibe the number of remaining payments for the

bond i and n be the number of bonds. Then, if we set for i = 1, · · · , n and j = 1, · · · , mi

T (i, j) := α0[t, BP (i, j)],

where α0[t1, t2] is the distance between the two dates t1 and t2, computed according to the actual/365

day-count convention (i.e., the day-count convention for bonds), we have P (i) =

mi

X

j=1

A(i, j)d(T (i, j)) ∀ i = 1, · · · , n. (1) Since the coupon bond i is characterized by a periodic coupon Ciand a facial value Fi, we set

(

A(i, j) = Ci if j < mi

A(i, j) = Ci+ Fi if j = mi,

for i = 1, · · · , n. For simplicity, in this paper we consider coupons paid every six months (semi-annual coupons) and we define Ci = bCi/2, where bCiis the annual payment for the bond i, i = 1, · · · , n.

If we now define T T as the vector containing all the elements of T , sorted in ascending order, and we define the matrix AA such that AA(i, j) is the payment of the bond i at time T T (j) (thus it could be equal to 0 if T T (j) is not a time to payment for the considered bond), then (1) becomes

AA D = P , (2) where D(i) = d(T T (i)), i = 0, · · · , m, and m is the number of elements of T T (i.e., the number of the global payment times).

Considering the bond i, i = 1, · · · , n, its price P (i) (i.e., the price that purchaser pays when buying the bond) is equal to the quoted price (clean price) plus the accrued interest AI (i.e., the interest accumulated between the most recent interest payment and the present time). In order to compute AI, let t−1be the date

of the previous coupon payment, t be the value date and t1be the date of the next coupon payment, then

the accrued interest is

AI = Cbi 2 α0[t−1, t] α0[t−1, t1] = Ci α0[t−1, t] α0[t−1, t1] .

(5)

2.2

Libor and Swap Rates

First of all we consider Libor (London Interbank Offered Rate) rates, which are daily reference rates based on the interest rates at which banks offer to lend funds to other banks.

Let n1be the number of Libors considered, LM be the vector containing the times to maturity of the n1

Libors and LR(i) be the interest rate of the Libor with time to maturity LM (i), i = 1, · · · , n1: this means

that 1 Euro bought at time t (i.e., the value date) gives

1 + LR(i) α1[t, LP (i)]

Euros at time LP (i), where:

• LP (i) is the payment date, i.e., LP (i) = t + LM (i) if it is a business day, otherwise LP (i) is the first business day after t + LM (i);

• α1[t1, t2] is the distance between the two dates t1 and t2, computed according to the actual/360

day-count convention, (i.e., the day-count convention for Libors). Thus, if we set T1(i) := α1[t, LP (i)], we have d(T1(i)) = 1 1 + LR(i) α1[t, LP (i)] = 1 1 + LR(i) T1(i) , and so, reasoning as in the previous subsection, if we define for each Libor rate i

A1(i) = 1 + LR(i) T1(i),

P1(i) = 1,

we obtain

A1(i) d(T1(i)) = P1(i) ∀ i = 1, · · · , n1. (3)

Now we consider Swaps, which are agreement to exchange one set of cash flow for another. The most commonly traded Swap requires one side to pay a fixed rate and the other to pay a floating rate. In order to derive the discount function from Swap rates, we suppose that they have cash flow at one-year intervals. Let t be the value date, SR(i) be the interest rate of the Swap with expiration at i years and SP (i, j), with 0 < j ≤ i, be its jthpayment date; we define

T2(i, j) := α2[t, SP (i, j)],

where α2[t1, t2] is the distance between the two dates t1and t2, computed according to the 30/360

day-count convention (i.e., the day-day-count convention for Swaps considering the Euro market). Thus, following [5], we have

d(T2(i)) =

1 − SR(i)Pi−1

j=1[T2(i, j) − T2(i, j − 1)] d(T2(i, j))

1 + SR(i) [T2(i) − T2(i, i − 1)]

(6)

where n2 is the maximum expiration time of the Swap considered and we have set T2(i, 0) = 0 and

T2(i) := T2(i, i), i.e., its time to maturity.

If we define for i = 1, · · · , n2

A2(i, j) = SR(i) [T2(i, j) − T2(i, j − 1)] if j < i,

A2(i, i) = 1 + SR(i) [T2(i) − T2(i, i − 1)],

P2(i) = 1,

then (4) is equivalent to

i

X

j=1

A2(i, j) d(T2(i, j)) = P2(i) ∀ i = 1, · · · , n2. (5)

It is easy to see that in order to use equations (4) and (5) it is necessary to know each Swap rates with expi-ration from 1 to n2years. If it is not possible, we obtain the missing Swap rates using linear interpolation,

i.e., if we suppose that the values of SR(i − 1) and SR(i + 1) are known, while SR(i) is unknown, we set

SR(i) = SR(i − 1) + SR(i + 1) 2 .

See the MATLABroutineMISSING_SWAPin Section 4.1 for further details and [1] for other interpolation techniques.

Reasoning as above, if we now define n as the total number of financial instruments considered (i.e., n = n1+ n2), T T as the vector containing all the times to payment of both the Libor and the Swap rates

(i.e., all the elements T1(l), l = 1, · · · , n1and T2(i, j), i = 1, · · · , n2, j = 1, · · · , i, sorted in ascending

order), we can define

• AA(i, j) = A1(i) if i ≤ n1and T T (j) = T1(i),

• AA(i, j) = A2(i − n1, p) if i > n1and T T (j) = T2(i − n1, p),

• P (i) = P1(i) if i ≤ n1,

• P (i) = P2(i − n1) if i > n1,

for i = 0, · · · , n, j = 1, · · · , m, where m is the size of T T , i.e., the number of payment dates, and p = 1, · · · , n2.

Thus equations (3) and (5) become

AA D = P , (6) where D(i) = d(T T (i)), i = 0, · · · , n.

Notice that equation (2) (i.e., the coupon bonds case) and equation (6) (i.e., the Libor and Swap rates case) are of the same type. Thus we will consider their resolution through a fitting procedure without any distinction between the kind of data considered.

3

The Fitting Procedure

The aim of this section is to introduce the data-fitting techniques: we start with the Nelson-Siegel model, introduced in [9], then we present six models related with the cubic spline method.

(7)

3.1

Nelson-Siegel Model

The Nelson-Siegel model uses a single exponential functional form over the entire maturity range (see [8]). The discount function associated with (1), (3) and (4) is given as

d(t) = e−α1t−β(α2+α3)(1−e−t/β)+α3te−t/β (7)

with the constraints

α1> 0, α1+ α2> 0, β > 0. (8)

Therefore, considering equations (2) and (6), we impose that

D(i) := d(T T (i)) = e−α1T T (i)−β(α2+α3)(1−e−T T (i)/β)+α3T T (i)e−T T (i)/β.

It is easy to understand that we are not sure that it is possible to find values of α1, α2, α3and β which

satisfies

AA D = P ;

thus the estimation of the discount function requires searching the unknown parameters Θ := {α1, α2, α3, β}

which minimize the sum of the squared errors, i.e., we consider the system AA D = P + E,

where E is the errors’vector (which depends on Θ) and we have to solve the following least square mini-mization problem:

min

Θ E

T

E. (9)

3.2

Cubic Spline Method

The term spline is used to refer to a wide class of functions that are used in applications requiring data interpolation and/or smoothing (see, for example, [10] for further details). Cubic splines are piecewise polynomial, joined at so-called knot points, characterized by the fact that their first and second derivatives are continuous functions.

A B-spline (or bell spline) is a spline function that has minimal support with respect to a given degree and domain partition; each spline function can be represented as a linear combination of B-splines of the same degree and over the same partition. In Figure 1 we show an example of B-spline basis function (see Appendix B and [2] for further details).

Following [2], we have implemented the term structure fitting techniques below. 3.2.1 B-spline

Let {φi}si=1 be the set of the B-spline basis functions; first of all we consider the case in which we

parametrize d as a cubic spline, i.e.,

d(τ ) =

s

X

i=1

(8)

Figure 1: 0 0.5 1 1.5 2 2.5 3 3.5 4 0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1

B−spline Basis Functions (Knot Points: 0; 2; 4)

φ1 φ2 φ3 φ4 φ5

Therefore, if we define for i = 1, · · · , m and j = 1, · · · , s G(i, j) = φj(T T (i)),

we obtain

D := G β, (10) where β = (β1, · · · , βs)T.

Then we consider the function

g(τ ) := −log(d(τ )) and we parametrize it as a cubic spline, i.e.,

g(τ ) = s X i=1 βiφi(τ ), As it holds d(τ ) = −eg(τ ), (11) we have D := −exp(G β), (12) where exp is the exponential function which operates element-wise on arrays.

Finally we consider the instantaneous forward rate function f (τ ) = − d

(9)

reasoning as above, it holds

d(τ ) = e−R0τf (t) dt. (13)

Thus, if we parametrize f as a cubic spline, i.e., f (τ ) =

s

X

i=1

βiφi(τ ),

and we define the matrix

IG(i, j) = Z T T (i) 0 φj(t) dt, then we have D := −exp(IG β). (14)

Reasoning as for the Nelson-Siegel model, the fitting procedure for the three cases above consists of solving the minimization problem associated to the following system

AA D = P + E,

i.e., since we have to search β which minimize ETE, we have to solve the least square minimization problem

min

β [(P − AA D)

T(P − AA D)]. (15)

3.2.2 B-spline with Penalty Term

In a spline the number of basis functions s is determined by the number of knot points: too few or too many parameters can lead to poor estimates. The strategy proposed in [2] is to penalize excess variability in the estimated discount function, reducing the effective number of parameters since the penalty forces implicit relationship between the spline basis functions.

If the domain of the spline is [0, T ], we define the penalty term H as the matrix of dimension s × s such that

H(i, j) = Z T

0

φ00i(t)φ00j(t) dt.

The minimization problem associated with the B-spline with penalty fitting technique is min

β [(P − AA D)

T(P − AA D) + λβTHβ],

(16) where λ is the penalty parameter (i.e., a positive real number) and D is defined as in (10), (12) or (14), depending on the function to be parametrized.

The penalty parameter λ controls the penalty matrix H; naturally, λ moves inversely to the effective number of parameters: the more λ becomes a large number, the more the penalty matrix H becomes important in (16). In order to choose the appropriate λ, we consider the value of λ which minimizes the so-called Generalized Cross Validation(GCV) function

γ(λ) := ((I − Q)Y )

T((I − Q)Y )

(10)

where

Q := X(XTX + λH)−1XT,

I is the s × s identity matrix, tr is the trace operator and X and Y are defined in Table 1. Table 1: Choice of X and Y (Xidenotes the ithrow of X)

Function to Parametrize W Xi Y

d - (AA G)i P

g AA exp(−G β) −W (i) (AA G)i P − W + X β

f AA exp(−IG β) −W (i) (AA IG)i P − W + X β

Intuitively, cross validation starts by looking at a leave-one-out estimator for each data point. If data is not scarce, then the set of available input-output measurements can be divided into two parts: one part for training and one part for testing. A better method, which is intended to avoid the possible bias introduced by relying on any particular division into test and train components, is to partition the original set in several different ways and to compute an average score over the different partitions. This is called “leave-one-out” cross-validation. The residual values from actual data point and the fitted data point from the “leave-one-out” estimation are averaged to construct the cross validation measure. With few parameters in the estimation the residual will tend to be large, due to a poor overall fit, while with an interpolant the perfect fit will tend to produce spurious movements and hence large out of sample residuals. Somewhere in between is the lowest value of the cross validation measure and thus the best estimate. See [2] for further details.

Notice that in Table 1 β is the solution of (16) and thus it depends also on λ: therefore, in the second and the third case (i.e., when we parametrize g or f ), in order to find the best λ we have to find β solving the minimization problem (16) at each step of the GCV-minimization procedure.

4

The M

ATLAB

Code

The aim of this section is to present our code; below we report the main file. For further information on the MATLABroutines used in the following code, such asFMINSEARCHorDAYSDIF, see Appendix C. function main(flag1,flag2)

% INPUT

% flag1: kind of data % flag1 = 0 -> Btp

% flag1 = 1 -> Swap + Libor %

% flag2: kind of curve

% flag2 = 0 -> Nelson-Siegel

% flag2 = 1 -> B-spline (function: d)

% flag2 = 2 -> B-spline + Penalty (function: d) % flag2 = 3 -> B-spline (function: g)

% flag2 = 4 -> B-spline + Penalty (function: g) % flag2 = 5 -> B-spline (function: f)

% flag2 = 6 -> B-spline + Penalty (function: f) %%%%%%%%%%%%%%%%%%%%%%%%%%%%

% FIRST STEP: Getting Data % %%%%%%%%%%%%%%%%%%%%%%%%%%%%

(11)

if flag1==0 [Btp,value_date]=Btp_data; elseif flag1==1 [Libor,Swap,value_date]=Libor_Swap_data; Swap=missing_Swap(Swap); end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % SECOND STEP: Building Matrices and Vectors % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % TT-> vector of global payments (time)

% AA-> matrix of global payments (value) % MAT->vector of maturity dates

if flag1==0 [P,T,A]=matrix_vector_Btp(value_date,Btp); elseif flag1==1 [P,T,A]=matrix_vector_LS(value_date,Libor,Swap); end [TT,AA,MAT]=matrix_vector(T,A); %%%%%%%%%%%%%%%%%%%%%%%%%%%%% % THIRD STEP: Curve Fitting % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% Find the vector x of the parameters of the curve %

% Options for FMINSEARCH

options=optimset(’TolFun’,1e-9,’TolX’,1e-9,’MaxIter’,1e8,’MaxFunEvals’,1e8); %

if flag2==0 %NELSON-SIEGEL

x_0=[0.04;-0.02;0.001;2]; %initial value

x=fminsearch(’NelsonSiegel’,x_0,options,AA,P,TT); else %B-SPLINE METHODS

K=length(MAT);

s=max(3,round(sqrt(K))); %number of knot points + 1 KP=knot_points(s,K,MAT);

s=length(KP)+2; %number of B-spline basis function

KPa=[KP(1),KP(1),KP(1),KP,KP(end),KP(end),KP(end)];%Augmented knot points if flag2==1 %B-SPLINE (function d)

for i=1:length(TT) for j=1:s

G(i,j)=BsplineBasis(j,4,TT(i),KPa); %B-spline matrix end

end

x_0=ones(s-1,1); %initial value

x=fminsearch(’Bspline’,x_0,options,AA*G,P); x=[1;x];

elseif flag2==2 %B-SPLINE + PENALTY (function d) for i=1:length(TT)

(12)

G(i,j)=BsplineBasis(j,4,TT(i),KPa); end

end

H=penalty(s,KPa); % Penalty Term % Find the optimal Penalty Parameter lambda=10^10; %initial value

lambda=fminsearch(’GCV’,lambda,options,AA*G,P,H); % Find x

x_0=ones(s-1,1); %initial value

x=fminsearch(’Bspline_penalty’,x_0,options,AA*G,P,H,lambda); x=[1;x];

elseif flag2==3 %B-SPLINE (function g) for i=1:length(TT) for j=1:s G(i,j)=BsplineBasis(j,4,TT(i),KPa); end end x_0=ones(s-1,1); x=fminsearch(’Bspline_g’,x_0,options,AA,G,P); x=[0;x];

elseif flag2==4 %B-SPLINE+PENALTY (function g) for i=1:length(TT)

for j=1:s

G(i,j)=BsplineBasis(j,4,TT(i),KPa); end

end

H=penalty(s,KPa); % Penalty Term % Find the optimal Penalty Parameter x_0=ones(s-1,1); %initial value lambda=10^3; % initial value

lambda=fminsearch(’GCV_g’,lambda,options,AA,G,P,H,x_0,s,options); % Find x

x=fminsearch(’Bspline_penalty_g’,x_0,options,AA,G,P,H,lambda); x=[0;x];

elseif flag2==5 %B-SPLINE (function f)

IG=intBsplineBasis(TT,s,KP,KPa); % integral of the B-spline basis x_0=ones(s,1); %initial value

x=fminsearch(’Bspline_f’,x_0,options,AA,IG,P); elseif flag2==6 %B-SPLINE+PENALTY (function f)

IG=intBsplineBasis(TT,s,KP,KPa); % integral of the B-spline basis H=penalty(s,KPa); % Penalty Term

% Find the optimal Penalty Parameter x_0=ones(s,1); %initial value

lambda=10^3; %initial value

lambda=fminsearch(’GCV_f’,lambda,options,AA,IG,P,H,x_0,s,options); % Find x

(13)

end end

4.1

First Step: Getting Data

The first step of the MATLABprogram is to get the Btp or the Libor and Swap data. If we consider Btp, the program calls the BTP_DATAroutine, which provides all the necessary data.

function [Btp,value_date]=Btp_data

% Btp -> Btp struct --> [nominal value, clean value, maturity, % rate, number of coupons (for year)] % value_date=’12/19/2006’; % Btp=[ struct(’n_val’,100,’val’,99.94,’mat’,’01/15/2007’,’rate’,2.75,’coupons’,2) ... struct(’n_val’,100,’val’,96.3,’mat’,’02/01/2037’,’rate’,4.00,’coupons’,2) ];

If instead we consider Libor and Swap, the program calls the LIBOR_SWAP_DATA routine for the necessary data and thenMISSING_SWAP, which uses linear interpolation for the missing Swap rates (see Section 2.2).

function [Libor,Swap,value_date]=Libor_Swap_data %

value_date=’09/21/2006’; %%%%%%%%%%%%%%%%%%%%%%

% Libor -> duration (in days) - duration (in months) - rate Libor=[ 1, 0, 3.04188; ... 0, 3, 3.37025; ]; %%%%%%%%%%%%%%%%%%%%%%

% Swap -> duration (in years) - rate Swap=[ 1, 3.808; ... 30, 4.214; ]; function Swap1=missing_Swap(Swap)

% Compute missing Swap using linear interpolation %

n=length(Swap); %number of Swaps difference=zeros(n,1); %initialize

% difference(i)=n means that between the duration of swap i and i+1 % there are n years-> if n=1 we do nothing, otherwise we create the

(14)

% missing Swap/Swaps using linear interpolation for i=1:n-1 difference(i)=Swap(i+1,1)-Swap(i,1); end % count=0; for i=1:n count=count+1; Swap1(count,:)=Swap(i,:); for j=1:difference(i)-1 count=count+1; Swap1(count,1)=Swap(i,1)+j; t=Swap1(count,1); t1=Swap(i,1); t2=Swap(i+1,1); s1=Swap(i,2); s2=Swap(i+1,2); Swap1(count,2)=(s1*(t2-t)+s2*(t-t1))/(t2-t1); end end

4.2

Second Step: Building Matrices and Vectors

In the second step, following Section 2, we build the matrix AA and the vector P necessary for the third step: the curve fitting.

If we consider Btp, the main program calls theMATRIX_VECTOR_BTProutine, which computes matrices A and T and the vector P (see Section 2.1).

function [P,T,A]=matrix_vector_Btp(Date,Btp) % Compute: P -> price vector

% T -> matrix of coupons’payments (time)

% T[i,j]=time to the jth payment of the ith Btp % A -> matrix of coupons’payments (value)

% A[i,j]=jth payment of the ith Btp % Date is taken as time 0

%

% Initialize Matrices and Vector n=length(Btp); % number of Btp P=zeros(n,1);

A=[]; T=[]; for i=1:n

% 1-compute Previous coupon and Next coupons [Pcoupon,Ncoupons]=PNcoupons(Btp(i),Date); % 2-compute Accrued Interest

AI=Btp(i).n_val*(Btp(i).rate/100)*(1/(Btp(i).coupons))*... (daysdif(Pcoupon,Date,3)/daysdif(Pcoupon,Ncoupons(1),3));

(15)

% 3-compute P

P(i)=Btp(i).val+AI; % 4-compute A and T

m=length(Ncoupons); % number of next coupons for j=1:m

T(i,j)=daysdif(Date,Ncoupons(j),3)/365;

A(i,j)=((Btp(i).rate/100)/Btp(i).coupons)*Btp(i).n_val; end

A(i,m)=A(i,m)+Btp(i).n_val; %pay the nominal value at maturity end

The above routine calls PNCOUPON, which computes the previous coupon date and the dates of the next coupons.

function [Pcoupon,Ncoupons]=PNcoupons(Btp,Date);

% Compute the Previous coupon and the Next coupons date %

maturity=Btp.mat;

numcoup=Btp.coupons;%number of coupons paid on each year monthcoup=12/numcoup; %months between two coupons

%

coupon=datenum(maturity);

%DATENUM converts date string into serial date number cday=day(maturity);%day of the maturity date

cmonth=month(maturity);%month of the maturity date cyear=year(maturity);%year of the maturity date count=0; %number of next coupons

while( daysdif(Date,coupon,3)>0 )

%DAYSDIF->days between dates with day-count basis 3(=actual/365) count=count+1; coup(count)=coupon;%next coupons’date temp=cmonth-monthcoup; if temp<=0 cyear=cyear-1; cmonth=12+temp; else cmonth=temp; end coupon=datenum(cyear,cmonth,cday); end Pcoupon=coupon;

while( isbusday(Pcoupon)==0 ) % if it is not a business day Pcoupon=Pcoupon+1;

end %

for i=1:count temp=coup(i);

(16)

temp=temp+1; end

Ncoupons(count-i+1)=temp; % ascending order end

In the same way, if we consider Libor and Swap, we compute matrix A, T and vector P using the

MATRIX_VECTOR_LS. Notice that A, T and P contain the elements of A1and A2, T1and T2, P1and

P2, respectively (see Section 2.2).

function [P,T,A]=matrix_vector_LS(Date,Libor,Swap) % Compute: P -> price vector

% T -> matrix of payments (time) % A -> matrix of payments (value) % Date is taken as time 0

%

n1=length(Libor); % number of Libors n2=length(Swap); % number of Swaps cday=day(Date); cmonth=month(Date); cyear=year(Date); % %%%%% % P % %%%%% P=ones(n1+n2,1); % %%%%%%%%%%% % A and T % %%%%%%%%%%% % Libor

% daycount -> actual/360 (basis 2 in daysdif) for i=1:n1

% temp is the maturity of the i-th Libor if Libor(i,1)>0 % if the duration is in days

temp=datenum(cyear,cmonth,cday+Libor(i,1)); else % if the duration is in months

temp=datenum(cyear,cmonth+Libor(i,2),cday); end

while( isbusday(temp)==0 ) %if it is not a business day temp=temp+1; end T(i,1)=daysdif(Date,temp,2)/360; A(i,1)=1+(Libor(i,3)/100)*T(i,1); end % % Swap

% daycount -> 30/360 (basis 6 in daysdif) for i=1:n2

(17)

for j=1:Swap(i,1)

% temp is the j-th payment date of the i-th Swap temp=datenum(cyear+j,cmonth,cday);

while( isbusday(temp)==0 ) %if it is not a business day temp=temp+1;

end

T(n1+i,j)=daysdif(Date,temp,6)/360; if j==1 %if it is the first payment

t=T(n1+i,j); else t=T(n1+i,j)-T(n1+i,j-1); end A(n1+i,j)=(Swap(i,2)/100)*t; end A(n1+i,Swap(i,1))=A(n1+i,Swap(i,1))+1; end

At the end, using routineMATRIX_VECTOR, we compute matrix AA and vector T T (see Section 2) for both the Btp case or the Libor-Swap case.

function [TT,AA,MAT]=matrix_vector(T,A) % Compute:

% TT-> vector of global payments (time) % AA-> matrix of global payments (value) % MAT->vector of times to maturity

% %%%%%% % TT % %%%%%% count=1; for i=1:size(T,2) for j=1:size(T,1) a=T(end+1-j,i);

if a==0 %all the remaining element of the column are 0 break % break the j-loop

else

flag=0; % the date a is not present in TT for k=1:count-1

if TT(k)==a

flag=1; % a is already present in T break % break the k-loop

end end

if flag==0 % if the date a is not present in TT... TT(count)=a; % add a to TT

count=count+1; end

(18)

end end

TT=sort(TT); %Sort in ascending order. %%%%%% % AA % %%%%%% for k=1:length(TT) for i=1:size(A,1) for j=1:size(A,2)

if T(i,j)==TT(k) %if the payment date are equal AA(i,k)=A(i,j); break; elseif T(i,j)>TT(k) break; end end end end %%%%%%% % MAT % %%%%%%% for i=1:size(T,1) for j=1:size(T,2) if T(i,j)==0 MAT(i)=T(i,j-1); break; elseif j==size(T,2) MAT(i)=T(i,j); break; end end end MAT=sort(MAT);

For further details see the examples reported in Appendix A.

4.3

Third Step: Curve Fitting

In this last step we compute the curve’s parameters. Notice that both the Btp case and the Libor and Swap case are considered without any distinction.

4.3.1 Nelson Siegel Model From theMAINroutine we have

x_0=[0.04;-0.02;0.001;2]; %initial value

x=fminsearch(’NelsonSiegel’,x_0,options,AA,P,TT); where the NELSONSIEGELroutine is the following

(19)

function [f]=NelsonSiegel(x,A,P,T) % f is the quantity to minimize %

if x(1)<=0 % x(1) must be positive... f=10^15;

elseif x(1)+x(2)<=0 % x(1)+x(2) must be positive... f=10^15;

elseif x(4)<=0 % x(4) must be positive... f=10^15; else % if x(1), x(1)+x(2), x(4) is positive... for i=1:length(T) t(i,1)=exp(-x(1)*T(i)-x(4)*(x(2)+x(3))*(1-exp(-T(i)/x(4)))+... x(3)*T(i)*exp(-T(i)/x(4))); end temp=P-A*t; f=0; for i=1:length(temp) f=f+temp(i)^2; end end

If we consider Section 3.1, we have

x(1):= α1, x(2):= α2, x(3):= α3, x(4):= β.

Notice that, in order to solve the constrain minimization (9), we impose f=10^15 if (8) is not satisfied. 4.3.2 B-spline methods

For the B-spline methods, in order to define the basis functions, in theMAINprogram we have K=length(MAT);

s=max(3,round(sqrt(K))); %number of knot points + 1 KP=knot_points(s,K,MAT);

s=length(KP)+2; %number of B-spline basis functions

KPa=[KP(1),KP(1),KP(1),KP,KP(end),KP(end),KP(end)]; %Augmented KP where theKNOT_POINTSroutine is as follows

function T=knot_points(s,k,MAT)

% Compute the knot points following McCulloch (1971)

% These points are used to compute the B-spline basis functions %

T(1)=0; for i=2:s-2

h=fix(((i-1)*k/(s-2)));

% fix(X) rounds X to the nearest integers towards zero. theta=((i-1)*k/(s-2))-h;

T(i)=MAT(h)+theta*(MAT(h+1)-MAT(h)); end

(20)

As in [6] and [8], the number of knot points (and thus the number of basis functions) depends on√K. In Appendix B we report the following routines:

• BSPLINEBASISreturns the value of B-spline basis functions; this routine is used to compute matrix G,

• DBSPLINEBASISreturns the value of the first derivative of the B-spline basis functions, • DDBSPLINEBASISreturns the value of the second derivative of the B-spline basis functions,

• INTBSPLINEBASISreturns the integrals of the B-spline basis functions: this routine is used to com-pute matrix IG.

Following Sections 3.2.1 and 3.2.2, in order to compute the set of parameters β, we have to consider the minimization problem below.

• B-spline (parametrized function: d) From theMAINroutine we have

x_0=ones(s-1,1); %initial value

x=fminsearch(’Bspline’,x_0,options,AA*G,P); x=[1;x];

where

function [f]=Bspline(x,A,b) % B-spline

% f is the quantity to minimize %

x=[1;x]; %the first term of the vector must be equal to 1 temp=b-A*x;

f=0;

for i=1:length(temp) f=f+temp(i)^2; end

Notice that d(0) = 1, since the present value of 1 Euro repayable in 0 years is actually 1; thus we have to impose

β1= 1

since 0 is the first knot point and it holds

φ1(0) = 1, φi(0) = 0 if i = 2, · · · s,

where we recall that s is the number of basis functions (see Figure 1 and [2]). For this reason, the minimization procedure involves only the parameters β2, · · · , βs.

• B-spline with Penalty (parametrized function: d) From theMAINroutine we have

(21)

H=penalty(s,KPa); % Penalty Term % Find the optimal Penalty Parameter lambda=10^10; %initial value

lambda=fminsearch(’GCV’,lambda,options,AA*G,P,H); % Find x

x_0=ones(s-1,1); %initial value

x=fminsearch(’Bspline_penalty’,x_0,options,AA*G,P,H,lambda); x=[1;x];

The penalty term, which is unique for each B-spline with penalty method, is computed by the PENALTYroutine (see Section 3.2.2).

function H=penalty(s,KPa) % Compute the Penalty Term % K=length(KPa)-6; H=sparse(s,s); for k=1:K-1 [x,w]=gauleg(KPa(k+3),KPa(k+4),4); for t=1:length(x) f=[]; for i=1:s f(i)=ddBsplineBasis(i,4,x(t),KPa); end for i=1:s for j=1:s H(i,j)=H(i,j)+w(t)*f(i)*f(j); end end end end

For theGAULEGroutine, which computes the nodes and weights of the Gauss-Legendre quadrature formula, see Appendix B.5.

The minimization procedures call the following routines: function f=GCV(lambda,X,Y,H)

% GENERAL CROSS VALIDATION %

Q=X*inv(X’*X+lambda*H)*X’; n=length(Y);

I=eye(n); %identity matrix of size n T=(I-Q)*Y;

theta=2;

f=((T’)*T)/((n-theta*trace(Q))^2); and

(22)

function [f]=usa_Bspline_penalty(x,A,b,H,lambda) % f is the quantity to minimize

%

x=[1;x];%the first term of the vector must be equal to 1 f=((b-A*x)’)*(b-A*x)+lambda*((x’)*H*x);

As above, the second minimization procedure involves only the parameters β2, · · · , βs.

• B-spline (parametrized function: g) From theMAINroutine we have x_0=ones(s-1,1);

x=fminsearch(’Bspline_g’,x_0,options,AA,G,P); x=[0;x];

where

function [f]=Bspline_g(x,C,F,b) % f is the quantity to minimize %

x=[0;x];

Pi=C*exp(-F*x); f=((b-Pi)’)*(b-Pi);

Notice that we have imposed β1= 0 since g(0) = 0 implies d(0) = 1 (see (11) ).

• B-spline with Penalty (parametrized function: g) From theMAINroutine we have

H=penalty(s,KPa); % Penalty Term % Find the optimal Penalty Parameter x_0=ones(s-1,1); %initial value lambda=10^3; % initial value

lambda=fminsearch(’GCV_g’,lambda,options,AA,G,P,H,x_0,s,options); % Find x x=fminsearch(’Bspline_penalty_g’,x_0,options,AA,G,P,H,lambda); x=[0;x]; where function e=GCV_g(lambda,AA,G,P,H,b_0,s,options) % GENERAL CROSS VALIDATION

% if lambda>0 b=fminsearch(’Bspline_penalty_g’,b_0,options,AA,G,P,H,lambda); b=[0;b]; W=AA*exp(-G*b); temp=AA*G;

(23)

for i=1:length(W)

Xg(i,:)=(-W(i)).*(temp(i,:)); end

Yg=P-W+Xg*b;

e=GCV(lambda,Xg,Yg,H); else %constrain: lambda>0

e=10^12; end

and

function [f]=Bspline_penalty_g(x,C,F,b,H,lambda) % f is the quantity to minimize

%

x=[0;x];

Pi=C*exp(-F*x);

f=(((b-Pi)’)*(b-Pi))+lambda*((x’)*H*x);

Notice that GCV_Gcall B-SPLINE_PENALTY_Gin a minimization procedure. Moreover, as above, we have imposed β1= 0 and the minimization procedures involve only parameters β2, · · · , βs.

• B-spline (parametrized function: f ) From theMAINroutine we have

x_0=zeros(s,1); %initial value

x=fminsearch(’Bspline_f’,x_0,options,AA,IG,P); where

function [f]=Bspline_f(x,C,F,b) % f is the quantity to minimize %

Pi=C*exp(-F*x); f=((b-Pi)’)*(b-Pi);

Notice that (13) implies d(0) = 1; thus we do not impose any restriction to β1and the minimization

procedure involves β1, · · · , βs.

• B-spline with Penalty (parametrized function: f )

This case is similar to the B-spline with Penalty (parametrized function: g) case. We have H=penalty(s,KPa); % Penalty Term

% Find the optimal Penalty Parameter x_0=ones(s,1); %initial value

lambda=10^3; %initial value

lambda=fminsearch(’GCV_f’,lambda,options,AA,IG,P,H,x_0,s,options); % Find x

(24)

where

function e=GCV_f(lambda,X,IG,P,H,b_0,s,options) % GENERAL CROSS VALIDATION

% if lambda>0 b=fminsearch(’Bspline_penalty_f’,b_0,options,X,IG,P,H,lambda); W=X*exp(-IG*b); temp=X*IG; for i=1:length(W) Xf(i,:)=(-W(i)).*(temp(i,:)); end Yf=P-W+Xf*b; e=GCV(lambda,Xf,Yf,H); else %constrain: lambda>0

e=10^12; end

and

function [f]=Bspline_penalty_f(x,C,F,b,H,lambda) % f is the quantity to minimize

%

Pi=C*exp(-F*x);

f=(((b-Pi)’)*(b-Pi))+lambda*((x’)*H*x);

5

Numerical Results

The aim of this section is to present the models’performances, considering both computational cost and approximation results. Numerical experiments have been carried out on a Personal Computer with a Pentium IV (2.40 Ghz) processor and 768 MB of RAM, and using MATLAB7.0 (R14).

5.1

Btp Case

In this section we deal with the Btp case, which are Italian coupon bonds with semi-annual payments. In the numerical experiments we have considered the Btp quotation with value date 19thDecember 2006 (see Table 2).

First of all we consider the computational cost: the “Building Matrices and Vectors” step, which does not depend on the fitting model considered, takes approximately 8.5 seconds, while in Table 3 we report the elapsed time of the third step of theMAIN routine (i.e., the “Curve Fitting” steps) for each method considered. Moreover, in the same table we present the residuals |E| of the minimization problems (9) for the Nelson Siegel model, (15) for the B-spline methods, and (16) for the B-spline with penalty methods; for this last class of methods, we also report the best λ computed with the GCV procedure.

From this table, it seems that the best choice from a computational point of view is the B-spline model with the parametrization of the discount function, while if we consider the residual, the best choice seems to be the B-spline method (f ), i.e., we parametrize the instantaneous forward rate function f using B-spline basis functions. Moreover, the B-spline methods with penalty (g) and (f ) have a great computational cost: this

(25)

Table 2: Btp

Value Clean Price Expiration Annual Rate Value Clean Price Expiration Annual Rate

(%) (%) 100 99.94 01/15/2007 2.75 100 105.91 08/01/2011 5.25 100 100.36 02/01/2007 6.75 100 99.57 09/15/2011 3.75 100 100.17 03/01/2007 4.50 100 105.31 02/01/2012 5.00 100 99.7 06/01/2007 3.00 100 104.81 02/01/2013 4.75 100 101.6 07/01/2007 6.75 100 102.22 08/01/2013 4.25 100 101 10/15/2007 5.00 100 102.31 08/01/2014 4.25 100 101.89 11/01/2007 6.00 100 102.27 02/01/2015 4.25 100 99.77 01/15/2008 3.50 100 98.6 08/01/2015 3.75 100 98.92 02/01/2008 2.75 100 98.19 08/01/2016 3.75 100 101.63 05/01/2008 5.00 100 110.78 08/01/2017 5.25 100 98.18 06/15/2008 2.50 100 101.96 02/01/2019 4.25 100 99.69 09/15/2008 3.50 100 104.24 02/01/2020 4.50 100 98.37 04/15/2009 3.00 100 96.16 08/01/2021 3.75 100 98.44 02/01/2009 3.00 100 158.78 11/01/2023 9.00 100 101.6 05/01/2009 4.50 100 141.42 11/01/2026 7.25 100 99.91 06/15/2009 3.75 100 131.7 11/01/2027 6.50 100 101.25 11/01/2009 4.25 100 115.18 11/01/2029 5.25 100 97.74 01/15/2010 3.00 100 127.09 05/01/2031 6.00 100 96.59 06/15/2010 2.75 100 124.27 02/01/2033 5.75 100 106.03 11/01/2010 5.50 100 112.94 08/01/2034 5.00 100 98.73 03/15/2011 3.50 100 96.3 02/01/2037 4.00

Table 3: Btp Data: Timing and Residual

Method Curve Fitting Residual Best λ (elapsed time)

Nelson Siegel 0.406 seconds 1.058905 -Bspline (d) 0.313 seconds 0.599565 -Bspline+Penalty(d) 0.531 seconds 0.858068 15442.197764 Bspline (g) 0.437 seconds 0.544416 -Bspline+Penalty (g) 28.922 seconds 0.560438 1273.437583 Bspline (f ) 3.234 seconds 0.471925 -Bspline+Penalty (f ) 80.062 seconds 1.641775 52148137.527466

is due to the GCV-minimization procedure, which call another minimization procedure at each step (see Section 3.2.2).

Then we show the plots of the discount function d (Figure 2), of the spot rate function h (Figure 3), where

h(τ ) := −log(d(τ )) τ , and of the instantaneous forward rate function f (Figure 4).

These figures suggest the following observations, which are important in order to understand the behavior of the different data-fitting techniques:

(26)

Figure 2: Btp Case 0 5 10 15 20 25 30 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1 Discount Function Nelson−Siegel Bspline (d) Bspline + Penalty (d) Bspline (g) Bspline + Penalty (g) Bspline (f) Bspline + Penalty (f) Figure 3: Btp Case 0 5 10 15 20 25 30 0.036 0.037 0.038 0.039 0.04 0.041 0.042 0.043 Spot Rate Nelson−Siegel Bspline (d) Bspline + Penalty (d) Bspline (g) Bspline + Penalty (g) Bspline (f) Bspline + Penalty (f)

(27)

Figure 4: Btp Case 0 5 10 15 20 25 30 0.034 0.036 0.038 0.04 0.042 0.044 0.046

Instantaneous Forward Rate

Nelson−Siegel Bspline (d) Bspline + Penalty (d) Bspline (g) Bspline + Penalty (g) Bspline (f) Bspline + Penalty (f) Figure 5: Btp Case 0 5 10 15 20 25 30 35 40 −0.8 −0.6 −0.4 −0.2 0 0.2 0.4 0.6 Comparison Nelson−Siegel Bspline (d) Bspline + Penalty (d) Bspline (g) Bspline + Penalty (g) Bspline (f) Bspline + Penalty (f)

(28)

• discount function

from Figure 2 it seems that the different methods for curve construction produce very similar plots; • spot rate function

from Figure 3 it seems that the Nelson Siegel and the B-spline with penalty (f ) models behave quite different from the other methods after the 15-years point. If we consider the last method, this behavior is due to the large penalty parameter computed with the GCV procedure (see Table 3);

• instantaneous forward rate function

the plots presented in Figure 4 are quite different; the best choices seem to be the Nelson-Siegel and the B-spline with penalty (f ) models, since for the other methods the plotted curves decrease too rapidly after the 20-years point (see [3] for further details).

Finally we compare our models with the initial data. More precisely, let eP be the vector containing the prices of the considered Btp at the value date, computed using the discount function obtained with a data-fitting technique, then in Figure 5 we plot the values

P (i) − eP (i), i = 1, · · · , 42, where 42 is the number of Btp considered.

5.2

Libor and Swap Case

In this section we present the same data as above, considering Libor and Swap rates with value date 21thSeptember 2006 (see Tables 4 and 5).

Table 4: Libor

Duration (days) Rate (%) Duration (months) Rate (%) 1 day 3.04188 1 month 3.19325 7 days 3.06275 2 months 3.2935 15 days 3.06563 3 months 3.37025

Table 5: Swap

Duration (year) Rate (%) Duration (year) Rate (%) 1 3.808 8 3.973 2 3.88 9 4.011 3 3.883 10 4.029 4 3.892 15 4.066 5 3.906 20 4.202 6 3.925 25 4.218 7 3.947 30 4.214

As above, in Table 6 we compare the different methods considering both the computational cost and the residuals |E|, respectively. The results are in agreement with the Btp case. Notice that the elapsed time for the “Building Matrices and Vectors” step is approximately 3.5 seconds.

Moreover, in Figures 6, 7 and 8 we show the plots of the discount function, of the spot rate function and of the instantaneous forward rate function, respectively. These figures suggest the following observations:

• discount function

(29)

Figure 6: Libor and Swap Case 0 5 10 15 20 25 30 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1 Discount Function Nelson−Siegel Bspline (d) Bspline + Penalty (d) Bspline (g) Bspline + Penalty (g) Bspline (f) Bspline + Penalty (f)

Figure 7: Libor and Swap Case

0 5 10 15 20 25 30 0.036 0.037 0.038 0.039 0.04 0.041 0.042 0.043 Spot Rate Nelson−Siegel Bspline (d) Bspline + Penalty (d) Bspline (g) Bspline + Penalty (g) Bspline (f) Bspline + Penalty (f)

(30)

Figure 8: Libor and Swap Case 0 5 10 15 20 25 30 0.034 0.036 0.038 0.04 0.042 0.044 0.046 0.048

Instantaneous Forward Rate

Nelson−Siegel Bspline (d) Bspline + Penalty (d) Bspline (g) Bspline + Penalty (g) Bspline (f) Bspline + Penalty (f)

Figure 9: Libor and Swap Case

0 5 10 15 20 25 30 35 40 −8 −6 −4 −2 0 2 4 x 10−3 Comparison Nelson−Siegel Bspline (d) Bspline + Penalty (d) Bspline (g) Bspline + Penalty (g) Bspline (f) Bspline + Penalty (f)

(31)

Table 6: Libor and Swap Data: Timing and Residual Method Curve Fitting Residual Best λ

(elapsed time)

Nelson Siegel 0.125 seconds 0.011997 -Bspline (d) 0.157 seconds 0.006932 -Bspline+Penalty(d) 0.360 seconds 0.011889 4.089915 Bspline (g) 0.157 seconds 0.007672 -Bspline+Penalty (g) 18.828 seconds 0.012356 22.205400 Bspline (f ) 0.920 seconds 0.005384 -Bspline+Penalty (f ) 44.875 seconds 0.006086 1.419115 • spot rate function

from Figure 7 it seems that the B-spline with penalty (g) method (and not the B-spline with penalty (f ), as in the Btp case) behaves like the Nelson Siegel model: this is due to the different penalty parameter value, since in the Btp case the largest parameter is the one of the B-spline with penalty (f ) method, while in the Libor and Swap case it is the one computed for the B-spline with penalty (g) model (see Table 6);

• instantaneous forward rate function

Figure 8 suggests that the best plots are the ones derived from the Nelson Siegel and the B-spline with penalty methods, since the classical B-spline methods produce curves which increase or decrease too rapidly after the 20-years points.

Finally, as in the previous subsection, in Figure 9 we compare our models with the initial data.

6

Conclusion

In this paper we have shown how to fit smoothing splines or exponential curves (like the Nelson Siegel model) to the term structure of interest rates. We have described the MATLABcode and we have presented numerical results, comparing the different models. From the numerical experiments, it is clear that it is not possible to find the best model: the choice of which method to use is subjective and need to be decided on a case by case basis. In fact, if we consider the residual, the best choice is to use smoothing splines which parametrized the instantaneous forward rate function f : this result is in agreement with [2]. Moreover, if we are interested in the instantaneous forward rate function, the best choice seems to be the Nelson Siegel model. Following [2], we have also presented methods with a penalty term: these methods behaves better than the classical B-spline methods if we consider the instantaneous forward rate function, but they are characterized by high computational costs due to the GCV procedure in order to compute the best penalty parameter. Notice that in [2] the authors use a great number of knot points and thus the penalty term is necessary in order to obtain well-behaved curves, while in this paper we have followed [6] and [8], using few knot points.

(32)

A

Building Matrices and Vectors: Examples

The aim of this section is to explain Sections 2 and 4.2 with two examples: one for the Btp case and the other for the Libor and Swap case.

A.1

Btp Case

In this section we consider the Btp quotation with value date 19thDecember 2006 reported in Table 7. Table 7: Btp

Facial Value Clean Price Expiration Annual Interest Rate (%) 100 99.94 01/15/2007 2.75

100 99.7 06/01/2007 3.00 100 99.77 01/15/2008 3.50 100 101.63 05/01/2008 5.00 100 98.18 06/15/2008 2.50 We now consider the first bond of Table 7: following Section 2.1, we have • m1= 1, i.e, there is only 1 payment date for the first bond;

• F1= 100, i.e., the facial value;

• C1= 1002.75%2 = 1.375, i.e., the facial value multiplied by the semi-annual interest rate.

Reasoning in the same way for all the elements of Table 7, we have

A =         101.375 0 0 101.5 0 0 1.75 1.75 101.75 2.5 2.5 102.5 1.25 1.25 101.25         . Moreover, we have BP =         01/16/07 06/01/07 01/16/07 07/16/07 01/15/08 05/01/07 11/01/07 05/01/08 06/15/07 12/17/07 06/16/08         and thus T =         28 0 0 164 0 0 28 209 392 133 317 499 178 363 545         ,

where we recall that T contains the days between the value date and the payment dates of the Btp BP , computed according to the actual/365 day-count convention.

Now we can compute vector T T , i.e., the vector containing all the non-zero elements of T T T = 28 133 164 178 209 317 363 392 499 545 ;

(33)

and thus we define matrix AA as follows AA =         101.375 0 0 0 0 0 0 0 0 0 0 0 101.5 0 0 0 0 0 0 0 1.75 0 0 0 1.75 0 0 101.75 0 0 0 2.5 0 0 0 2.5 0 0 102.5 0 0 0 0 1.25 0 0 1.25 0 0 101.25         .

Notice that in the MATLABcode (see Section 4) both the elements of T and T T are computed in years and not in days. Moreover, in order to compute the payment dates (and thus BP ), we have to check if each date is a business day: in our code, we have used the MATLABfunctionISBUSDAY, which is based on the US calendar (that is why the 15thJanuary 2007 is considered as holiday and thus the payment date of the first bond is 16thJanuary 2007).

Finally, if we sum the clean prices and the accrued interests, we obtain

P =         101.104617486339 99.848351648352 101.252240437158 102.292983425414 98.207472527473         .

A.2

Libor and Swap

Now we consider the Libor and Swap interest rates with value date 21thSeptember 2006 reported in

Tables 8 and 9, respectively.

Table 8: Libor Duration Interest Rate (%)

1 day 3.04188 7 days 3.06275 15 days 3.06563

Table 9: Swap Duration Interest Rate (%)

1 year 3.808 2 years 3.88 3 years 3.883 First of all, we consider the Libor case: from Table 8, we obtain

LR = 0.0304188 0.0306275 0.0306563 , LM = 1 7 15 ;

thus, following Section 2.2, we have

LP = 09/22/06 09/28/06 10/06/06 , T1=



(34)

and so

A1=



1.000084 1.000595 1.001278 ;

notice that in this example the elements of LM are computed in days, while the elements of T1 are

computed in years, using the actual/360 day-count convention. Now we consider the Swap case: from Table 9 we obtain

SR = 0.03808 0.0388 0.03883  and SP =    09/21/07 09/21/07 09/22/08 09/21/07 09/22/08 09/21/09   .

Recalling that the value date is 09/21/06, using the 30/360 day-count convention, we have

T2=    1 0 0 1 2.002778 0 1 2.002778 3   .

We recall that in order to compute the payment dates, we have to check if each date is a business day, otherwise we have to look for the next business day: this is the reason why T2(2, 2) = 2.002778.

Finally, following Section 2.2, we calculate matrix A2

A2=    1.03808 0 0 0.0388 1.038908 0 0.03883 0.038938 1.038722   .

If we now compute vector T T , i.e., the vector containing all the non-zero elements of T1and T2

T T = 0.002778 0.019444 0.041667 1 2.002778 3 , we can define matrix AA as follows

AA =           1.000084 0 0 0 0 0 0 1.000595 0 0 0 0 0 0 1.001277 0 0 0 0 0 0 1.03808 0 0 0 0 0 0.0388 1.038908 0 0 0 0 0.03883 0.038938 1.038722           ;

Notice that in theMATRIX_VECTOR_LS routine (see Section 4.2) the elements of A1and A2are stored

in a unique matrix A A =           1.000084 0 0 1.000595 0 0 1.001278 0 0 1.03808 0 0 0.0388 1.038908 0 0.03883 0.038938 1.038722           ;

(35)

in the same way, the elements of T1and T2are stored in T as follows T =           0.002778 0 0 0.019444 0 0 0.041667 0 0 1 0 0 1 2.002778 0 1 2.002778 3           .

B

Bspline Routines

In this section, we present the following routines:

1. BSPLINEBASIScomputes the value of B-spline basis functions;

2. DBSPLINEBASIScomputes the value of the first derivative of the B-spline basis functions; 3. DDBSPLINEBASIScomputes the value of the second derivative of the B-spline basis functions; 4. INTBSPLINEBASISreturns the integrals of the B-spline basis functions;

5. GAULEGcomputes the nodes and weights of the Gauss-Legendre quadrature formula.

B.1

B

SPLINE

B

ASIS

function F=BsplineBasis(k,r,x,d) % B-spline Basis Function

% k -> consider the kth basis function % r -> r-1 is the degree of the spline

% x -> is the the point in which I evaluate the function % d -> augmented knot points

% if (k+r-1<5 & k<5) if (x<d(5)) F=((d(5)-x)/(d(5)-d(1)))^(r-1); else F=0; end

elseif (k+1>length(d)-4 & k+r>length(d)-4) if (x>=d(end-4)) F=((x-d(end-4))/(d(end)-d(end-4)))^(r-1); else F=0; end else if r==1 if (x>=d(k) & x<d(k+1)) F=1; else

(36)

F=0; end else f1=BsplineBasis(k,r-1,x,d); f2=BsplineBasis(k+1,r-1,x,d); F=((f1*(x-d(k)))/(d(k+r-1)-d(k)))+... ((f2*(d(k+r)-x))/(d(k+r)-d(k+1))); end end

B.2

D

B

SPLINE

B

ASIS function F=dBsplineBasis(k,r,x,d)

% First Derivative of B-spline Basis Function % k -> consider the kth basis function

% r -> r-1 is the degree of the spline

% x -> is the vector of the points in which I evaluate the function % d -> augmented knot points (necessary to define the basis function) % if r<2 F=0; else if (k+r-1<5 & k<5) if (x<d(5)) F=(r-1)*(((d(5)-x)/(d(5)-d(1)))^(r-2))*(-1/(d(5)-d(1))); else F=0; end

elseif (k+1>length(d)-4 & k+r>length(d)-4) if (x>=d(end-4)) F=(r-1)*(((x-d(end-4))/(d(end)-d(end-4)))^(r-2))*... (1/(d(end)-d(end-4))); else F=0; end else f1=BsplineBasis(k,r-1,x,d); f2=BsplineBasis(k+1,r-1,x,d); d1=dBsplineBasis(k,r-1,x,d); d2=dBsplineBasis(k+1,r-1,x,d); F=((f1+(x-d(k))*d1)/((d(k+r-1)-d(k))))+... ((-f2+(d(k+r)-x)*d2)/(d(k+r)-d(k+1))); end end end

(37)

B.3

DD

B

SPLINE

B

ASIS

function F=ddBsplineBasis(k,r,x,d)

% Second Derivative of B-spline Basis Function % k -> consider the kth basis function

% r -> r-1 is the degree of the spline

% x -> is the vector of the points in which I evaluate the function % d -> augmented knot points (necessary to define the basis function) % if r<3 F=0; else if (k+r-1<5 & k<5) if (x<d(5)) F=(r-1)*(r-2)*(((d(5)-x)/(d(5)-d(1)))^(r-3))*... ((-1/(d(5)-d(1)))^2); else F=0; end

elseif (k+1>length(d)-4 & k+r>length(d)-4) if (x>=d(end-4)) F=(r-1)*(r-2)*(((x-d(end-4))/(d(end)-d(end-4)))^(r-3))*... ((1/(d(end)-d(end-4)))^2); else F=0; end else d1=dBsplineBasis(k,r-1,x,d); d2=dBsplineBasis(k+1,r-1,x,d); dd1=ddBsplineBasis(k,r-1,x,d); dd2=ddBsplineBasis(k+1,r-1,x,d); F=((d1+(x-d(k))*dd1+d1)/((d(k+r-1)-d(k))))+... ((-d2+(d(k+r)-x)*dd2-d2)/(d(k+r)-d(k+1))); end end end

B.4

INT

B

SPLINE

B

ASIS

function IG=intBsplineBasis(T,s,KP,d)

% Integral of the cubic B-spline basis function % IG[i,j]=int_{0}^{T(i)} B(j) dx

% where B(j) is the jth basis function % KP -> Knot Points

% d -> Augmented Knot Points %

IG=zeros(length(T),s); for i=1:length(T)

(38)

for ii=1:length(KP) if T(i)>KP(ii) if ii<length(KP) t=min(T(i),KP(ii+1)); else t=T(i); end [x,w]=gauleg(KP(ii),t,4); for j=1:s for jj=1:length(x) temp=BsplineBasis(j,4,x(jj),d); IG(i,j)=IG(i,j)+temp*w(jj); end end

else %the integral between 0 and T(i) has already been computed break %stop the ii-loop and change the value of i

end end end

B.5

GAULEG

function [xx,ww]=gauleg(a,b,n) % Gauss-Legendre quadrature formula

% Computes the Gauss-Legendre nodes xx and weights ww % of order n for the interval (a,b)

% m=(n+1)/2; xm=0.5*(b+a); xl=0.5*(b-a); for i=1:m z=cos(pi*(i-0.25)/(n+0.5)); while 1 % do untill break

p1=1.0; p2=0.0; for j=1:n p3=p2; p2=p1; p1=((2.0*j-1.0)*z*p2-(j-1.0)*p3)/j; end pp=n*(z*p1-p2)/(z*z-1.0); z1=z; z=z1-p1/pp;

if (abs(z-z1)<eps), break, end end

xx(i)=xm-xl*z; xx(n+1-i)=xm+xl*z;

(39)

ww(i)=2.0*xl/((1.0-z*z)*pp*pp); ww(n+1-i)=ww(i);

end

C

M

ATLAB

Routines

The following informations are taken from the MATLAB[13] manual.

C.1

DAYSDIF

- Days between dates for any day count basis

DAYSDIF returns the number of days between D1 and D2 using the given day count basis. Enter dates as serial date numbers or date strings.

D = daysdif(D1, D2) D = daysdif(D1, D2, Basis) Inputs:

D1 - [Scalar or Vector] of dates. D2 - [Scalar or Vector] of dates.

Optional Inputs:

Basis - [Scalar or Vector] of day-count basis. Valid Basis are:

0 = actual/actual (default) 1 = 30/360 2 = actual/360 3 = actual/365 4 - 30/360 (PSA compliant) 5 - 30/360 (ISDA compliant) 6 - 30/360 (European) 7 - act/365 (Japanese)

C.2

DATENUM

- Serial date number

N = DATENUM(S) converts the string or date vector S into a serial date number. Date numbers are serial days where 1 corresponds to 1-Jan-0000.

Certain formats may not contain enough information to compute a date number. In those cases, missing values will in general default to 0 for hours, minutes and seconds, will default to January for the month, and 1 for the day of month. The year will default to the current year. Date strings with 2 character years are interpreted to be within the 100 years centered around the current year.

N = DATENUM(Y,M,D) and N = DATENUM([Y,M,D]) return the serial date numbers for correspond-ing elements of the Y,M,D (year,month,day) arrays. Y, M, and D must be arrays of the same size (or any can be a scalar).

Examples:

(40)

n = datenum(2001,12,19) returns n = 731204.

n = datenum(2001,12,19,18,0,0) returns n = 731204.75.

C.3

FMINSEARCH

- Multidimensional unconstrained nonlinear minimization

X = FMINSEARCH(FUN,X0) starts at X0 and attempts to find a local minimizer X of the function FUN. FUN accepts input X and returns a scalar function value F evaluated at X. X0 can be a scalar, vector or matrix.

X = FMINSEARCH(FUN,X0,OPTIONS) minimizes with the default optimization parameters replaced by values in the structure OPTIONS, created with the OPTIMSET function. FMINSEARCH uses these options: Display, TolX, TolFun, MaxFunEvals, MaxIter, FunValCheck, and OutputFcn.

[X,FVAL]= FMINSEARCH(...) returns the value of the objective function, described in FUN, at X. [X,FVAL,EXITFLAG] = FMINSEARCH(...) returns an EXITFLAG that describes the exit condition of FMINSEARCH. Possible values of EXITFLAG and the corresponding exit conditions are:

1 - FMINSEARCH converged to a solution X.

0 - Maximum number of function evaluations or iterations reached. -1 - Algorithm terminated by the output function.

FMINSEARCH uses the Nelder-Mead simplex (direct search) method.

C.4

ISBUSDAY

- True for dates that are business days

T = ISBUSDAY(D,HOL,WEEKEND)

Inputs:

D - a vector of dates in question. Optional Inputs:

HOL - a user-defined vector of holidays. The default is a predefined US holidays (in holidays.m).

WEEKEND - a vector of length 7, containing 0 and 1, with the value of 1 to indicate weekend day(s). The first element of this vector corresponds to Sunday. Thus, when Saturday and Sunday are weekend then WEEKDAY = [1 0 0 0 0 0 1]. The default is Saturday and Sunday weekend.

Outputs:

T = - 1 if D is business day and 0 if otherwise.

C.5

OPTIMSET

- Create/alter OPTIM OPTIONS structure

OPTIONS = OPTIMSET(’PARAM1’,VALUE1,’PARAM2’,VALUE2,...) creates an optimization options structure OPTIONS in which the named parameters have the specified values. Any unspecified parameters are set to [] (parameters with value [] indicate to use the default value for that parameter when OPTIONS is passed to the optimization function).

OPTIMSET PARAMETERS for MATLAB: Display - Level of display [ off | iter | notify | final ]

(41)

MaxIter - Maximum number of iterations allowed [ positive scalar ] TolFun - Termination tolerance on the function value [ positive scalar ] TolX - Termination tolerance on X [ positive scalar ]

FunValCheck - Check for invalid values, such as NaN or complex, from user-supplied functions [ off | on ] OutputFcn - Name of installable output function [ function ]. This output function is called by the solver after each iteration.

References

[1] Revisiting “The Art and Science of Curve Building”, FINCAD News, December 2005 Issue.

[2] M. Fisher, D. Nychka, D. Zervos, “Fitting the Term Structure of Interest Rates with Smoothing Splines”, Board of Governors of the Federal Reserve System (U.S.), Finance and Economics Dis-cussion Series, Vol. 95-1, 1994.

[3] P. Hagan, G. West, “Interpolation Methods for Curve Construction”, Applied Mathematical Finance, Vol. 13-2, 2006.

[4] M. Ioannides, “A Comparison of Yield Curve Estimation Techniques Using UK Data”, Journal of Banking & Finance, Vol. 27, 2003.

[5] J. James, N. Webber, Interest Rate Modelling, John Wiley & Sons, 2000.

[6] J.H. McCulloch, “Measuring the Term Structure of Interest Rate”, Journal of Business, Vol. XLIV, 1971.

[7] J.H. McCulloch, “The Tax-Adjusted Yield Curve”, The Journal of Finance, Vol. XXX-3, 1975. [8] S.K. Nawalkha, G.M. Soto, N.K. Beliaeva, Interest Rate Risk Modeling: The Fixed Income Valuation

Course, John Wiley & Sons, 2005.

[9] C.R. Nelson, A.F. Siegel, “Parsimonious Modeling of Yield Curves”, Journal of Business, Vol. 60-4, 1987.

[10] A. Quarteroni, R. Sacco, F. Saleri, Numerical Mathematics, Springer, 2000.

[11] A.F. Siegel, C.R. Nelson, “Long-Term Behaviour of Yield Curves”, Journal of Financial and Quanti-tative Analysis, Vol. 23-1, 1988.

[12] O.A. Vasicek, H.G. Fong, “Term Structure Modeling Using Exponential Splines”, The Journal of Finance, Vol. XXXVII-2, 1982.

References

Related documents

organisasjonslæring, arbeidsplasslæring, uformell og formell læring, læring gjennom praksis, sosial praksis og så videre vil derfor være nyttige når man skal foreta en studie

mectant), (emollient), (protein reju- 와 같이 다양한 종류가 있다 환자들의 연령 및 습 venator). 진의 형태에 따라 적절한 보습제를 선택하여야 한다 보습.

Histogram equalization is a common method for enhancing the contrast of image. The method defines a mapping of grey levels p into grey levels q which attempts to uniformly

Тип ресурсу Призначення Алфавітний підхід Статистичний підхід Семантичний підхід Файлова система Персональний ресурс Автоматично Не застосовується

As consequence, this paper contains a study on the effect of the rotor bar number on the torque (average and quality) of five-phase induction machines under different supply

Dilatation of the urinary tract has not been reported in adults or children with psychogenic polydipsia.29 This may be due, in part, to incom plete study of these patients

The Highway Safety Strategic Plan Committee, the Metropolitan Planning Organizations, the Motor Carrier Safety Assistance Program Committee, the Traffic Records Coordinating Council,

who is previously considered as a non-resident and who arrives in the Philippines at anytime during the taxable year to reside thereat permanently shall be