Está en la página 1de 5

Vasicek short rate interest rate model

Before we enter in the programming subject we have to make some remarks related to the solution
of the Vasicek equation: = ( ) + .

The solution is : = + (0 ) + 0 () .

Since we have a deterministic function inside the stochastic integral with respect to the Brownian
motion ( )0 then is Gaussian, with mean the first part, + (0 ) and Variance 2
1 2
2
.

Hence,in order to simulate ,namely the trajectories of the process for different times, we have to
1 2
simulate a ( + (0 ), 2 2
) random variable.

1 2
In this way, = + (0 ) + 2
, ~(0,1)r.v.

For that, first I will use a N(0,1) generator(C++ code):


#include <cmath>
double random_uniform_0_1(void)
{
return double(rand()) / double(RAND_MAX);//(C built-in random number generator)
}

double random_normal(void)
{
double U1, U2, V1, V2;
double S = 2;
while (S >= 1)
{
U1 = random_uniform_0_1();//no parameters since it has void as argument;
U2 = random_uniform_0_1();
V1 = 2.0*U1 - 1.0;
V2 = 2.0*U2 - 1.0;
S = pow(V1, 2) + pow(V2, 2);
};
double X1 = V1*sqrt((-2.0*log(S)) / S);
return X1;
}

This is Box-Muller method in cartesian coordinates.


We go further to the Vasicek rate simulation.
double simulate_vasicek_random_variable(double r0, double theta, double a, double b,
double sigma)
{
double R = b + (r0 - b)*exp(-a*theta);
double S = sigma*sqrt((1 - exp(-2 * a*theta)) / (2 * a));
return R + S*random_normal();
}//r0 is the initial rate,theta=time to maturity,a,b,sigma are the Vasicek parameters.
Also, for zero rate we following function:
double zero_rate(double r, double theta, double a, double b, double sigma,double lambda)
{
double r_infty = b - (sigma*lambda) / a - sigma*sigma / (2 * a*a*a);
double rate = r_infty - (r_infty - r)*((1 - exp(-a*theta)) / theta) +
(sigma*sigma) / (4 * a*a*a*theta)*(1 - exp(-a*theta))*(1 - exp(-a*theta));
return rate;
}

In this project case, I simulate inside C++ the Vasicek rate, but export for further usage outside
to VBA.
Inside the C DLL(dynamic library) export project I will make two files: term_structure_rate.h
and term_structure_rate.cpp.
Inside term_structure.h:
#define M2API __declspec(dllexport)
extern "C"
{
M2API double __stdcall term_structure_discount_factor_yield(double r, double t);
M2API double __stdcall term_structure_forward_rate(double d_t1, double d_t2,
double time);
M2API double __stdcall option_price_call_european( double S, double K, double r,
double sigma,
double time, int no_sims);
M2API double __stdcall lognormal_simulate(double S, double r, double sigma, double
time);
M2API double __stdcall vasicek_simulate(double r0, double theta, double a, double
b, double sigma);
M2API double __stdcall zero_coupon_rate(double r, double theta, double a, double
b, double sigma, double lambda);
}

The functions of interest are the last two, the rest are used for other purposes.
Inside term_structure_dll.cpp:
#include "term_structure_dll.h"

//also other files from other projects

double __stdcall vasicek_simulate(double r0, double theta, double a, double b, double


sigma)

{
return simulate_vasicek_random_variable(r0, theta, a, b, sigma);
}
double __stdcall zero_coupon_rate(double r, double theta, double a, double b, double
sigma, double lambda)
{
return zero_rate(r, theta, a, b, sigma, lambda);
}

//theta is the time to maturiy,lambda is the market price of risk of interest rate.

]
VBA: code part.
First,we have 2 declare there functions:
Declare Function simulate_vasicek Lib _
"C:\Users\theodor\Documents\Visual Studio
2015\Projects\term_structure_dll\Debug\term_structure_c_dll.dll" Alias _
"_vasicek_simulate@40" (ByVal r0 As Double, ByVal theta As Double, ByVal a As
Double, ByVal b As Double, ByVal sigma As Double) As Double
Declare Function zero_rate Lib _
"C:\Users\theodor\Documents\Visual Studio
2015\Projects\term_structure_dll\Debug\term_structure_c_dll.dll" Alias _
"_zero_coupon_rate@48" (ByVal r As Double, ByVal theta As Double, ByVal a As
Double, ByVal b As Double, ByVal sigma As Double, ByVal lambda As Double) As
Double
'lambda is the market price of interest_rate_risk'

Before creating command buttons or userforms we test these functions:


In the first column of sheet2 Ive created manually a column with the number of days expressed
as integers, considering after that 1Y=360 days(although the financial year is 252 days).
Sub test4()
Sheet2.Activate
For i = 1 To 13
Sheet2.Cells(i + 1, 2).Value = simulate_vasicek(0.1, (Sheet2.Cells(i + 1,
1).Value) / 360#, 0.1, 0.13, 0.25)
Next i
End Sub

However, the way weve written the simulation gives extreme values occurences:
vasicek interest rate
0.4

0.35

0.3

0.25

0.2

0.15

0.1

0.05

0
1 2 3 4 5 6 7 8 9 10 11 12 13
If I want to build the zero rates, along with some rates from the vasicek equation:

Sub test_zero_rate_vasicek()
For i = 1 To 13
r = simulate_vasicek(0.1, (Sheet2.Cells(i + 1, 1).Value) / 360#, 0.1, 0.13, 0.25)
Sheet2.Cells(i + 1, 2).Value = r
Sheet2.Cells(i + 1, 3).Value = zero_rate(r, 0.2, 0.3, 0.12, 0.25, 0.2)
Next i
End Sub

We will use now MC simulation of Vasicek int_rate:

Function MC_vasicek(ByVal r0 As Double, ByVal theta As Double, ByVal a As


Double, ByVal b As Double, ByVal sigma As Double, ByVal no_sims As Integer)
As Double
S = 0#
For i = 1 To no_sims
S = S + simulate_vasicek(r0, theta, a, b, sigma)
Next i
MC_vasicek = S / no_sims
End Function

In the continuation I will create an userform that takes the values of r0,alpha,beta,sigma and will
generate on specific columns the vasicek Monte Carlo rates and the corresponding
zero_coupon_rates:

The userform will look like this:


For each button we have a specific code:

Private Sub CommandButton1_Click() 'generating Vasicek interest rates and


also
Dim n As Integer
n = InputBox("enter the number of simulations for each vasicek rate sample")
For i = 1 To 13
Sheet2.Cells(i + 1, 4).Value = MC_vasicek(TextBox1.Value, Sheet2.Cells(i + 1,
1) / 360#, TextBox2.Value, TextBox3.Value, TextBox4.Value, n)
Next i
Dim lambda As Double
lambda = InputBox("Give the market price of risk")
For i = 1 To 13
Sheet2.Cells(i + 1, 5).Value = zero_rate(Sheet2.Cells(i + 1, 4),
Sheet2.Cells(i + 1, 1) / 360#, TextBox1.Value, TextBox2.Value,
TextBox3.Value, lambda)
Next i
End Sub

For the Close button the code is:


Private Sub CommandButton2_Click() 'corresponding to close button
Unload Me
End Sub

For the activation of the userform the command button from the Worksheet must have the
following code:
Private Sub CommandButton1_Click()
UserForm1.Show
End Sub

También podría gustarte