# librerias y carga de bases
library(dplyr)
library(readr)
library(tidyverse)
library(tidyquant)
library(tidyr)
library(highcharter)
library(tibble)


ETFs<-read_csv("dataset/ETFs.csv")
weight<-c(SPY=0.25,EFA=0.25,IJS=0.2,EEM=0.2,AGG=0.1)
ETFs_code<-c('SPY','EFA','IJS','EEM','AGG')

Este documento trata sobre los Exchange Traded Funds (ETFs) desde Agosto 2003 hasta Noviembre 2018, frecuancia mensual. La finalidad es utilizar funciones financieras para el análisis y comprensión de estos activos.

1 - Creación de portafolios con ETFs

Considerando los cincos ETFs (retornos), se construye un portafolio siguiendo los pesos (weighted) que crean un portafolio genérico.

Activo Detalle Peso
SPY S&P50 25%
EFA Non-US equitie 25%
IJS Small-cap value 20%
EEM Emerging-markets 20%
AGG Bonds 10%

Como Benchmark se utilizará el activo SPY, que consolida los 500 activos mas transados del mercado de EEUU.

ETFs_long<-tidyr::pivot_longer(data=ETFs,cols=ETFs_code,
                               names_to = "ETF",
                               values_to = "ret") 

portfolio_returns<-ETFs_long %>%                    #portafolio
  tq_portfolio(assets_col =  ETF,
    returns_col = ret,
    weights = weight,
    col_rename = "returns",
    rebalance_on = "months")

ETFs<-ETFs%>%left_join(portfolio_returns,by='date')# join con la base completa
ETFs<-ETFs%>%dplyr::rename(Portafolio=returns)

# PDF
ETFs%>%ggplot(aes(x=date,y=Portafolio))+geom_bar(stat='Identity')+
  labs(title="Retorno del portafolio con ETFs",
       subtitle = "2003-2018",x="Fecha",y="Retorno")+
  theme_minimal()

# HTML
# hchart(ETFs,"column",hcaes(x='date',y=Portafolio))%>%
#     hc_yAxis(title = list(text = 'Retorno'))%>%
#     hc_xAxis(title = list(text = 'Fecha'))

2 - Retorno anualizado

# Ra es un vector o lista de números.
#La función se aplica a ese vector directamente
Fun.ret_anualizado <- function(Ra) {
  prod(1+Ra)^(12/length(Ra))
}
#genero el tibble
ETFs2<-ETFs%>%select(-c(date,GS10,GS3M))
#aplico función por columna
ret.anualizado.todos<-apply(ETFs2,2,Fun.ret_anualizado)
#busco el máximo
max.ret<-max(apply(ETFs%>%select(-date),2,Fun.ret_anualizado))
# match del máximo con los nombres (buscarh a la mala)
max.nom.ret<-names(ETFs2[match(max.ret,ret.anualizado.todos)])

ret.anualizado.todos
##        AGG        EEM        EFA        IJS        SPY Portafolio 
##   1.000745   1.040438   1.018241   1.064915   1.057888   1.043731

El activo con mayor retorno anualizado es IJS , cuyo valor es 1.0649148

3 - Ratios de Sharpe

Rentabilidad según riesgo

#Ex.nom es el nombre de un activo
#La función busca el nombre del activo en la lista de nombres.
# La Desv.Est. se busca en el tibble con retornos
# El resto de la función utiliza el tibble con excesos de retorno
Fun.sharpe <- function(Ex.nom) {
  Ex.num<- match(Ex.nom,names(ETFs_ex))
  ((prod(1+ETFs_ex[[Ex.num]])^(12/length(ETFs_ex[[Ex.num]])))-1)/
    (12^(1/2)*sd(ETFs2[[Ex.num]])^(1/2))
}

#Genero la tibble del exceso de retorno
ETFs_ex<-as_tibble(ETFs2%>%apply(2, function(x) x-ETFs[['GS3M']]))

#aplico en cada columna
ratio.sharpe.todos<-sapply(names(ETFs_ex),Fun.sharpe)
#busco el máximo
max.sharpe<-max(sapply(names(ETFs_ex),Fun.sharpe))
# match del máximo con los nombres
max.nom.sharpe<-names(ETFs2[match(max.sharpe,ratio.sharpe.todos)])

ratio.sharpe.todos
##          AGG          EEM          EFA          IJS          SPY 
## -0.033074309  0.031537692  0.007419849  0.065444059  0.065822959 
##   Portafolio 
##  0.043441418

El activo con mayor ratio de Sharpe es SPY , cuyo valor es 0.065823

4 - Ratio de Treynor

Diferencial de rentabilidad de un activo sobre el activo libre de riesgo, ajustado por unidad de riesgo

# Beta
Fun.B<- function(Ex.nom){
  Ex.num<- match(Ex.nom,names(ETFs_ex))
  cov(ETFs_ex[[Ex.num]],ETFs_ex[["SPY"]])/  #SPY es benchmark
    var(ETFs_ex[[Ex.num]])
}
# Treynor
Fun.Traynor<- function(Ex.nom){
  Ex.num<- match(Ex.nom,names(ETFs_ex))
  mean(ETFs_ex[[Ex.num]])/Fun.B(Ex.nom) 
  #Notar que el promedio de cada una de las restas es igual al promedio del retorno menos el promedio del retorno libre de riesgo. Así que puedo usar el vector que contiene las restas listas.
}

#utilizo el tibble hecho en el chunk anterior ETFs_ex
#Aplico función por columna
ratio.traynor.todos<-sapply(names(ETFs_ex),Fun.Traynor)
#busco el máximo
max.traynor<-max(sapply(names(ETFs_ex),Fun.Traynor))
# match del máximo con los nombres
max.nom.traynor<-names(ETFs2[match(max.traynor,ratio.traynor.todos)])

ratio.traynor.todos
##          AGG          EEM          EFA          IJS          SPY 
## -0.003797196  0.009248164  0.002502935  0.008611832  0.004427510 
##   Portafolio 
##  0.003957553

El activo con mayor ratio de Traynor es EEM , cuyo valor es 0.0092482

5 - Tracking Error

Volatilidad de la diferencia en la rentabilidad entre un activo y un benchmark

Fun.TE <- function(Ex.nom) {
  Ex.num<- match(Ex.nom,names(ETFs_ex))
  sd(ETFs_ex[[Ex.num]]-ETFs_ex[["SPY"]])*(12^(1/2))
}

#Aplico función por columna
ratio.TE.todos<-sapply(names(ETFs_ex),Fun.TE)
#busco el máximo
max.TE<-max(sapply(names(ETFs_ex),Fun.TE))
# match del máximo con los nombres
max.nom.TE<-names(ETFs2[match(max.TE,ratio.TE.todos)])

ratio.TE.todos
##        AGG        EEM        EFA        IJS        SPY Portafolio 
## 0.13673934 0.14299834 0.08303496 0.09029886 0.00000000 0.04717720

El activo con mayor ratio de Trackinh Error es EEM , cuyo valor es 0.1429983