Introducción

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.

Packetes a utilizar

Se utilizarán los siguientes paquetes de R:

  1. dplyr: Principalmente porque permite manejar los datos de una manera fácil mendiante la utilización de funciones como mutate, summarize, group_by, etc. Además se utilizará el Pipe Operator: %>% para trabajar de forma más ituitiva.
  2. tidyr: Para el manejo de datos, es útil para agrupar y desagrupar datos con sus funciones gather y spread.
  3. ggplot2: Para la visualización de datos.
  4. plotly: Se combina con ggplot, utilizando el comando ggplotly para realizar gráficos interactivos.
  5. quantmod: Escencial para importar datos financieros y trabajar con series de tiempo.
library(dplyr)
library(tidyr)
library(ggplot2)
library(quantmod)
library(plotly)

Importar los datos

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

Cálculo de retornos

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:

Cálculo del VaR

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.

Seteamos los parámetros:

alpha <- .05
psi <- qnorm(1-alpha)
M <- 10000

Creamos la función del VaR:

varCov <- function(u,sigma,psi,M) {
    return(
        (exp((u-sigma^2/2)+sigma*psi)-1)*M
    )
}

Cálculo con ventana móvil:

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.

Visualización del VaR

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