En este documento, se importarán datos de acciones entre los años 2014 y 2017 con la finalidad de calcular el Value at Risk (VaR) para los años 2016 y 2017 con una ventana móvil de 504 días (dos años en días transables), mediante el método de varianza-covarianza.
Se utilizarán los siguientes paquetes de R:
mutate
, summarize
, group_by
, etc. Además se utilizará el Pipe Operator: %>%
para trabajar de forma más ituitiva.gather
y spread
.ggplotly
para realizar gráficos interactivos.library(dplyr)
library(tidyr)
library(ggplot2)
library(quantmod)
library(plotly)
La función getSimbols
permite importar como series de tiempo los datos de las acciones. Para importar mas de una serie de tiempo, se separan por ;
.
getSymbols("AAPL;AMZN;FB;MSFT;NKE", source='yahoo', from=as.Date('2014-01-01'), to=as.Date('2017-12-31'))
## [1] "AAPL" "AMZN" "FB" "MSFT" "NKE"
Veamos por ejemplo, la serie de tiempo de Apple:
head(AAPL)
## AAPL.Open AAPL.High AAPL.Low AAPL.Close AAPL.Volume
## 2014-01-02 79.38286 79.57571 78.86000 79.01857 58671200
## 2014-01-03 78.98000 79.10000 77.20428 77.28286 98116900
## 2014-01-06 76.77857 78.11429 76.22857 77.70428 103152700
## 2014-01-07 77.76000 77.99429 76.84571 77.14857 79302300
## 2014-01-08 76.97285 77.93714 76.95571 77.63715 64632400
## 2014-01-09 78.11429 78.12286 76.47857 76.64571 69787200
## AAPL.Adjusted
## 2014-01-02 67.72286
## 2014-01-03 66.23527
## 2014-01-06 66.59647
## 2014-01-07 66.12019
## 2014-01-08 66.53890
## 2014-01-09 65.68922
Y se puede visualizar, ocupando la función chartSeries
de quantmod.
chartSeries(AAPL)
Ahora, se ocuparán los precios Adjusted para el cáculo del VaR, transformaremos la serie en en data frame y nos quedaremos con la columna Adjusted y una columna Date.
NKE <- NKE %>% as.data.frame() %>% mutate(date=index(NKE)) %>% select(date,NKE.Adjusted)
AMZN <- AMZN %>% as.data.frame() %>% mutate(date=index(AMZN)) %>% select(date,AMZN.Adjusted)
FB <- FB %>% as.data.frame() %>% mutate(date=index(FB)) %>% select(date,FB.Adjusted)
MSFT <- MSFT %>% as.data.frame() %>% mutate(date=index(MSFT)) %>% select(date,MSFT.Adjusted)
AAPL <- AAPL %>% as.data.frame() %>% mutate(date=index(AAPL)) %>% select(date,AAPL.Adjusted)
# veamos Apple ahora
head(AAPL)
## date AAPL.Adjusted
## 1 2014-01-02 67.72286
## 2 2014-01-03 66.23527
## 3 2014-01-06 66.59647
## 4 2014-01-07 66.12019
## 5 2014-01-08 66.53890
## 6 2014-01-09 65.68922
Lo siguiente es realizar un join para tener todos los datos en un data frame. Esto lo hacemos con la función inner_join
de dplyr.
precios <- NKE %>%
inner_join(AMZN, by='date') %>%
inner_join(FB, by='date') %>%
inner_join(MSFT, by='date') %>%
inner_join(AAPL, by='date') %>% tbl_df
# renombramos las columnas para evitar tener el '.Adjusted'
colnames(precios) <- c('date','NKE','AMZN','FB','MSFT','AAPL')
#veamos la data
head(precios)
## # A tibble: 6 x 6
## date NKE AMZN FB MSFT AAPL
## <date> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 2014-01-02 35.9 398. 54.7 33.2 67.7
## 2 2014-01-03 35.8 396. 54.6 33.0 66.2
## 3 2014-01-06 35.6 394. 57.2 32.3 66.6
## 4 2014-01-07 35.6 398. 57.9 32.6 66.1
## 5 2014-01-08 35.4 402. 58.2 32.0 66.5
## 6 2014-01-09 35.4 401. 57.2 31.8 65.7
Se calcularán los retosnos logarítmicos: \(r_t=ln(\frac{p_t}{p_{t-1}})\). Se ocupará la función transmutate
de dplyr para crear las variables y eliminar las restantes.
retornos <- precios %>% transmute(
date = date,
NKE = log(NKE/lag(NKE)),
AAPL = log(AAPL/lag(AAPL)),
AMZN = log(AMZN/lag(AMZN)),
FB = log(FB/lag(FB)),
MSFT = log(MSFT/lag(MSFT))
)
# veamos la data
head(retornos)
## # A tibble: 6 x 6
## date NKE AAPL AMZN FB MSFT
## <date> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 2014-01-02 NA NA NA NA NA
## 2 2014-01-03 -0.00269 -0.0222 -0.00385 -0.00275 -0.00675
## 3 2014-01-06 -0.00772 0.00544 -0.00711 0.0473 -0.0214
## 4 2014-01-07 0.000775 -0.00718 0.0111 0.0125 0.00772
## 5 2014-01-08 -0.00518 0.00631 0.00973 0.00534 -0.0180
## 6 2014-01-09 0. -0.0129 -0.00227 -0.0175 -0.00645
Ahora visualicemos los retornos de las acciones:
Para el cálculo del value at risk, se utilizará la siguiente fórmula:
\[VaR_{t,t+1}=\left(e^{\left(\mu-\frac{\sigma^2}{2}\right)+\sigma\psi}-1\right)M\]
Donde \(\mu\) y \(\sigma^2\) son la media y la varianza de los retornos logarítmicos, \(\psi\) es la inversa de una \(N(0,1)\) con probabilidad \(\alpha\) y \(M\) es la cantidad invertida en el activo. Para este caso utilizaremos un \(\alpha=0,05\), por lo que la inversa de la normal de un 95% es \(\psi=1,64\) aprox. Además supondremos que se invertirá una cantidad de $10000 en cada activo.
alpha <- .05
psi <- qnorm(1-alpha)
M <- 10000
varCov <- function(u,sigma,psi,M) {
return(
(exp((u-sigma^2/2)+sigma*psi)-1)*M
)
}
Se iterará con dos ciclos, uno para cada stock y otro para cada día:
# Se crea una matriz que almacenará los VaR para cada acción desde 2016 a 2017
VAR <- matrix(1:503, nrow = 503, ncol = 5)
colnames(VAR) <- colnames(retornos[,2:6])
# Se realiza el loop
for (s in 1:5) {
for (i in VAR[,s]) {
u <- mean(retornos[i:(i+503),][[s+1]], na.rm = T)
sigma <- sd(retornos[i:(i+503),][[s+1]], na.rm = T)
VAR[i,s]=varCov(u,sigma,psi,M)
}
}
# veamos la matriz de VaR
head(VAR)
## NKE AAPL AMZN FB MSFT
## [1,] 236.7870 265.2560 355.5393 336.8330 259.2130
## [2,] 236.5622 264.9994 356.8731 336.5273 258.8857
## [3,] 237.0831 265.1019 356.8589 336.6840 259.0662
## [4,] 237.1429 265.0161 356.9222 333.9420 258.9893
## [5,] 237.5286 266.2650 357.1175 334.8111 259.5069
## [6,] 237.6212 266.2325 356.8286 334.6047 259.5510
Luego, se crea un data frame con la fecha(date) y el VaR de cada acción
# se transforma en data frame la matriz VAR
VAR <- data.frame(VAR)
# se combina la data para obtener date y VaR de cada acción
VAR <- cbind(date=retornos[505:1007,1],VAR) %>% tbl_df
# veamos la data
head(VAR)
## # A tibble: 6 x 6
## date NKE AAPL AMZN FB MSFT
## <date> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 2016-01-04 237. 265. 356. 337. 259.
## 2 2016-01-05 237. 265. 357. 337. 259.
## 3 2016-01-06 237. 265. 357. 337. 259.
## 4 2016-01-07 237. 265. 357. 334. 259.
## 5 2016-01-08 238. 266. 357. 335. 260.
## 6 2016-01-11 238. 266. 357. 335. 260.
Finalmente, podemos ver gráficamente el VaR de cada acción, agrupando la data con gather
para gráficar más fácimente:
g2 <- VAR %>% gather(Stock, VaR, 2:6) %>%
ggplot(aes(x=date, y=VaR, color=Stock)) + geom_line() + theme_test() + xlab('Date') + ggtitle('Value at Risk')
ggplotly(g2)
Nota: Esto es parte de una tarea para el ramos de Finanza II. Cualquier consulta sobre el código a elias.alegria@ug.uchile.cl