El Valor en Riesgo (VaR) es una medida estadística clave en la gestión de riesgos, que estima la pérdida potencial máxima en un periodo dado bajo condiciones normales de mercado y para un nivel de confianza específico. En esta guía, exploraremos tres métodos de cálculo de VaR: histórico, paramétrico y de Montecarlo, además del uso de cópulas para modelar la dependencia entre activos en un portafolio.
(10 pts) Debe presentar un pdf, con su nombre y número de carnet, donde muestre la replicación de los ejemplos y técnicas mostradas en esta guía e incluir lo solicitado en el punto 2 y 3.
(5 pts) Estimar el VaR histórico, VaR paramétrico y VaR de Montecarlo para las acciones de Microsoft (Ticket=“MSFT”)
(6 pts) Usando el portafolio de la Guía estime el VaR usando la Cópula de Clayton (“claytonCopula()”) y estime el VaR usando la Cópula de Frank (“frankCopula()”), para esto estime el parámetro de dependencia y realice las simulaciones con el parámetro estimado.
(10 puntos) Construir una presentación de no más 6 filminas (incluyendo la portada), del Análisis realizado en la Guía, que se muestre los diferentes VaR estimado y sus explicaciones.
Objetivo: Calcular el Valor en Riesgo (VaR) de una cartera de activos financieros o una inversión específica, a un nivel de confianza determinado.
El valor en Riesgo (VaR) mide la pérdida máxima esperada en una inversión o portafolio dentro de un periodo dado, con un nivel de confianza, que usualmente es entre el 95% y 99%.
Según la normativa internacional (Basilea), el horizonte temporal son 10 días, en la normativa costarricense, por ser un mercado poco profundo y desarrollado, este plazo se toma de 21 días, este periodo mide la posible pérdida producida por movimientos adversos en los precios de los activos del portafolio, para esta guía trabajaremos el horizonte de 1 día.
La Ventana histórica, es el periodo de observación usualmente es un año bursátil, cerca de 252 observaciones, para la guía tomaremos un año calendario
El nivel de confianza para la guía es de 95\(\%\), que constituye la pérdida asociada a la medida VaR.
A lo largo de la guía, se usaran funciones de diferentes paquetes de R, a continuación se en listan, deben ser instalados con anterioridad:
library(quantmod)
library(PerformanceAnalytics)
library(matrixStats)
library(copula)
library(fCopulae)
library(QRM)
library(MASS)
library(sm)
library(knitr)
library(univariateML)
Para la guía,descargaremos los precios de las acciones de Amazon y de Tesla y construiremos un portafolio, donde el 55% de las inversiones son Amazón y el 45% restante de Tesla.
Usando la función Ad, podemos cargar los datos desde la fecha máxima hasta el día del análisis, con fuente Yahoo Finance, esta función genera el vector en un objeto “xts”, por lo que los convertiremos en un vector númerico.
Graficamos el comportamiento de cada acción por aparte.
maxDate = "2023-10-31"
minDate = "2024-10-31"
tick1<-"AMZN"
p.amazon <- Ad(getSymbols(tick1, auto.assign = FALSE, from=maxDate, to=minDate))
plot(p.amazon)
p.amazon<-as.numeric(p.amazon)
tick2<-"TSLA"
p.tesla <- Ad(getSymbols(tick2, auto.assign = FALSE, from=maxDate,to=minDate))
plot(p.tesla)
p.tesla<-as.numeric(p.tesla)
Construiremos nuestro portafolio con los pesos dados
W=as.matrix(c(0.55,0.45))
Portafolio<-data.frame("amazon"=p.amazon,"tesla"=p.tesla)
Portafolio<-cbind(Portafolio,"Total"=as.matrix(Portafolio)%*%W)
plot(Portafolio$Total, type="s",main="Portafolio",ylab="Portafolio")
Calcularemos el retorno diario, para cada acción y el total del portafolio, para esto los estimaremos con la siguiente fórmula:
\[r_t=\ln \left( \frac{P_t}{P_{t-1}} \right)\] donde \(P_t\) es el precio en el tiempo \(t\).
retornos<-data.frame("r.amazon"=diff(log(Portafolio$amazon)),
"r.tesla"=diff(log(Portafolio$tesla)),
"r.porta"=diff(log(Portafolio$Total)))
Algo importante en el análisis del VaR, son la dependencia o correlaciones que poseen los diferentes instrumentos que conforman el portafolio, por lo que es importante calcular estas dependencias, además de la media observada en la muestra
media_r<-colMeans(retornos)
cat("Medias observadas: \n")
## Medias observadas:
kable(media_r)
| x | |
|---|---|
| r.amazon | 0.0014752 |
| r.tesla | 0.0009909 |
| r.porta | 0.0012149 |
cov_r<-cov(retornos)
cat("Matriz de Covarianzas observadas: \n")
## Matriz de Covarianzas observadas:
kable(cov_r)
| r.amazon | r.tesla | r.porta | |
|---|---|---|---|
| r.amazon | 0.0002676 | 0.0001795 | 0.0002260 |
| r.tesla | 0.0001795 | 0.0013147 | 0.0007336 |
| r.porta | 0.0002260 | 0.0007336 | 0.0004768 |
corr_r<-cor(retornos)
cat("Matriz de Correlaciones observadas: \n")
## Matriz de Correlaciones observadas:
kable(corr_r)
| r.amazon | r.tesla | r.porta | |
|---|---|---|---|
| r.amazon | 1.0000000 | 0.3026854 | 0.6328151 |
| r.tesla | 0.3026854 | 1.0000000 | 0.9265464 |
| r.porta | 0.6328151 | 0.9265464 | 1.0000000 |
El VaR Histórico, esta forma de estimar el Valor en Riesgo, es utilizando la distribución empirica \(\hat F(x)\) de los retornos o rendimientos, para esto debemos definir nuestro nivel de confianza \(1-\alpha\) y:
\[Var=\hat F^{-1}(\alpha)\]
Es decir el \(\alpha-cuantil\) de las observaciones.
VarHist<-data.frame("VH_amazon"=quantile(retornos$r.amazon,0.05),
"VH_tesla"=quantile(retornos$r.tesla,0.05),
"VH_Porta"=quantile(retornos$r.porta,0.05))
kable(VarHist)
| VH_amazon | VH_tesla | VH_Porta | |
|---|---|---|---|
| 5% | -0.0237677 | -0.0458643 | -0.0333812 |
Observe que el VaR no es aditivo en sus partes, es decir el VaR no necesariamente es la suma ponderada de sus partes, esto debido a la correlación entre los componentes del portafolio, cuando son iguales significa que son perfectamente correlacionados, usualmente es menor el VaR del portafolio que la suma ponderada de sus partes, esto gracias al efecto de diversificación.
cat("Suma de sus parte ponderadas :\n")
## Suma de sus parte ponderadas :
VarHist$VH_amazon*.55+VarHist$VH_tesla*.45
## [1] -0.03371117
Para el VaR paramétrico, se asume que los rendimientos tienen un comportamiento Normal, para el caso de un sólo instrumento, podríamos definir lo como:
\[VaR=\mu+ z_{\alpha} \sigma\]
Estimaremos el VaR individual para cada instrumento del portafolio
VP_amazon<-media_r[1]+qnorm(0.05)*(cov_r[1,1])^(1/2)
cat("VaR paramétrico amazon: \n")
## VaR paramétrico amazon:
VP_amazon
## r.amazon
## -0.0254323
VP_tesla<-media_r[2]+qnorm(0.05)*(cov_r[2,2])^(1/2)
cat("VaR paramétrico tesla: \n")
## VaR paramétrico tesla:
VP_tesla
## r.tesla
## -0.05864961
Para el caso del portafolio, se asume una distribución multinormal,si el portafolio está conformado por n instrumentos, \(X=[X_1,X_2,...,X_n]^t\), estos se comportarán de la siguiente manera
\[X \sim N(\mu,\Sigma)\] donde \(\mu=[\mu_1,\mu_2,..,\mu_n]^t\) vector de medias y matriz de covarianzas
\[\Sigma=\begin{pmatrix} \sigma_{x_1}^2 & \sigma_{x_1x_2} & \cdots & \sigma_{x_1x_n}\\ \sigma_{x_1x_2} & \sigma_{x_2}^2 & \cdots & \sigma_{x_2x_n} \\ \vdots & \vdots & &\vdots \\ \sigma_{x_1x_n} & \sigma_{x_2x_n} & \cdots & \sigma_{x_n}^2 \end{pmatrix}\] Por lo que si tomamos una Transformación Afin, con \(c=0\) y \(B=W\), donde W es el vector de los pesos, obtenemos que nuestro portafolio \(Y\) sigue
\[Y\sim N(W\mu,W\Sigma W^t)\]
con media \(\mu_p=W\mu\) la media ponderada de cada instrumento
Con varianza \(W*\Sigma*W^{t}\)
mu_p=0.55*media_r[1]+0.45*media_r[2]
cov2=cov_r[c(1,2),c(1,2)] #para la var, cov sin el total
sigma2_p=t(W)%*%cov2%*%W
VP_porta<-mu_p+qnorm(0.05)*(sigma2_p)^(1/2)
cat("VaR paramétrico portafolio: \n")
## VaR paramétrico portafolio:
VP_porta
## [,1]
## [1,] -0.0330902
Esta metodología tiene como objetivo generar escenarios aleatorios, según la distribución de probabilidad que se supone que describe el comportamiento de la distribución de pérdida, por lo que se requiere una cantidad suficiente de escenarios con el fin de determinar la convergencia de la distribución simulada a la distribución real.
Para la simulación de los precios de acciones es común suponer que estas sigue una caminata aleatoria, lo cual se puede representar como un proceso Browniano
\[dS=\mu Sdt+\sigma Sdw\]
donde \(S\) corresponde al precio de la acción o portafolio, \(\mu\) el valor esperado de los retornos y \(\sigma\) la volatilidad de los retornos (desviación estandar), además \(dw\) es el diferencial del proceso Browniano (Wiener).
Las variación de \(dw\) son independientes para cualquier par de intervalos de tiempos diferentes y además cumple que:
\[dw=\epsilon \sqrt{dt}\]
con \(\epsilon \sim N(0,1)\)
Para nuestro caso estamos utilizando diferencias de tiempo de 1 día, es decir \(\Delta t=1\), y si asumimos que \(S_0=100\), podemos representar el proceso en forma discreta como:
\[S_{t+1}=S_t exp \left( \left(\mu-\frac{\sigma^2}{2}\Delta t \right)+\sigma\epsilon_t \sqrt{\Delta t} \right)\]
Procederemos a construir el caso de un instrumento de Amazon, con horizonte de proyección de 1 año bursátil, aproximadamente 260 días.
n_sims = 1000
n_periods = 260
matriz_precios=matrix(,n_periods+1,n_sims)
#En esta matriz vamos a almacenar los iteraciones para cada periodo,
#y agregamos 1 periodo para tener el dato inicial, nuestra última
#observación
S0=p.amazon[length(p.amazon)]
mu=media_r[1]
volatilidad=sqrt(cov_r[1,1])
matriz_precios[1,]=S0
for(i in 1:n_sims)
{
for (j in 2:nrow(matriz_precios))
{
matriz_precios[j,i]=matriz_precios[j-1,i]*exp((mu-volatilidad^2/2)+volatilidad*rnorm(1))
}
}
# En la fórmula no se muestra el delta t, porque estamos
#estimado con diferencia de 1 día, el valor rnorm(1)
#es el error con distribución normal.
Ya obteniendo, los datos de la simulación, podemos estimar la media de cada periodo proyectado, es decir la tendencia e intervalos de confianza correspondientes.
Tendencia=apply(matriz_precios,1,mean)
IC=t(apply(matriz_precios, 1,quantile, probs=c(0.01,0.05,0.95,0.99)))
matplot(matriz_precios,type="l", col="gray",ylab="")
lines(Tendencia,type="l",lwd=2)
lines(IC[,"1%"],col="blue")
lines(IC[,"99%"],col="blue")
lines(IC[,"5%"],col="red")
lines(IC[,"95%"],col="red")
legend("topleft",legend = c("tendencia","intervalo 90%","intervalo 95%"),lwd = c(2,1,1,1),bty="n",col=c("black","red","blue"))
Por el plazo de proyección, que fue de 1 año bursátil, podemos observar la distribución del último día simulado, tanto para el valor del instrumento como el retorno.
dist_retorno=log(matriz_precios[nrow(matriz_precios),]/matriz_precios[1,])
par(mfrow=c(1,2))
hist(dist_retorno,100,col="black",main="retornos a un Año",xlab="")
hist(matriz_precios[nrow(matriz_precios),],breaks = 100,col="black",main="precio a un año 365", xlab = "")
Según la teoría los precios simulados poseen una distribución Log-Normal, y los retornos con una distribución normal. Verificar realizando un test para verificar la distribución, comparándolo como las distribuciones más comunes
distribuciones <- c("exp", "gamma", "lnorm", "norm", "unif",
"weibull","lgamma")
cat("Precios: \n")
## Precios:
(model_select(matriz_precios[nrow(matriz_precios),], models=distribuciones))
## Maximum likelihood estimates for the Lognormal model
## meanlog sdlog
## 5.5982 0.2723
cat("Retornos: \n")
## Retornos:
(model_select(dist_retorno, models=distribuciones))
## Maximum likelihood estimates for the Normal model
## mean sd
## 0.3369 0.2723
También podemos analizar, la convergencia del modelo, observando los promedios ergodicos y su convergencia
n=length(matriz_precios[nrow(matriz_precios),])
acumulado1<-cumsum(matriz_precios[nrow(matriz_precios),])/(1:n)
acumulado2<-cumsum(dist_retorno)/(1:n)
par(mfrow=c(1,2))
plot(1:n,acumulado1,col="blue",type="l",ylab="Aproximacion",xlab="Iteraciones",main="Convergencia Precio")
plot(1:n,acumulado2,col="red",type="l",ylab="Aproximacion",xlab="Iteraciones",main="Convergencia retornos")
Para simular un portafolio, requerimos considerar la dependencia entre los instrumentos y no solamente la volatilidad de cada instrumento, para esto requeriremos considerar la descomposición de Cholesky la matriz de Correlaciones \(P\), que nos brinda una matriz triangular (\(L\)) tal que:
\[P=LL^t\],
Esto dado que los errores se asumen que se distribuyen multinormal.
Cómo estamos estimando en esta guía el VaR a un día, simularemos solamente un día de proyección.
L=chol(corr_r[c(1,2),c(1,2)])
#Descomposición de Cholesky de la matriz de correlación.
kable(L,caption="Descomposición de Cholesky")
| r.amazon | r.tesla | |
|---|---|---|
| r.amazon | 1 | 0.3026854 |
| r.tesla | 0 | 0.9530905 |
V_porta=c(sqrt(cov_r[1,1]),sqrt(cov_r[2,2]))
M_porta=c(media_r[1],media_r[2])
n_sims = 1000
n_periods = 2
precio_activos=matrix(,n_periods,length(V_porta))
S0=Portafolio$Total[length(Portafolio$Total)]
precio_activos[1,]=S0
retornos_p=vector()
portafolio_sim=vector()
for(j in 1:n_sims) {
for (i in 1:length(V_porta)) {
Z=rnorm(length(V_porta))
# vector de variables aleatorios estándar independientes
K=Z%*%L # vector de variables aleatorios correlacionado
precio_activos[2,i]=precio_activos[1,i]*exp((M_porta[i]-V_porta[i]^2/2)+V_porta[i]*K[i]) #Caminata aleatoria
}
portafolio_sim[j]<-precio_activos[2,1]*.55+precio_activos[2,2]*.45
#Según los pesos de W.
retornos_p[j]=log(portafolio_sim[j]/S0)
}
Var_MC_Porta<-quantile(retornos_p,0.05)
kable(Var_MC_Porta,caption="VaR MonteCarlo")
| x | |
|---|---|
| 5% | -0.0277028 |
par(mfrow=c(1,2))
hist(retornos_p,main="Retornos a 1 día")
hist(portafolio_sim,main="precios a 1 día")
En esta sección estimaremos el riesgo de un portafolio o cartera de inversión utilizando Cópulas paramétricas Bivariadas, para lo que realizaremos simulaciones de Montecarlo para cada Cópula. Para esto estimaremos el parámetro de dependencia según cada Cópula a utilizar y ajustaremos las distribuciones marginales para después estimar el VaR del portafolio.
Cómo primer acercamiento, trabajaremos con las Cópulas Elípticas Normales, para este caso, nuestra relación de dependencia sería correlación \(\rho\).
Trabajaremos con una simulación 100 000 iteraciones.
rho<-corr_r[1,2]
r<-100000
Cop.norm<-normalCopula(rho, dim = 2)
Sim_val_cop.norm<-rCopula(r,Cop.norm) # Valores simulados
Una vez simulada, nuestra cópula Normal, podemos ajustar Marginal a una Normal con media y varianza de cada instrumento
V_porta=c(sqrt(cov_r[1,1]),sqrt(cov_r[2,2]))
M_porta=c(media_r[1],media_r[2])
sim.val.ln1 <- qnorm(Sim_val_cop.norm[,1], mean=M_porta[1], sd=V_porta[1])
sim.val.ln2 <- qnorm(Sim_val_cop.norm[,2], mean=M_porta[2], sd=V_porta[2])
c_norm<-cbind(sim.val.ln1,sim.val.ln2)
par(mfrow=c(2,2))
plot(density(sim.val.ln1), main="Marginal Amazon")
plot(density(sim.val.ln2), main="Marginal Tesla")
sm.density(c_norm,xlab="Amazon",ylab="Tesla",zlab="Cópula")
plot(c_norm,xlab="Amazon",ylab="Tesla")
Obteniendo las marginales, podemos estimar el portafolio con los pesos \(W\) correspondientes y estimar el VaR con la Cópula Normal
MC.data<-cbind(sim.val.ln1, sim.val.ln2)
MC.Lsim <- (MC.data%*%t(t(W)))
kable(quantile(MC.Lsim, 0.05),caption="VaR Cópula Normal")
| x | |
|---|---|
| 5% | -0.0333555 |
Estimaremos el VaR con otras Cópulas, para esto transformaremos los retornos originales a variables uniforme, con la función de distribución empírica corregida:
\[ F_n=\frac{n}{n+1}\hat F_n \] Para realizar la transformación usaremos la función pobs
valA.unif<-pobs(retornos$r.amazon)
valT.unif<-pobs(retornos$r.tesla)
data2<-cbind(valA.unif,valT.unif)
par(mfrow=c(1,2))
hist(valA.unif)
hist(valT.unif)
Cópula Gumbel
Usaremos para generar los valores la Cópula de Gumbel, para esto debemos estimar el parámetro de dependencia \(\theta\). Para esto definimos la Cópula a utilizar en este caso “gumbelCopula” con la dimensión y con la función “fitCopula” y el método de maxima verosimilitud “ml”, estimamos sus parametros.
g_copula<-gumbelCopula(dim=2)
ParaT <- fitCopula(g_copula, data = data2, method = "ml")
summary(ParaT)
## Call: fitCopula(g_copula, data = data2, ... = pairlist(method = "ml"))
## Fit based on "maximum likelihood" and 251 2-dimensional observations.
## Gumbel copula, dim. d = 2
## Estimate Std. Error
## alpha 1.23 0.059
## The maximized loglikelihood is 10.49
## Optimization converged
## Number of loglikelihood evaluations:
## function gradient
## 6 6
El parametro de dependencia, en este caso es denominado “alpha”, para extraer este valor, en vez de utilizar el símbolo \(\$\) se utiliza el símbolo \(@\) para extraer los datos, esto por la estructura del paquete “copula”
theta<-ParaT@estimate
Una vez estimado el parámetro de dependencia de la Cópula, generamos los valores y aplicamos las marginales normales como el caso de la Cópula Normal.
g_cop_est<-gumbelCopula(theta, dim =2)
Sgumbelcopula <- rCopula(r, g_cop_est)
sim.val.ln1 <- qnorm(Sgumbelcopula[,1], mean=M_porta[1], sd=V_porta[1])
sim.val.ln2 <- qnorm(Sgumbelcopula[,2], mean=M_porta[2], sd=V_porta[2])
MC.data<-cbind(sim.val.ln1, sim.val.ln2)
MC.Lsim <- (MC.data%*%t(t(W)))
kable(quantile(MC.Lsim, 0.05),caption="VaR Cópula Gumbel")
| x | |
|---|---|
| 5% | -0.0320119 |
Nota: Usa colores y estilos consistentes, mantén textos breves y utiliza palabras clave en negritas.
En la medida de los posible utilice la regla 6-6-6: 6 Filminas con 6 lineas de texto en cada filmina con 6 palabras por linea, esto ayuda a sintetizar la información que se desea presentar
Nelsen Roger (2006) An Introduction to Copulas Springer, 2da Edición, Estados Unidos.
Wasserman, L. (2006). All of Nonparametric Statistics.
Robert, C. P., & Casella, G. (2009). Introducing Monte Carlo Methods with R. Springer.
Sánchez, R et Al. (2019). Guía de introducción al VaR usando R. RPubs. https://rpubs.com/RaulSanchez/557642
Rendón, J. (2020). Valor en Riesgo (VaR) mediante simulación de Monte Carlo para un portafolio. RPubs. https://rpubs.com/juanrendon/VaR_montecarlo_portafolio
Ferro, P. (Fecha de publicación desconocida). Valor en Riesgo: Teoría y aplicación en R. RPubs. https://rpubs.com/profe_ferro/809314