Se eliminan los mensajes de precaución y de descarga de paquetes.
options(warn = -1)
suppressPackageStartupMessages({
library(knitr)
library(plotly)
library(dplyr)
library(ggplot2)
library(plotly)
library(moments)
library(magrittr)
library(stats)
library(tidyverse)
})
Se analiza la serie diaria TRM desde 2000-01-31, hasta 2022-09-17
Datos_TRM = read.table("C:/Users/57314/Downloads/DB_TRM.txt", header = TRUE)
# Guardar el archivo como un archivo HTML
library(knitr)
# Convertir la tabla a HTML
html_TRM <- kable(Datos_TRM, format = "html")
# Guardar el código HTML en un archivo
write(html_TRM, "tabla_trm.html")
head(Datos_TRM)
## Fecha TRM
## 1 01/01/2000 1873.77
## 2 02/01/2000 1873.77
## 3 03/01/2000 1873.77
## 4 04/01/2000 1874.35
## 5 05/01/2000 1895.97
## 6 06/01/2000 1912.69
install.packages("moments")
library(moments)
library(tidyverse)
library(magrittr)
TRM = Datos_TRM[,2]
resumen_trm <- Datos_TRM %>%
mutate(media_trm = mean(TRM),
mediana_trm = median(TRM),
desviacion_estandar_trm = sd(TRM),
rango_trm = max(TRM) - min(TRM),
varianza_trm = var(TRM),
coeficiente_variacion_trm = sd(TRM) / mean(TRM),
rendimiento_anualizado = (mean(TRM) - 1) * 100,
volatilidad_anual = sd(TRM) * sqrt(252),
cuantiles = quantile(TRM, probs = 0.25:0.75),
sesgo = skewness(TRM),
curtosis = kurtosis(TRM),
minimo = min(TRM),
maximo = max(TRM)
)
# Seleccionar solo las columnas que no son Fecha ni TRM
estadistica_trm <- resumen_trm %>%
select(-c(Fecha, TRM))
fila_unica <- do.call(c, estadistica_trm)
print(head(estadistica_trm, n = 1))
## media_trm mediana_trm desviacion_estandar_trm rango_trm varianza_trm
## 1 2553.402 2345.47 643.277 2975.05 413805.3
## coeficiente_variacion_trm rendimiento_anualizado volatilidad_anual cuantiles
## 1 0.2519294 255240.2 10211.71 1974.47
## sesgo curtosis minimo maximo
## 1 0.7478894 2.685184 1652.41 4627.46
rendimientos_diarios <- diff(log(Datos_TRM$TRM))
• Media: La TRM promedio durante el período 2000-2022 fue de $2660.966 COP por USD.
• Mediana: El valor de la TRM que representa el valor “del medio” en un conjunto de datos ordenados durante el período 2000-2022 fue de $2389.75 COP por USD.
• Desviación estándar: La desviación estándar de la TRM fue de $762.4161 COP por USD, lo que significa que en promedio el precio de la TRM puede subir o bajar $762.4161 en un día.
• Máximo: El valor máximo de la TRM fue de $5061.21 COP por USD.
• Mínimo: El valor mínimo de la TRM fue de $1652.41 COP por USD.
• La tendencia de la TRM ha sido creciente durante el período de tiempo analizado.
• El aumento de la TRM se ha visto afectada por varios factores tanto internos como externos:
• La economía estadounidense ha experimentado un crecimiento durante estos años, acompañado de que la Reserva Federal ha trabajado en que el dólar sea una moneda atractiva para invertir (aumento de las tasas de interés), por esto su precio frente a otras monedas ha aumentado.
• Debido a los diferentes conflictos en países productores de petróleo, su precio ha sido muy volátil, lo que puede conducir a una depreciación de la TRM.
• Los conflictos económicos globales como la guerra de Ucrania o la crisis financiera en USA del 2008, hacen que los inversores busquen activos de bajo riesgo para invertir como las divisas, por ejemplo, el dólar estadounidense.
• La pandemia de COVID-19 en 2020 generó incertidumbre económica global, lo que generó una depreciación del peso colombiano frente al dólar.
• En Colombia los bienes importados son mayores a los exportados, por esto existe un déficit en cuenta corriente, lo que genera un alza en la TRM.
• En los últimos años la inflación en Colombia ha sido superior a la de Estados Unidos esto hace que el peso colombiano pierda poder adquisitivo frente al dólar.
• Cuando el Banco de la República emite pesos para aumentar la oferta de dinero, puede conducir a una depreciación de la moneda.
La TRM tiene una autocorrelación positiva, lo que significa que los valores actuales de la TRM están correlacionados con los valores pasados.
• Sesgo: El sesgo de la TRM es de 0.8964715, lo que indica una ligera asimetría a la derecha.
• Curtosis:La curtosis de la TRM es de 3.040295, lo que indica una distribución ligeramente más aplanada que la normal.
#Graficar los datos
Se realiza la gráfica de la Serie Histórica TRM
library(ggplot2)
library(plotly)
if (!is.data.frame(Datos_TRM)) {
stop("Datos_TRM no es un data frame. Por favor, proporcione datos de series de tiempo.")
} else {
if (!("index" %in% names(Datos_TRM))) {
Datos_TRM$index <- 1:nrow(Datos_TRM)
}
}
ggplot_obj <- ggplot(Datos_TRM, aes(x = index, y = TRM)) +
geom_line(color = "lightblue") +
labs(title = "Serie Histórica TRM", x = "Fecha", y = "Valor") +
theme_minimal() +
theme(panel.border = element_blank())
p <- ggplotly(ggplot_obj)
p
Se realiza la gráfica de la Densidad Empírica de los Precios y de los Retornos
# Calcular la densidad empírica de los precios TRM
densidad_empirica <- density(TRM)
# Crear un data frame con los valores de la densidad
df_densidad <- data.frame(
x = densidad_empirica$x,
y = densidad_empirica$y
)
# Graficar la densidad empírica
ggplot_obj <- ggplot(data = df_densidad, aes(x = x, y = y)) +
geom_line(color = "lightblue", size = 1.5) +
geom_point(aes(tooltip = paste0("Valor TRM: ", x, "\nDensidad: ", round(y, 4))), color = "lightblue", size = 3) +
geom_vline(xintercept = TRM[length(TRM)], color = "black", linetype = "dashed") +
labs(title = "Densidad Empírica de Precios TRM",
x = "Valor TRM",
y = "Densidad") +
theme_minimal() +
theme(plot.title = element_text(hjust = 0.5))
plotly_densidad <- ggplotly(ggplot_obj)
plotly_densidad
# Calcular la densidad empírica de los retornos
densidad_retornos <- density(rendimientos_diarios)
# Crear un data frame con los valores de la densidad
df_densidad_retornos <- data.frame(
x = densidad_retornos$x,
y = densidad_retornos$y
)
ggplot_obj <- ggplot(data = df_densidad_retornos, aes(x = x, y = y)) +
geom_line(color = "lightblue", size = 1.5) +
geom_point(aes(tooltip = paste0("Retorno diario: ", x, "\nDensidad: ", round(y, 4))), color = "lightblue", size = 3) +
geom_vline(xintercept = 0, color = "black", linetype = "dashed") +
labs(title = "Densidad Empírica de Retornos Diarios",
x = "Retorno diario",
y = "Densidad") +
theme_minimal() +
theme(plot.title = element_text(hjust = 0.5))
plotly_densidad_retornos <- ggplotly(ggplot_obj)
plotly_densidad_retornos
Cuánto miden los precios y los retornos
length(TRM)
## [1] 8296
length(rendimientos_diarios)
## [1] 8295
Media anualizada
Media_Rtos = mean(rendimientos_diarios)*252
Desviación Estandar anualizada
Desv_Rtos = sd(rendimientos_diarios)*sqrt(252)
Sesgo
Sesgo_Rtos = skewness(rendimientos_diarios)
Curtosis
Curtosis = kurtosis(rendimientos_diarios)
Simulación de los precios a 5 meses
t = 5/12
delta_t = 1/252
N = t/delta_t
M = 10000
S = matrix(ncol = M, nrow = (N+1))
volatilidad = sd(diff(log(TRM)))
mu = mean(diff(log(TRM)))
Se toma el último valor de la serie de precios
S[1,] = 4435.84
S0 <- 4435.84
# Simulación de la dinámica del precio
for (i in 1:M) {
for (t in 2:(N + 1)) {
S[t, i] <- S[(t - 1), i] * exp((Media_Rtos - Desv_Rtos^2 / 2) * delta_t + Desv_Rtos * sqrt(delta_t) * rnorm(1))
}
}
matplot(S, type = "l",
main = "Distribución Empírica",
xlab = "Tiempo",
ylab = "Precio")+
theme_minimal()
## NULL
S <- matrix(NA, nrow = N + 1, ncol = M)
S[1, ] <- S0
for (i in 1:M) {
for (j in 1:N) {
epsilon <- rnorm(1)
dW <- epsilon * sqrt(delta_t)
S[j + 1, i] <- S[j, i] * exp((mu - 0.5 * volatilidad^2) * delta_t + volatilidad * dW)
}
}
Proyeccion1 = matrix(nrow = (8296 + 105), ncol = 1)
Proyeccion1[1: 8296] = TRM
matplot(Proyeccion1, type="l", ylim = c(1500, 5000))
title("Proyección")
lines(Proyeccion1, col = "lightblue", type = "l")
Proyeccion2 = matrix(nrow = (8296 + 105), ncol = M)
Proyeccion2[8296:8401] = S
matlines(Proyeccion2, type="l")
install.packages("stats")
library(stats)
alfa=0.05
q1 = quantile(S[(N+1),], (alfa/2))
q2 = quantile(S[(N+1),], (1-alfa/2))
q1
## 2.5%
## 4403.987
q2
## 97.5%
## 4469.147
library(ggplot2)
library(plotly)
# Supongamos que Rtos_TRM contiene los rendimientos diarios
gg_qq <- ggplot(data.frame(rendimientos_diarios = rendimientos_diarios), aes(sample = rendimientos_diarios)) +
stat_qq(color = "lightblue", size = 1.5, pch = 16) +
labs(title = "Gráfico QQ Rendimientos Diarios TRM",
x = "Cuantiles teóricos",
y = "Cuantiles observados") +
theme_minimal() +
theme(plot.title = element_text(size = 14),
axis.title = element_text(size = 12),
axis.text = element_text(size = 10))
# Convierte la gráfica de ggplot a plotly
plotly_qq <- ggplotly(gg_qq)
plotly_qq
Se simuló la distribución empírica de los precios futuros del TRM colombiano utilizando el método MBG.Se define la matriz Proyeccion1 que contiene los valores históricos de la TRM y los 105 días de la proyección. También se define la matriz Proyeccion2 que contiene las simulaciones de la serie de precios a partir del día 8296 (actual).
• La distribución empírica de los precios futuros de la TRM presenta una forma asimétrica con una mayor probabilidad de valores superiores al precio actual.
• La volatilidad anualizada de la tasa de cambio es un factor importante que determina la dispersión de la distribución.
• La incertidumbre alrededor de la proyección es considerable, como se observa en la dispersión de las simulaciones.
mu = mean(S)
sigma = sd(S)
qnorm(c(0.05, 0.95), mu, sigma)
## [1] 4416.642 4455.481
Una empresa exportadora que realizó crédito para ejercer una inversión empresarial el 17 de septiembre de 2022 con los siguientes criterios de pago por parte de su capitalizadora de inversión:
Monto de inversión: 1’790.000 USD Tasa de interés: 10% AMV Cuotas: 24 Frecuencia de pago: Mensual
fecha<- c("17/10/2022","17/11/2022","17/12/2022","17/01/2023","17/02/2023")
pagos<- c(91738,90992,90246,89500,88754)
tabla <- data.frame(fecha = fecha, pagos = pagos)
print(tabla)
## fecha pagos
## 1 17/10/2022 91738
## 2 17/11/2022 90992
## 3 17/12/2022 90246
## 4 17/01/2023 89500
## 5 17/02/2023 88754
La tasa de cambio actual es de 4066 COP. Se sugiere una cobertura del 70% del total del monto de los flujos expuestos a riesgo cambiario. El intermediario financiero IF le ofrece contratos de futuros TRM__F (ver bolsa de valores de Colombia) sugiriendo el uso de los siguientes contratos que se encuentran en la bolsa de valores de Colombia.
mu= mean(rendimientos_diarios)*252
sigma= sd(rendimientos_diarios)*sqrt(252)
T= 5/12 # 5 meses
delta_t=1/252
N=T/delta_t
M= 1000 # Numero de simulaciones
TRM= matrix(ncol=M, nrow = (N+1))
TRM[1,]=4435.84
for(i in 1:M){
for (t in 2:(N+1)){
TRM[t,i]=TRM[(t-1),i]*exp((mu-sigma^2/2)*delta_t+sigma*sqrt(delta_t)*rnorm(1))
}
}
matplot(TRM, type = "l",
main = "Simulación",
xlab = "Tiempo",
ylab = "Precio")+
theme_minimal()
## NULL
Dada la proyección de la TRM, se hace una estimación del valor de las cuotas en COP para cada periodo.
Cuotas_USD = c(91738,90992,90246,89500,88754)
Cuotas_COP=TRM[2,]*Cuotas_USD[1]
for(j in 2:length(Cuotas_USD)){
Cuotas_COP=rbind(Cuotas_COP,TRM[j+1,]*Cuotas_USD[j])
}
media_cuotas=vector()
volatilidad_cuotas=vector()
percentil_5_cuotas=vector()
percentil_95_cuotas=vector()
for(l in 1:5){
media_cuotas[l]=mean(TRM[l+1,]*Cuotas_USD[l])
volatilidad_cuotas[l]=sd(TRM[l+1,]*Cuotas_USD[l])
percentil_5_cuotas[l]=quantile(TRM[l+1,]*Cuotas_USD[l],0.05)
percentil_95_cuotas[l]=quantile(TRM[l+1,]*Cuotas_USD[l],0.95)
}
matplot(Cuotas_COP,type = "l", col="lightblue", main="Estimado Cuotas en COP", ylab = "Valor Cuota", xlab = "Cuota")
lines(percentil_5_cuotas, type = "l")
lines(percentil_95_cuotas, type = "l")
lines(media_cuotas, type = "l")
print("Volatilidad de cada cuota en millones de COP")
## [1] "Volatilidad de cada cuota en millones de COP"
print(volatilidad_cuotas/1000000)
## [1] 2.351191 3.270562 3.894329 4.475130 4.952336
Dado que quien tiene una deuda en USD tiene una posición corta en la tasa de cambio, se debe de tomar una posición larga en los contratos Forward para hacer la cobertura.
Cobertura<-0.7
Precio_Entrega= 4500
Utilidad_POR_USD=TRM[-1,]-Precio_Entrega
matplot(Utilidad_POR_USD,type="l", col="lightblue", main="Utilidad por USD", ylab = "Utilidad (USD)", xlab = "Fecha")
Utilidad_total=Utilidad_POR_USD[1,]*Cuotas_USD[1]*0.7
for(j in 2:length(Cuotas_USD)){
Utilidad_total=rbind(Utilidad_total,Utilidad_POR_USD[j,]*Cuotas_USD[j]*0.7)
}
matplot(Utilidad_total,type="l", col = "lightblue", main="Utilidad Total", ylab = "Utilidad (USD)", xlab = "Fecha")
Cuotas_COP_CON_C=Cuotas_COP-Utilidad_total
media_cuotas_COP_CON_C=vector()
volatilidad_cuotas_COP_CON_C=vector()
percentil_5_cuotas_COP_CON_C=vector()
percentil_95_cuotas_COP_CON_C=vector()
for(l in 1:5){
media_cuotas_COP_CON_C[l]=mean(Cuotas_COP_CON_C[l,])
volatilidad_cuotas_COP_CON_C[l]=sd(Cuotas_COP_CON_C[l,])
percentil_5_cuotas_COP_CON_C[l]=quantile(Cuotas_COP_CON_C[l,],0.05)
percentil_95_cuotas_COP_CON_C[l]=quantile(Cuotas_COP_CON_C[l,],0.95)
}
matplot(Cuotas_COP_CON_C,type = "l", col="lightblue", main="Estimado Cuotas en COP", ylab = "Valor Cuota", xlab = "cuota")
lines(percentil_5_cuotas_COP_CON_C, type = "l")
lines(percentil_95_cuotas_COP_CON_C, type = "l")
lines(media_cuotas_COP_CON_C, type = "l")
print("Volatilidad de cada cuota con cobertura en millones de COP")
## [1] "Volatilidad de cada cuota con cobertura en millones de COP"
print(volatilidad_cuotas_COP_CON_C/1000000)
## [1] 0.7053574 0.9811685 1.1682987 1.3425389 1.4857008
fecha <- c("17/10/2022", "17/11/2022", "17/12/2022", "17/01/2023", "17/02/2023")
valores_TRM <- c(4636.83, 4922.70, 4802.48, 4693.99, 4966.33)
# Crear un vector vacío para almacenar los valores de TRM_OBSERVADA
TRM_OBSERVADA <- numeric(length(fecha))
# Asignar los valores de TRM_OBSERVADA
for (j in 1:length(fecha)) {
TRM_OBSERVADA[j] <- valores_TRM[j]
}
print(TRM_OBSERVADA)
## [1] 4636.83 4922.70 4802.48 4693.99 4966.33
Cuota_Real_COP=TRM_OBSERVADA*Cuotas_USD
matplot(Cuotas_COP,type = "l", col="lightblue", main="Estimado Cuotas en COP", ylab = "Valor Cuota", xlab = "Cuota")
lines(percentil_5_cuotas, type = "l")
lines(percentil_95_cuotas, type = "l")
lines(media_cuotas, type = "l")
lines(Cuota_Real_COP, type = "l",lwd=2)
"Cuota Real COP"
## [1] "Cuota Real COP"
print(Cuota_Real_COP)
## [1] 425373511 447926318 433404610 420112105 440781653
"Beneficio sin cobertura"
## [1] "Beneficio sin cobertura"
Utilidad_POR_USD_Observada=TRM_OBSERVADA-Precio_Entrega
Utilidad_total_observada= Cuotas_USD*Utilidad_POR_USD_Observada
Valor_Observado_Cuotas_con_cobertura=Cuota_Real_COP-Utilidad_total_observada
matplot(Cuotas_COP_CON_C,type = "l", col="lightblue", main="Estimado Cuotas en COP", ylab = "Valor Cuota", xlab = "Cuota")
lines(percentil_5_cuotas_COP_CON_C, type = "l")
lines(percentil_95_cuotas_COP_CON_C, type = "l")
lines(media_cuotas_COP_CON_C, type = "l")
lines(Valor_Observado_Cuotas_con_cobertura, type = "l", lwd=2)
Se deben de definir las variables y las fórmulas a usar:
Numero_de_contratos <- 1
Nominal_del_contrato <- 1790000*0.7
Precio_inicial <- 4066 # TRM al momento 0
Garantia_inicial <- 0.063 #Futuros tasa de cambio BVC
Margen_mantenimiento <- 0.50
Exposicion_Total =Numero_de_contratos*Nominal_del_contrato*Precio_inicial
Valor_de_la_garantia_inicial = Exposicion_Total*Garantia_inicial
Valor_de_la_garantia_minima = Margen_mantenimiento*Valor_de_la_garantia_inicial
Apalancamiento = Exposicion_Total/Valor_de_la_garantia_inicial
Se liquidan los futuros y se nombran las columnas
TRM_Filas <- TRM[c(22, 43, 64, 85, 106), ]
Media_Filas <- rowMeans(TRM_Filas)
Media_TRM <- data.frame(Media_Futuro = Media_Filas)
Tabla_liquidacion <- Media_TRM
Media_TRM$fecha <- fecha
Media_TRM$TRM_OBSERVADA <- TRM_OBSERVADA
Media_TRM <- Media_TRM[, c("fecha", "TRM_OBSERVADA", "Media_Futuro")]
Tabla_liquidacion <- Media_TRM
Dif_Fut_TRM <- diff(Tabla_liquidacion[,3])*-1
Dif_Fut_TRM <- append(0,Dif_Fut_TRM)
Tabla_liquidacion <- cbind(Tabla_liquidacion,(Dif_Fut_TRM*Numero_de_contratos*Nominal_del_contrato))
colnames(Tabla_liquidacion) <- c("Fecha","TRM","Futuro","Liquidacion_Diaria")
Se calcula el llamado al margen
margen <- matrix()
tabaux <- matrix()
Llamado_al_margen <- matrix()
for (i in 1:(nrow(Tabla_liquidacion))) {
# Tabla Auxiliar
tabaux[1]=Valor_de_la_garantia_inicial
tabaux[i+1] <- tabaux[i] + Tabla_liquidacion$Liquidacion_Diaria[i+1]
# Llamado al Margen
Llamado_al_margen[i] <- if(tabaux[i]<Valor_de_la_garantia_minima){Valor_de_la_garantia_inicial-tabaux[i]}
else{0}
# Margen
margen[i] <- tabaux[i]+Llamado_al_margen[i]
}
margen <- na.omit(margen)
Tabla_liquidacion <- cbind(Tabla_liquidacion,margen,Llamado_al_margen,Dif_Fut_TRM)
print(Tabla_liquidacion)
## Fecha TRM Futuro Liquidacion_Diaria margen Llamado_al_margen
## 1 17/10/2022 4636.83 4445.645 0 320965974 0
## 2 17/11/2022 4922.70 4457.082 -14330559 306635415 0
## 3 17/12/2022 4802.48 4470.761 -17139927 289495488 0
## 4 17/01/2023 4693.99 4479.008 -10334000 279161489 0
## 5 17/02/2023 4966.33 4491.262 -15354463 263807026 0
## Dif_Fut_TRM
## 1 0.000000
## 2 -11.436999
## 3 -13.679111
## 4 -8.247406
## 5 -12.254160
Se calcula el número de periodos en los que se realiza una llamada al margen y luego se Calcula la probabilidad de ser llamado al margen
llamadas_al_margen <- sum(Llamado_al_margen > 0)
probabilidad_llamado_al_margen <- llamadas_al_margen / nrow(Tabla_liquidacion)
cat("La probabilidad de ser llamado al margen es:", probabilidad_llamado_al_margen)
## La probabilidad de ser llamado al margen es: 0
La probabilidad de ser llamado al margen si solo se deposita en la cuenta el margen inicial es del 0
Valor_de_la_garantia_minima
## [1] 160482987
Valor_garantia_minima <- 160482987
# Probabilidad máxima deseada
probabilidad_maxima <- 0.01
# Calcular el saldo inicial necesario usando la distribución binomial inversa
saldo_inicial <- qbinom(probabilidad_maxima, size = nrow(Tabla_liquidacion), prob = 0.5) * (-Valor_garantia_minima)
print(paste("El saldo inicial requerido para una probabilidad menor al 1% es:", saldo_inicial))
## [1] "El saldo inicial requerido para una probabilidad menor al 1% es: 0"
La garantía inicial necesaria para que la probabilidad de ser llamado al margen antes de cubrir el primer flujo sea menor al 1% es 0
Se definen los parámetros del modelo
r0_FED <- 0.0387 #19/09/2022 Tasa semestral tomada de: https://home.treasury.gov/resource-center/data-chart-center/interest-rates/TextView?type=daily_treasury_yield_curve&field_tdr_date_value=2022
theta <- 0.08
k <- 0.4
SD_FED <- 0.0094 #Desviación estándar de 3 años, calculada desde el 19/09/2019 hasta el 19/09/2022
Se simulan las trayectorias de Short-Rate
n <- 10 # MC simulation trials
T <- 10 # total time
m <- 252 # subintervals
dt <- T/m # difference in time each subinterval
r <- matrix(0,m+1,n) # matrix to hold short rate paths
r[1,] <- r0_FED
for(j in 1:n){
for(i in 2:(m+1)){
dr <- k*(theta-r[i-1,j])*dt + SD_FED*sqrt(dt)*rnorm(1,0,1)
r[i,j] <- r[i-1,j] + dr
}
}
Se grafican los resultados
t <- seq(0, T, dt)
rT.expected <- theta + (r0_FED-theta)*exp(-k*t)
rT.stdev <- sqrt( SD_FED^2/(2*k)*(1-exp(-2*k*t)))
matplot(t, r[,1:10], type="l", lty=1, main="Short Rate Paths", ylab="rt")
abline(h=theta, col="lightblue", lty=2)
lines(t, rT.expected, lty=2)
lines(t, rT.expected + 2*rT.stdev, lty=2)
lines(t, rT.expected - 2*rT.stdev, lty=2)
points(0,r0_FED)
Función para encontrar el precio ZCB usando el modelo Vasicek
VasicekZCBprice <-
function(r0_FED, k, theta, SD_FED, T){
b.vas <- (1/k)*(1-exp(-T*k))
a.vas <- (theta-SD_FED^2/(2*k^2))*(T-b.vas)+(SD_FED^2)/(4*k)*b.vas^2
return(exp(-a.vas-b.vas*r0_FED))
}
Se definen los parámetros del modelo para trazar curvas de rendimiento
r0 <- seq(0.00, 0.20, 0.05)
n <- length(r0)
yield <- matrix(0, 10, n)
for(i in 1:n){
for(T in 1:10){
yield[T,i] <- -log(VasicekZCBprice(r0[i], k, theta, SD_FED, T))/T
}
}
Se grafican los resultados
maturity <- seq(1, 10, 1)
matplot(maturity, yield, type="l", col="skyblue", lty=1, main="Yield Curve FED")
abline(h=theta, col="blue", lty=2)
Se definen los parámetros del modelo
r0_TES <- 0.0564 #19/09/2022 Tasa semestral tomada del Banco de la Rpública
theta <- 0.08
k <- 0.4
SD_TES <- 0.01274 #Desviación estándar de 3 años
Se simulan las trayectorias de Short-Rate
n <- 10 # MC simulation trials
T <- 10 # total time
m <- 252 # subintervals
dt <- T/m # difference in time each subinterval
r <- matrix(0,m+1,n) # matrix to hold short rate paths
r[1,] <- r0_TES
for(j in 1:n){
for(i in 2:(m+1)){
dr <- k*(theta-r[i-1,j])*dt + SD_TES*sqrt(dt)*rnorm(1,0,1)
r[i,j] <- r[i-1,j] + dr
}
}
Se grafican los resultados
t <- seq(0, T, dt)
rT.expected <- theta + (r0_TES-theta)*exp(-k*t)
rT.stdev <- sqrt( SD_TES^2/(2*k)*(1-exp(-2*k*t)))
matplot(t, r[,1:10], type="l", lty=1, main="Short Rate Paths", ylab="rt")
abline(h=theta, col="lightblue", lty=2)
lines(t, rT.expected, lty=2)
lines(t, rT.expected + 2*rT.stdev, lty=2)
lines(t, rT.expected - 2*rT.stdev, lty=2)
points(0,r0_TES)
Función para encontrar el precio ZCB usando el modelo Vasicek
VasicekZCBprice <-
function(r0_TES, k, theta, SD_TES, T){
b.vas <- (1/k)*(1-exp(-T*k))
a.vas <- (theta-SD_TES^2/(2*k^2))*(T-b.vas)+(SD_TES^2)/(4*k)*b.vas^2
return(exp(-a.vas-b.vas*r0_TES))
}
Se definen los parámetros del modelo para trazar curvas de rendimiento
r0 <- seq(0.00, 0.20, 0.05)
n <- length(r0)
yield <- matrix(0, 10, n)
for(i in 1:n){
for(T in 1:10){
yield[T,i] <- -log(VasicekZCBprice(r0[i], k, theta, SD_TES, T))/T
}
}
Se grafican los resultados
maturity <- seq(1, 10, 1)
matplot(maturity, yield, type="l", col="skyblue", lty=1, main="Yield Curve TES")
abline(h=theta, col="blue", lty=2)