Products & Services Solutions Academia Support User Community Company

Learn more about Fixed-Income Toolbox   

Creating an IRFunctionCurve Object

Using a Function Handle to Fit an IRFunctionCurve Object

You can use the constructor IRFunctionCurve with a MATLAB function handle to define an interest-rate curve. For more information on defining a function handle, see the MATLAB Programming Fundamentals documentation.

Example

This example uses a FunctionHandle argument with a value @(t) t.^2 to construct an interest-rate curve:

rr = IRFunctionCurve('Zero',today,@(t) t.^2);
rr = 

  Properties:
    FunctionHandle: @(t)t.^2
              Type: 'Zero'
            Settle: 733600
       Compounding: 2
             Basis: 0

Using the Nelson-Siegel Method to Fit an IRFunctionCurve Object

Use the method, fitNelsonSiegel, for the Nelson-Siegel model that fits the empirical form of the yield curve with a prespecified functional form of the spot rates which is a function of the time to maturity of the bonds.

The Nelson-Siegel model represents a dynamic three-factor model: level, slope, and curvature. However, the Nelson-Siegel factors are unobserved, or latent, which allows for measurement error, and the associated loadings have economic restrictions (forward rates are always positive, and the discount factor approaches zero as maturity increases). For more information, see "Zero-coupon yield curves: technical documentation," BIS Papers, Bank for International Settlements, Number 25, October, 2005.

Example

This example uses IRFunctionCurve to model the default-free term structure of interest rates in the United Kingdom.

Load the data:

load ukdata20080430

Convert repo rates to be equivalent zero coupon bonds:

RepoCouponRate = repmat(0,size(RepoRates));
RepoPrice = bndprice(RepoRates, RepoCouponRate, RepoSettle, RepoMaturity);

Aggregate the data:

Settle = [RepoSettle;BondSettle];
Maturity = [RepoMaturity;BondMaturity];
DirtyPrice = [RepoPrice;BondDirtyPrice];
CouponRate = [RepoCouponRate;BondCouponRate];
Instruments = [Settle Maturity DirtyPrice CouponRate];
InstrumentPeriod = [repmat(0,6,1);repmat(2,31,1)];
CurveSettle = datenum('30-Apr-2008');

The IRFunctionCurve object provides the capability to fit a Nelson-Siegel curve to observed market data with the fitNelsonSiegel method. The fitting is done by calling the Optimization Toolbox function lsqnonlin. This method has required inputs of Type, Settle, and a matrix of instrument data.

NSModel = IRFunctionCurve.fitNelsonSiegel('Zero',CurveSettle,...
Instruments,'Compounding',-1,'InstrumentPeriod',InstrumentPeriod);
Settle = [RepoSettle;BondSettle];
Maturity = [RepoMaturity;BondMaturity];
DirtyPrice = [RepoPrice;BondDirtyPrice];
CouponRate = [RepoCouponRate;BondCouponRate];
Instruments = [Settle Maturity DirtyPrice CouponRate];
InstrumentPeriod = [repmat(0,6,1);repmat(2,31,1)];
CurveSettle = datenum('30-Apr-2008');

Plot the Nelson-Siegel interest-rate curve for forward rates:

PlottingDates = CurveSettle+20:30:CurveSettle+365*25;
TimeToMaturity = yearfrac(CurveSettle,PlottingDates);
NSForwardRates = NSModel.getForwardRates(PlottingDates);
plot(TimeToMaturity,NSForwardRates)
title('Nelson Siegel model of UK instantaneous nominal forward curve')

Using the Svensson Method to Fit an IRFunctionCurve Object

Use the method, fitSvensson, for the Svensson model to improve the flexibility of the curves and the fit for a Nelson-Siegel model. In 1994, Svensson extended Nelson and Siegel's function by adding a further term that allows for a second "hump." The extra precision is achieved at the cost of adding two more parameters, β3 and τ2, which have to be estimated.

Example

In this example of using the fitSvensson method, an IRFitOptions structure, previously defined using the IRFitOptions constructor, is used. Thus, you must specify FitType, InitialGuess, UpperBound, LowerBound, and the OptOptions optimization parameters for lsqnonlin.

Load the data:

load ukdata20080430

Convert repo rates to be equivalent zero coupon bonds:

RepoCouponRate = repmat(0,size(RepoRates));
RepoPrice = bndprice(RepoRates, RepoCouponRate, RepoSettle, RepoMaturity);

Aggregate the data:

Settle = [RepoSettle;BondSettle];
Maturity = [RepoMaturity;BondMaturity];
DirtyPrice = [RepoPrice;BondDirtyPrice];
CouponRate = [RepoCouponRate;BondCouponRate];
Instruments = [Settle Maturity DirtyPrice CouponRate];
InstrumentPeriod = [repmat(0,6,1);repmat(2,31,1)];
CurveSettle = datenum('30-Apr-2008');

Define OptOptions for the IRFitOptions constructor:

OptOptions = optimset('lsqnonlin');
OptOptions = optimset(OptOptions,'MaxFunEvals',1000);
fIRFitOptions = IRFitOptions([5.82 -2.55 -.87 0.45 3.9 0.44],...
'FitType','durationweightedprice','OptOptions',OptOptions,...
'LowerBound',[0 -Inf -Inf -Inf 0 0],'UpperBound',[Inf Inf Inf Inf Inf Inf]);

Fit the interest-rate curve using a Svensson model:

SvenssonModel = IRFunctionCurve.fitSvensson('Zero',CurveSettle,...
Instruments,'IRFitOptions',fIRFitOptions, 'Compounding',-1,...
'InstrumentPeriod',InstrumentPeriod);

Local minimum possible.

lsqnonlin stopped because the final change in the sum of squares relative to 
its initial value is less than the selected value of the function tolerance.

The status message, output from lsqnonlin, indicates that the optimization to find parameters for the Svensson equation terminated successfully.

Plot the Svensson interest-rate curve for forward rates:

PlottingDates = CurveSettle+20:30:CurveSettle+365*25;
TimeToMaturity = yearfrac(CurveSettle,PlottingDates);
SvenssonForwardRates = SvenssonModel.getForwardRates(PlottingDates);
plot(TimeToMaturity,SvenssonForwardRates)
title('Svensson model of UK instantaneous nominal forward curve')

Using the Smoothing Spline Method to Fit an IRFunctionCurve Object

Use the method, fitSmoothingSpline, to model the term structure with a spline, specifically, the term structure represents the forward curve with a cubic spline.

Example

The IRFunctionCurve object is used to fit a smoothing spline representation of the forward curve with a penalty function. Required inputs are Type, Settle, the matrix of Instruments, and Lambdafun, a function handle containing the penalty function

Load the data:

load ukdata20080430

Convert repo rates to be equivalent zero coupon bonds:

RepoCouponRate = repmat(0,size(RepoRates));
RepoPrice = bndprice(RepoRates, RepoCouponRate, RepoSettle, RepoMaturity);

Aggregate the data:

Settle = [RepoSettle;BondSettle];
Maturity = [RepoMaturity;BondMaturity];
DirtyPrice = [RepoPrice;BondDirtyPrice];
CouponRate = [RepoCouponRate;BondCouponRate];
Instruments = [Settle Maturity DirtyPrice CouponRate];
InstrumentPeriod = [repmat(0,6,1);repmat(2,31,1)];
CurveSettle = datenum('30-Apr-2008');

Choose parameters for Lambdafun:

L = 9.2;
S = -1;
mu = 1;

Define the Lambdafun penalty function:

lambdafun = @(t) exp(L - (L-S)*exp(-t/mu));
t = 0:.1:25;
y = lambdafun(t);
figure
semilogy(t,y);
title('Penalty Function for VRP Approach')
ylabel('Penalty')
xlabel('Time')

Use the fitSmoothinSpline method to fit the interest-rate curve and model the Lambdafun penalty function:

VRPModel = IRFunctionCurve.fitSmoothingSpline('Forward',CurveSettle,...
Instruments,lambdafun,'Compounding',-1, 'InstrumentPeriod',InstrumentPeriod);

The plot demonstrates the interest-rate curve with the penalty function.

Plot the smoothing spline interest-rate curve for forward rates:

PlottingDates = CurveSettle+20:30:CurveSettle+365*25;
TimeToMaturity = yearfrac(CurveSettle,PlottingDates);
VRPForwardRates = VRPModel.getForwardRates(PlottingDates);
plot(TimeToMaturity,VRPForwardRates)
title('Smoothing Spline model of UK instantaneous nominal forward curve')

Using the fitFunction to Create a Custom Fitting Function for an IRFunctionCurve Object

When using an IRFunctionCurve object, you can create a custom fitting function with the fitFunction method. To use fitFunction, you must define a FunctionHandle. In addition, you must also use the constructor IRFitOptions to define IRFitOptionsObj to support an InitialGuess for the parameters of the curve function.

Example

The following example demonstrates the use of fitFunction with a FunctionHandle and an IRFitOptionsObj:

Settle = repmat(datenum('30-Apr-2008'),[6 1]);
Maturity = [datenum('07-Mar-2009');datenum('07-Mar-2011');...
datenum('07-Mar-2013');datenum('07-Sep-2016');...
datenum('07-Mar-2025');datenum('07-Mar-2036')];

DirtyPrice = [100.1;100.1;100.8;96.6;103.3;96.3];
CouponRate = [0.0400;0.0425;0.0450;0.0400;0.0500;0.0425];
Instruments = [Settle Maturity DirtyPrice CouponRate];
CurveSettle = datenum('30-Apr-2008');

Define the FunctionHandle:

functionHandle = @(t,theta) polyval(theta,t);

Define the OptOptions for IRFitOptions:

OptOptions = optimset('lsqnonlin');
OptOptions = optimset(OptOptions,'display','iter');

Define fitFunction:

CustomModel = IRFunctionCurve.fitFunction('Zero', CurveSettle, ...
functionHandle,Instruments, IRFitOptions([.05 .05 .05],'FitType','price',...
'OptOptions',OptOptions));

                                        Norm of      First-order 
 Iteration  Func-count     f(x)          step          optimality   CG-iterations
     0          4         38036.7                     4.92e+004
     1          8         38036.7             10      4.92e+004            0
     2         12         38036.7            2.5      4.92e+004            0
     3         16         38036.7          0.625      4.92e+004            0
     4         20         38036.7        0.15625      4.92e+004            0
     5         24         30741.5      0.0390625      1.72e+005            0
     6         28         30741.5       0.078125      1.72e+005            0
     7         32         30741.5      0.0195312      1.72e+005            0
     8         36         28713.6     0.00488281      2.33e+005            0
     9         40         20323.3     0.00976562      9.47e+005            0
    10         44         20323.3      0.0195312      9.47e+005            0
    11         48         20323.3     0.00488281      9.47e+005            0
    12         52         20323.3      0.0012207      9.47e+005            0
    13         56         19698.8    0.000305176      1.08e+006            0
    14         60           17493    0.000610352         7e+006            0
    15         64           17493      0.0012207         7e+006            0
    16         68           17493    0.000305176         7e+006            0
    17         72         15455.1   7.62939e-005      2.25e+007            0
    18         76         15455.1    0.000177558      2.25e+007            0
    19         80         13317.1    3.8147e-005      3.18e+007            0
    20         84         12867.9   7.62939e-005      7.84e+007            0
    21         88         11779.8   7.62939e-005      7.58e+006            0
    22         92         11747.6    0.000152588      1.46e+005            0
    23         96         11720.9    0.000305176      2.48e+005            0
    24        100         11667.2    0.000610352      1.48e+005            0
    25        104         11558.5      0.0012207      4.47e+005            0
    26        108         11335.4     0.00244141      1.58e+005            0
    27        112           10864     0.00488281      1.61e+005            0
    28        116         9797.68     0.00976562      6.85e+005            0
    29        120         6884.03      0.0195312      5.79e+005            0
    30        124         6884.03       0.037498      5.79e+005            0
    31        128         3216.51     0.00937449      1.75e+006            0
    32        132         607.317       0.018749      2.94e+006            0
    33        136         12.7284      0.0253662         3e+006            0
    34        140       0.0760939     0.00153457      4.88e+004            0
    35        144       0.0731652   3.58678e-006           24.6            0
    36        148       0.0731652   6.04329e-008         0.0213            0

Local minimum possible.

lsqnonlin stopped because the final change in the sum of squares relative to 
its initial value is less than the selected value of the function tolerance.

Plot the custom function that is defined using fitFunction:

Yields = bndyield(DirtyPrice,CouponRate,Settle(1),Maturity);
scatter(Maturity,Yields);
PlottingPoints = min(Maturity):30:max(Maturity);
hold on;
plot(PlottingPoints,CustomModel.getParYields(PlottingPoints),'r');
datetick
legend('Market Yields','Fitted Yield Curve')
title('Custom Function fit to Market Data')

  


Free Interactive Computational Finance CD

View demos and recorded presentations led by industry experts.

Now On Demand
Network with industry peers and learn the latest applications of the leading software product for computational finance.

 © 1984-2009- The MathWorks, Inc.    -   Site Help   -   Patents   -   Trademarks   -   Privacy Policy   -   Preventing Piracy   -   RSS