El modelo Vasicek se utiliza para predecir los tipos de interés a largo plazo mediant la simulación de tipos de interés a corto plazo. Tiene en cuenta que los tipos de interés son distintos en diferentes períodos de tiempo
Función auxiliar que calcula la próxima tasa en función de la discretización del modelo Varice.
r: La tasa de interés utilizada para generar la siguiente tasa de interés.
kappa: La tasa de reversión media.
theta: La tasa media o tasa a largo plazo.
sigma : Volatilidad.
dt: El cambio de tiempo entre observaciones. El valor predeterminado es 1/252 porque asumimos la generación de tarifas diarias y hay 252 días de negociación por año.
Devoluciones: Un vector de tasas cortas simuladas.
VasicekHelper <- function(r, kappa, theta, sigma, dt = 1/252) {
term1 <- exp(-1 * kappa * dt)
term1 <- exp(-1 * kappa * dt)
term2 <- (sigma^2) * (1 - term1^2) / (2*kappa)
result <- r*term1 + theta*(1-term1) + sqrt(term2)*rnorm(n=1)
return(result)
}
Genera una sola simulación de tasa corta utilizando el modelo Vasicek.
N: El número de puntos a generar en cada simulación. Por ejemplo, el número de días al simular tarifas diarias.
r0: La tasa de interés inicial.
Devoluciones: Un vector de tasas cortas simuladas.
VasicekSimulation <- function(N, r0, kappa, theta, sigma, dt = 1/252) {
short.rates <- rep(0, N)
short.rates[1] <- r0
for (i in 2:N) {
short.rates[i] <- VasicekHelper(short.rates[i - 1], kappa, theta, sigma, dt)
}
return(short.rates)
}
Genera varias simulaciones de tasa corta utilizando el modelo Vasicek.
M: El número de simulaciones a ejecutar.
N: El número de puntos a generar en cada simulación. Por ejemplo,el número de días al simular tarifas diarias.
Devoluciones: Una matriz de N filas por M columnas de tasas cortas simuladas.
VasicekSimulations <- function(M, N, r0, kappa, theta, sigma, dt = 1/252) {
sim.mat <- matrix(nrow = N, ncol = M)
for (i in 1:M) {
sim.mat[, i] <- VasicekSimulation(N, r0, kappa, theta, sigma, dt)
}
return(sim.mat)
}
Calcula el precio del bono cupón cero.
años: La duración o vencimiento del bono.
Devoluciones: Un precio decimal del bono (es decir, 0,98 por 98).
VasicekZeroCouponBondPrice <- function(r0, kappa, theta, sigma, years) {
b.vas <- (1-exp(-years*kappa)) / kappa
a.vas <- (theta-sigma^2/(2*kappa^2))*(years-b.vas)+(sigma^2)/(4*kappa)*b.vas^2
return(exp(-a.vas-b.vas*r0))
}
Produce una curva de rendimiento del modelo de Vasicek con vencimientos que van desde 1 año hasta vencimiento máximo.
max.maturity: Vencimiento máximo en años (debe ser entero).
Devoluciones: Un precio decimal del bono (es decir, 0,98 por 98).
VasicekYieldCurve <- function(r0, kappa, theta, sigma, max.maturity=10) {
yields <- rep(0, max.maturity)
for (y in 1:max.maturity) {
yields[y] <- -log(VasicekZeroCouponBondPrice(r0, kappa, theta, sigma, y))/y
}
return(yields)
}
Calibra el modelo vasicek utilizando el estimador de máxima verosimilitud. #### Argumentos:
fred.ticker: Ticker utilizado para descargar las tasas históricas de la Federal Banco de Reserva de St. Louis. Predeterminado a DSG3MO, los 3 meses
Tasa de Vencimiento Constante del Tesoro.
Devoluciones:Un vector de la forma c(kappa, theta, sigma, r0), donde kappa es la media tasa de reversión, theta es la tasa/media a largo plazo, sigma es la volatilidad y r0 es la última tasa observada.
Requiere:quantmod
VasicekCalibration <- function(fred.ticker = 'DGS3MO', dt = 1/252) {
require(quantmod)
data <- getSymbols(fred.ticker, src = 'FRED', auto.assign = FALSE)
data <- na.omit(data)/100 # FRED cita 1,00% como 1,00 en lugar de 0,01
n <- length(data)
Sx <- sum(data[1:(length(data) - 1)])
Sy <- sum(data[2:length(data)])
Sxx <- as.numeric(crossprod(data[1:(length(data) - 1)], data[1:(length(data) - 1)]))
Sxy <- as.numeric(crossprod(data[1:(length(data) - 1)], data[2:length(data)]))
Syy <- as.numeric(crossprod(data[2:length(data)], data[2:length(data)]))
theta <- (Sy * Sxx - Sx * Sxy) / (n* (Sxx - Sxy) - (Sx^2 - Sx*Sy) )
kappa <- -log((Sxy - theta * Sx - theta * Sy + n * theta^2) / (Sxx - 2 * theta * Sx + n * theta^2)) / dt
a <- exp(-kappa*dt)
sigmah2 <- (Syy - 2 * a * Sxy + a^2 * Sxx - 2 * theta * (1-a) * (Sy - a * Sx) + n * theta^2 * (1 - a)^2)/n
sigma <- sqrt(sigmah2 * 2 * kappa / (1 - a^2))
r0 <- data[length(data)]
return(c(kappa, theta, sigma, r0))
}
Se defininen los parámetros del modelo y se calibran para poder gráficar
## Loading required package: quantmod
## Warning: package 'quantmod' was built under R version 4.2.2
## Loading required package: xts
## Warning: package 'xts' was built under R version 4.2.2
## Loading required package: zoo
##
## Attaching package: 'zoo'
## The following objects are masked from 'package:base':
##
## as.Date, as.Date.numeric
## Loading required package: TTR
## Warning: package 'TTR' was built under R version 4.2.2
## Registered S3 method overwritten by 'quantmod':
## method from
## as.zoo.data.frame zoo
Prueba con 20 simulaciones en donde se puede observar la tasa esperada
## [1] 0.8599499