setwd("C:/Users/rchang/Downloads/Mercado de Capitales UNAH 2023/Scripts")

Capítulo 3 Quantmod

IMPORTATE: Aún no está del todo listo el formato en pdf, por lo que recomiendo verlo online.

El paquete quantmod para R esta diseñado para la asistencia quantitativa de los traders en el desarrollo de sus estrategias y modelos financieros.

3.1 ¿Que es quantmod?

Un entorno rápido, donde los operadores cuantitativos pueden explorar y construir modelos de negociación rápida y limpiamente. A través de la función getSymbols podemos extraer datos financieros desde varias fuentes: Google Finance, Yahoo Finance, Federal Reserve Bank of St. Louis FRED (más de 11,000 series !!!) y Oanda. Incluso desde fuentes propias: MySQL , R (Rdata) y Comma Separated Value files (csv).

No es el paquete definitivo dado que se complementa con otros, tales como: TTR, zoo y xts. En lo que respecta al análisis técnico son las más usadas en el mercado y usan todas las propiedades que hacen al lenguaje R útil para realizar análisis de datos.

3.2 Obtención de Datos

Para comenzar, como todo paquete en R se debe instalar

# Instalación package
#install.packages("quantmod")
#Una vez que esté instalado, creamos nuestro script usando ctrl/cmd + shift + n y lo “llamamos” con

# Cargamos "quantmod"
library("quantmod")
## Warning: package 'quantmod' was built under R version 4.1.3
## Loading required package: xts
## Loading required package: zoo
## 
## Attaching package: 'zoo'
## The following objects are masked from 'package:base':
## 
##     as.Date, as.Date.numeric
## Loading required package: TTR
## Registered S3 method overwritten by 'quantmod':
##   method            from
##   as.zoo.data.frame zoo

HINT: con ctrl + R en windows/Linux y cmd + R en MAC OS agregamos más rapido comentarios (sección) en Rstudio.

quantmod provee una función para descargar datos desde fuentes externas. Esta función se llama getSymbols, para mayor información escribir en la linea de comandos ? getSymbols. Por defecto, se crea un objeto en el workspace (Global Environment) con el nombre del ticker/nemotécnico seleccionado. Imaginemos por un momento que necesitamos analizar el S&P 500 desde el 2022 hasta la fecha con periocidad diaria. Lo primero que debemos hacer es pensar desde que fuente vamos a descargar los datos, como es un índice accionario se recomienda usar yahoo finance, luego buscar el nemotécnico, en este caso es “^GSPC”.

getSymbols("^GSPC", src = "yahoo", from = "2022-06-06", to = "2023-02-15", periodicity = "daily")
## [1] "^GSPC"
getSymbols("MSFT", src = "yahoo", from = "2022-06-06", to = "2023-02-15", periodicity = "daily")
## [1] "MSFT"

3.2.1 ¿Qué hizo la función getSymbols?

La función getSymbols se construye basicamente de cinco opciones:

  1. El ticker/nemotécnico, eg. ^GSPC.
  2. src, que es la abreviación de “source”, eg. yahoo, FRED…
  3. from, es el inicio de la fecha a descargar, tener presente que se incluye la fecha en nuestros datos.
  4. to, es el final del periodo para los datos, este no se incluye.
  5. periodicity, es la periodicidad de los datos, eg. daily, monthly o yearly, solo algunos datos se ajustan a las tres periodicidades.

En el ejemplo anterior se descargo desde yahoo los datos del S&P 500 desde Lunes 06 del 2022 hasta el miercoles 15 de febrero del 2023 con periodicidad diaria, construyendo un objeto en formato xts cuyo nombre es GSPC.

3.3 Graficando con chartSeries

Aún no introducimos la librería ggplot2, sin embargo, quantmod también nos permite graficar.

3.3.1 chartSeries

Para graficar basta con escribir el nombre del objeto con clase (class) xts, en nuestro caso es GSPC que representa al Standard and Poor 500. Si escribimos TA = NULL, charSeries no mostrará el volume

chartSeries(GSPC, TA=NULL)

Pero cuando las series son muy largas, podemos ver tendencias pero dificulta ver cambios importantes a nivel de análisis técnico.

chartSeries(GSPC, subset = "last 3 months")

Con el código anterior nos enfocamos solo en los tres meses anteriores.

library(ggplot2)
## Warning: package 'ggplot2' was built under R version 4.1.3

3.4.3 S&P 500 con ggplot2

gspc <- as.data.frame(GSPC)
g1 <- ggplot(gspc) + geom_line(mapping = aes(index(gspc),GSPC.Adjusted))
g1 <- g1 + labs(title = "S&P 500", subtitle = "Desde Enero 2010 a 2018") + xlab("Fecha") + ylab("")
g1 <- g1 + theme_bw()
g1

3.5 Multiples Datos

A continuación trabajaremos con las acciones de Oracle, Nvidia, IBM y AMD, comenzamos con crear un objeto con los nombres de los tickers

tickers <- c("ORCL","AMD","IBM","NVDA")

descargamos los datos con las características requeridas, que son las mismas que usamos anteriormente con S&P 500

getSymbols(tickers, src = "yahoo", from = "2022-06-06", to = "2023-02-15", periodicity = "daily")
## [1] "ORCL" "AMD"  "IBM"  "NVDA"

[1] “ORCL” “AMD” “IBM” “NVDA”

list <- lapply(tickers, function(x) Cl(get(x)))
precio.cierre <- do.call(merge,list)

Acá deben tener mucha atención:

list <- lapply(tickers, function(x) Cl(get(x)))
precio.cierre <- do.call(merge,list)

3.5.1 Retornos

La formula para calcular (log) retornos es:

Ahora pasamos a construir el retorno.

library(tidyverse)
## -- Attaching packages --------------------------------------- tidyverse 1.3.1 --
## v tibble  3.1.8     v dplyr   1.0.7
## v tidyr   1.1.4     v stringr 1.4.0
## v readr   2.0.2     v forcats 0.5.1
## v purrr   0.3.4
## Warning: package 'tibble' was built under R version 4.1.3
## -- Conflicts ------------------------------------------ tidyverse_conflicts() --
## x dplyr::filter() masks stats::filter()
## x dplyr::first()  masks xts::first()
## x dplyr::lag()    masks stats::lag()
## x dplyr::last()   masks xts::last()
retornos <- data.frame(apply(precio.cierre, 2, function(x) Delt(x, type = "log")),
                       fecha = index(precio.cierre)) %>%
            rename(orcl = ORCL.Close, amd = AMD.Close, ibm = IBM.Close, nvda = NVDA.Close) %>% 
            na.omit() 

3.5.2 Retornos Acumulados

Si graficamos los retornos no será muy descriptivo, una forma es trabajar con su acumulado. Con la misma lógica usamos la función cumsum().

acumulados <- data.frame(apply(retornos[1:4], 2, function(x) cumsum(x)), fecha = index(precio.cierre[-1]))

3.5.2.1 Gráfico retornos acumulados

library("reshape2")
## Warning: package 'reshape2' was built under R version 4.1.3
## 
## Attaching package: 'reshape2'
## The following object is masked from 'package:tidyr':
## 
##     smiths
reshape <- melt(acumulados, id.vars = "fecha")
g2 <- ggplot(reshape) + geom_line(mapping = aes(fecha,value, color = variable))
g2 <- g2 + labs(title = "Retornos Acumulados", subtitle = "Oracle, AMD, IBM y Nvidia")
g2 <- g2 + theme_bw() + xlab("Fecha") + ylab("Retornos Acumulados")
g2 <- g2 + scale_color_manual("Tickers", values = c("red","blue","green","orange"))
g2 <- g2 + theme(legend.position = "bottom")
g2

3.6 Estadística Descriptiva

Existe muchas formas de obtener la estadística descriptiva en R, un librería es fBasics, la que a su vez contiene test de normalidad.

library("fBasics")
## Warning: package 'fBasics' was built under R version 4.1.3
## 
## Attaching package: 'fBasics'
## The following object is masked from 'package:TTR':
## 
##     volatility
summary <- basicStats(retornos[1:4])[c("Mean", "Stdev", "Median", "Minimum", "Variance",
                                       "Maximum", "nobs","Skewness","Kurtosis"),]

3.7 Ratio de Sharpe

EL ratio de Sharpe es una medida de desempeño para portafolios, el que se define como:

Para realizar el cálculo del ratio de Sharpe (SR) para Oracle

SR_orcl <- (mean(retornos$orcl) - 0.0000 )/sd(retornos$orcl)

Con mean(retornos\(orcl) vamos a obtener el promedio de la primera columna del objeto retornos que es Oracle (en el data.frame la columna se llama orcl, si tuviese otro nombre como por ejemplo perrito, entonces hubiese sido mean(retornos\)perrito)), si quisieramos AMD debería ser amd y asì sucesivamente. El 0.0000 sería la tasa libre de riesgo que la asumimos mensual y sd(retornos[1]) nos calcula la desviación estandar. Dado que poseemos 4 activos con sus respectivos retornos, deberiamos construir cuatro objetos que partan con SR.

3.8 Test de JarqueBera

El test de jarque-bera usa los coeficientes de la skewness y kurtosis de la muestra y se usa para testar normalidad. Otros test comunes son el de Anderson–Darling, Cramér–von Mises, y Kolmogorov–Smirnov.

En resumen compara que la skewness sea 0 y la kurtosis sea 3 bajo normalidad.

El test se encuentra en varias librerías, una de ellas es fBasics que deberíamos tener instalada y cargada. Para obtener los resultados del test para Oracle.

jarqueberaTest(retornos$orcl)
## 
## Title:
##  Jarque - Bera Normalality Test
## 
## Test Results:
##   STATISTIC:
##     X-squared: 138.9315
##   P VALUE:
##     Asymptotic p Value: < 2.2e-16 
## 
## Description:
##  Fri Mar 03 08:29:10 2023 by user: rchang

Para los demàs activos hay que solo cambiar por el nombre de la columna correspondiente.

3.10 Apéndice

Existe más de una forma de calcular los retornos y retornos acumulados. A continuación cargaremos una base que contiene los precios al cierre desde Enero del 2013 hasta Diciembre del 2018 con periodicidad mensual de las siguientes empresas tecnológicas:

Facebook (FB) Amazon (AMZN) Apple (AAPL) Netflix (NFLX) Google (GOOG)

Ahora en adelante FAANG.

La base de datos se encuentran almacenada en Dropbox en el siguiente enlace

https://www.dropbox.com/s/tjqvs9w16al1jl2/FAANG.csv?dl=1

Como tiene una extensión csv, utilizamos:

FAANG <- read_csv("https://www.dropbox.com/s/tjqvs9w16al1jl2/FAANG.csv?dl=1")
## Rows: 72 Columns: 6
## -- Column specification --------------------------------------------------------
## Delimiter: ","
## dbl  (5): AAPL, AMZN, FB, GOOG, NFLX
## date (1): date
## 
## i Use `spec()` to retrieve the full column specification for this data.
## i Specify the column types or set `show_col_types = FALSE` to quiet this message.

De esta manera podemos descargarla inmediatamente desde dropbox a nuestra sesión en RStudio.

3.10.1 Retorno y retorno acumulado

La forma en que calcularemos el retorno logarítmico es siguiendo la formula presentado durante el capítulo:

Como tenemos la fecha (date) y el resto de las columnas con los precios, una forma es crear una objeto con tres columnas, fecha (date), symbol (tickers) y precios (prices).

Lo anterior se logra utilizando gather(symbol, prices, -date), luego agrupamos por symbol por medio de group_by(symbol) y creamos el retorno mutate(returns = log(prices/lag(prices))). Como tendremos NA usamos filter(!is.na(returns)), finalmente eliminamos la columna price y extendemos el objeto de tal forma de tener la fecha (date) y las columnas restantes sea el retorno correspondiente a cada tickers (symbol), spread(symbol, returns). Todo lo anterior se resume en el siguiente código:

# retornos 
FAANG_returns <- FAANG %>% 
  gather(symbol, prices, -date)  # en la tarea es -Date y no -date
FAANG_returns
## # A tibble: 360 x 3
##    date       symbol prices
##    <date>     <chr>   <dbl>
##  1 2013-01-01 AAPL     65.1
##  2 2013-02-01 AAPL     63.1
##  3 2013-03-01 AAPL     63.2
##  4 2013-04-01 AAPL     63.3
##  5 2013-05-01 AAPL     64.2
##  6 2013-06-01 AAPL     56.6
##  7 2013-07-01 AAPL     64.6
##  8 2013-08-01 AAPL     69.6
##  9 2013-09-01 AAPL     68.1
## 10 2013-10-01 AAPL     74.7
## # ... with 350 more rows
## # i Use `print(n = ...)` to see more rows
# retornos 
FAANG_returns <- FAANG %>% 
  gather(symbol, prices, -date) %>% # en la tarea es -Date y no -date
  group_by(symbol) %>% 
  mutate(returns = log(prices/lag(prices))) %>% 
  filter(!is.na(returns)) %>% 
  select(-prices) %>% 
  spread(symbol, returns)

La lógica para los retornos acumulados es el mismo, pero ahora no debemos trabajar con el objeto FAANG, sino con FAANG_returns.

FAANG_returns
## # A tibble: 71 x 6
##    date            AAPL     AMZN        FB     GOOG     NFLX
##    <date>         <dbl>    <dbl>     <dbl>    <dbl>    <dbl>
##  1 2013-02-01 -0.0314   -0.00464 -0.128     0.0585   0.129  
##  2 2013-03-01  0.00285   0.00837 -0.0632   -0.00879  0.00636
##  3 2013-04-01  0.000271 -0.0488   0.0821    0.0375   0.132  
##  4 2013-05-01  0.0156    0.0589  -0.131     0.0550   0.0460 
##  5 2013-06-01 -0.126     0.0311   0.0215    0.0104  -0.0694 
##  6 2013-07-01  0.132     0.0813   0.391     0.00835  0.147  
##  7 2013-08-01  0.0739   -0.0696   0.115    -0.0471   0.150  
##  8 2013-09-01 -0.0217    0.107    0.196     0.0337   0.0854 
##  9 2013-10-01  0.0920    0.152   -0.000398  0.163    0.0420 
## 10 2013-11-01  0.0619    0.0781  -0.0659    0.0278   0.126  
## # ... with 61 more rows
## # i Use `print(n = ...)` to see more rows
FAANG_acum <- FAANG_returns %>% 
  gather(symbol, returns, -date) %>% 
  group_by(symbol) %>% 
  mutate(returns_acum = cumsum(returns)) %>% 
  select(-returns) %>% 
  spread(symbol, returns_acum)
FAANG_acum
## # A tibble: 71 x 6
##    date           AAPL     AMZN     FB   GOOG  NFLX
##    <date>        <dbl>    <dbl>  <dbl>  <dbl> <dbl>
##  1 2013-02-01 -0.0314  -0.00464 -0.128 0.0585 0.129
##  2 2013-03-01 -0.0286   0.00372 -0.192 0.0497 0.136
##  3 2013-04-01 -0.0283  -0.0450  -0.109 0.0872 0.268
##  4 2013-05-01 -0.0127   0.0138  -0.241 0.142  0.314
##  5 2013-06-01 -0.139    0.0449  -0.219 0.153  0.245
##  6 2013-07-01 -0.00652  0.126    0.172 0.161  0.392
##  7 2013-08-01  0.0673   0.0567   0.287 0.114  0.541
##  8 2013-09-01  0.0456   0.163    0.483 0.148  0.627
##  9 2013-10-01  0.138    0.316    0.483 0.310  0.669
## 10 2013-11-01  0.200    0.394    0.417 0.338  0.795
## # ... with 61 more rows
## # i Use `print(n = ...)` to see more rows

3.10.2 Graficar retorno acumulado

FAANG_acum %>% 
  gather(symbol, returns_acum, -date) %>% 
  ggplot(aes(y = returns_acum, x = date, color = symbol)) + 
  geom_line(size = 1.5) + 
  labs(title = "Retornos Acumulados", subtitle = "FAANG", color = "") +
  theme_bw() + 
  theme(legend.position = "bottom", legend.direction = "horizontal") 

3.10.3 Teoría de portafolio

La teoría del portafolio considera que en las decisiones de inversión sólo se tienen en cuenta el retorno esperado y el riesgo. El primer momento de la distribución del retorno es usado como estimación del retorno esperado, y la varianza (o la desviación estándar) del retorno es empleada como medida del riesgo. En el área financiera, la desviación estándar es conocida como la volatilidad.

Vamos a obtener dos portafolios, el de mínima varianza y el portafolio tangente o media-varianza (optimo).

Comenzamos con cargar las funciones para calcular los portafolios.

#library("IntroCompFinR")

Yo “llamé” la librería que instalé con anterioridad, tambíen se puede usar source(“IntroCompFinR.R”).

Debemos tener el retorno esperado (promedio), el riesgo (desviación estandar) y la matriz de varianza-covarianza.

mean_FAANG <- apply(FAANG_returns[2:6], 2, mean)
sd_FAANG <- apply(FAANG_returns[2:6], 2, sd)
cov_FAANG <- cov(FAANG_returns[2:6])

3.10.3.1 Portafolio de mínima varianza

El portafolio de varianza mínima se refiere a un tipo de estructura de cartera que se enfoca en minimizar los riesgos en la inversión mientras maximiza el potencial de generación de ganancias.

Este tipo de cartera de inversión presenta activos individuales que tienen algún nivel de riesgo.

características de un portafolio de mínima varianza

Entre las características que destacan de un portafolio de mínima varianza podemos mencionar: 1. Maximiza el rendimiento y minimiza el riesgo. 2. Puede contener tipos de inversión que son volátiles por sí mismos, pero cuando se combinan, crean una 3. cartera diversificada con menos volatilidad que cualquiera de las partes individuales. 4. La estrategia es simple de implementar.

globalMin.portfolio <-
function(er, cov.mat, shorts=TRUE)
{
  call <- match.call()

  #
  # check for valid inputs
  #
  asset.names <- names(er)
  er <- as.vector(er) # assign names if none exist
  cov.mat <- as.matrix(cov.mat)
  N <- length(er)
  if(N != nrow(cov.mat))
    stop("invalid inputs")
  if(any(diag(chol(cov.mat)) <= 0))
    stop("Covariance matrix not positive definite")
  # remark: could use generalized inverse if cov.mat is positive semi-definite

  #
  # compute global minimum portfolio
  #
  if(shorts==TRUE){
    cov.mat.inv <- solve(cov.mat)
    one.vec <- rep(1,N)
    w.gmin <- rowSums(cov.mat.inv) / sum(cov.mat.inv)
    w.gmin <- as.vector(w.gmin)
  } else if(shorts==FALSE){
    Dmat <- 2*cov.mat
    dvec <- rep.int(0, N)
    Amat <- cbind(rep(1,N), diag(1,N))
    bvec <- c(1, rep(0,N))
    result <- quadprog::solve.QP(Dmat=Dmat,dvec=dvec,Amat=Amat,bvec=bvec,meq=1)
    w.gmin <- round(result$solution, 6)
  } else {
    stop("shorts needs to be logical. For no-shorts, shorts=FALSE.")
  }
 
  names(w.gmin) <- asset.names
  er.gmin <- crossprod(w.gmin,er)
  sd.gmin <- sqrt(t(w.gmin) %*% cov.mat %*% w.gmin)
  gmin.port <- list("call" = call,
            "er" = as.vector(er.gmin),
            "sd" = as.vector(sd.gmin),
            "weights" = w.gmin)
  class(gmin.port) <- "portfolio"
  gmin.port
}
port_min_var_FAANG <- globalMin.portfolio(mean_FAANG, cov_FAANG, shorts = TRUE) 

El retorno esperado del portafolio de mínima varianza es:

port_min_var_FAANG$er
## [1] 0.01323118

La desviación estandar es:

port_min_var_FAANG$sd
## [1] 0.04743125

y los pesos:

port_min_var_FAANG$weights
##         AAPL         AMZN           FB         GOOG         NFLX 
##  0.294616111 -0.009889592  0.156635553  0.627372021 -0.068734093

3.10.3.2 Portafolio tangente o media-varianza (óptimo)

Se debe especificar la tasa del activo libre de riesgo, la cual en el modelo de media-varianza influye en la conformación de los portafolios eficientes, y consecuentemente del portafolio óptimo o tangente.

Necesitamos una tasa libre de riesgo, asumirémos una tasa anualizada del 3%.

risk_free <- 3/1200 # debe estar mensual y no anual

tangency.portfolio <-
function(er,cov.mat,risk.free, shorts=TRUE)
{
  call <- match.call()

  #
  # check for valid inputs
  #
  asset.names <- names(er)
  if(risk.free < 0)
    stop("Risk-free rate must be positive")
  er <- as.vector(er)
  cov.mat <- as.matrix(cov.mat)
  N <- length(er)
  if(N != nrow(cov.mat))
    stop("invalid inputs")
  if(any(diag(chol(cov.mat)) <= 0))
    stop("Covariance matrix not positive definite")
  # remark: could use generalized inverse if cov.mat is positive semi-definite

  #
  # compute global minimum variance portfolio
  #
  gmin.port <- globalMin.portfolio(er, cov.mat, shorts=shorts)
  if(gmin.port$er < risk.free)
    stop("Risk-free rate greater than avg return on global minimum variance portfolio")

  # 
  # compute tangency portfolio
  #
  if(shorts==TRUE){
    cov.mat.inv <- solve(cov.mat)
    w.t <- cov.mat.inv %*% (er - risk.free) # tangency portfolio
    w.t <- as.vector(w.t/sum(w.t))          # normalize weights
  } else if(shorts==FALSE){
    Dmat <- 2*cov.mat
    dvec <- rep.int(0, N)
    er.excess <- er - risk.free
    Amat <- cbind(er.excess, diag(1,N))
    bvec <- c(1, rep(0,N))
    result <- quadprog::solve.QP(Dmat=Dmat,dvec=dvec,Amat=Amat,bvec=bvec,meq=1)
    w.t <- round(result$solution/sum(result$solution), 6)
  } else {
    stop("Shorts needs to be logical. For no-shorts, shorts=FALSE.")
  }
    
  names(w.t) <- asset.names
  er.t <- crossprod(w.t,er)
  sd.t <- sqrt(t(w.t) %*% cov.mat %*% w.t)
  tan.port <- list("call" = call,
           "er" = as.vector(er.t),
           "sd" = as.vector(sd.t),
           "weights" = w.t)
  class(tan.port) <- "portfolio"
  return(tan.port)
}
risk_free <- 3/1200 # debe estar mensual y no anual
port_tang_FAANG <- tangency.portfolio(mean_FAANG, cov_FAANG, risk_free, shorts = TRUE) 

3.10.4 Medidas de performance

De acuerdo a (Moreno, 2018) una medida de evaluación de portafolio se puede definir como una ecuación o fórmula cuyo objetivo es evaluar un portafolio, tanto en términos de riesgo y de rendimiento, para así valorar las habilidades que tiene su administrador.

Entre los primeros trabajos publicados sobre evaluación de performance de carteras se encuentran: Treynor (1965), Jensen (1968) y Sharpe (1966) (Vallejo Alonso, 2003, pág.50).

En este apéndice, veremos dos medidas de performance, Alpha de Jensen y Medida de Treynor, la que aplicaremos solo al último periodo.

Ambos se obtienen por medio de la siguiente regresión por mínimo cuadrado ordinario.

Donde rp,t es el retorno del portafolio (en este caso mínima varianza o tangente), rm,t el retorno de mercado (o benchmark), rf,t la tasa libre de riesgo, β el componente de riesgo sistemático y αjp alfa de jensen.

Alfa de Jensen

Según Jensen (1968), la performance de un fondo viene determinado por dos dimensiones: en primer lugar, por la habilidad del gestor de incrementar el rendimiento de la cartera, mediante una predicción precisa de la evolución de los precios de los activos financieros y; en segundo lugar, por su capacidad de minimizar el riesgo, mediante una diversificación adecuada de la cartera (Ruiz Martín, 2007, pág. 13).

El alfa de Jensen es una medida de performance relativa que “mide el exceso de rentabilidad obtenido por la cartera ajustado al riesgo respecto de la cartera de mercado” (Vallejo Alonso, 2003, pág. 51).

El retio de Treynor

Desarrollada por Jack L. Treynor en 1965, la ratio o índice de Treynor es la primera medida de performance que mide la rentabilidad de la cartera ajustando el riesgo sistemático (Steinki & Ziad, 2015, pág. 13).

La ratio de Treynor es un indicador absoluto que “mide el exceso de rentabilidad obtenida con respecto a los activos libres de riesgo por unidad de riesgo sistemático asumido” (Ruiz Martín, 2007, pág. 87)

El β no permitirá calcular la medida de Treynor:

Donde ri el valor esperado del portafolio, rf tasa libre de riesgo.

Como es solo una ejemplo y tenemos solo una tasa libre de riesgo deberemos calcular el retorno del portafolio rp,t y luego restarle la tasa libre de riesgo rf,t.

En el caso del portafolio de mínima varianza debemos realizar una sumaproducto de sus pesos y el retorno en cada periodo.

exceso_min_var <- as.matrix(FAANG_returns[2:6])%*%port_min_var_FAANG$weights - risk_free 

Para el portafolio tangente es el mismo procedimiento.

exceso_tangency <- as.matrix(FAANG_returns[2:6])%*%port_tang_FAANG$weights - risk_free

Solo estaría faltando un benchmark, como es un ejemplo, voy a considerar Google (GOOG), que es la columna 5 de mis retornos.

exceso_benchmark <- as.matrix(FAANG_returns[,5]) - risk_free

Ahora solo nos faltaría hacer la regresiòn para cada portafolio.

Portafolio de minima varianza:

regresion_min_var <- lm(exceso_min_var ~ exceso_benchmark)
regresion_min_var
## 
## Call:
## lm(formula = exceso_min_var ~ exceso_benchmark)
## 
## Coefficients:
##      (Intercept)  exceso_benchmark  
##         0.002254          0.718859

Nuestro alpha de jensen sería 0.0022543 y nuestra medida de Treynor:

treynor_min_var <- (mean(exceso_min_var)/coef(regresion_min_var)[2])
treynor_min_var
## exceso_benchmark 
##       0.01492807

Para portafolio tangente:

regresion_tangency <- lm(exceso_tangency ~ exceso_benchmark)
regresion_tangency
## 
## Call:
## lm(formula = exceso_tangency ~ exceso_benchmark)
## 
## Coefficients:
##      (Intercept)  exceso_benchmark  
##          0.01357           0.78993

Nuestro alpha de jensen sería 0.0022543 y nuestra medida de Treynor

treynor_tangency <- (mean(exceso_tangency)/coef(regresion_tangency)[2])
treynor_tangency
## exceso_benchmark 
##       0.02897672
  1. Proximamente incluire el tidyquant↩︎

  2. No solo funcióna con getSymbols, si no que con todas las funciones de distintas librerias, basta con ante poner ? y luego el nombre la función↩︎

  3. Por el momento solo trabajaremos con estas opciones, exiten más.↩︎

  4. TA proviene de Technical Analysis↩︎

  5. Esta base es muy común en los software estadísticos y presenta datos de autos.↩︎