suppressPackageStartupMessages({
if (!require("rmarkdown")) {
install.packages("rmarkdown")
library("rmarkdown")
}if (!require("knitr")) {
install.packages("knitr")
library("knitr")
}if (!require("quantmod")) {
install.packages("quantmod")
library("quantmod")
}if (!require("ggplot2")) {
install.packages("ggplot2")
library("ggplot2")
}if (!require("highcharter")) {
install.packages("highcharter")
library("highcharter")
}if (!require("gt")) {
install.packages("gt")
library("gt")
}if (!require("PerformanceAnalytics")) {
install.packages("PerformanceAnalytics")
library("PerformanceAnalytics")
}if (!require("tidyverse")) {
install.packages("tidyverse")
library("tidyverse")
} })
Genius2023
1 Carga de librerías
Una librería es un conjunto de funciones y paquetes preconstruidos que se <pueden utilizar para realizar una amplia variedad de tareas y nos permiten realizar análisis complejos, manipular datos, crear visualizaciones y mucho más.
Para usar una librería en R, primero debes instalarla utilizando la función install.packages()
. Una vez instalada la librería, puedes cargarla en tu sesión de R usando la función library()
. Esto hará que todas las funciones y paquetes dentro de la librería estén disponibles para su uso en tu código de R.
Hay muchas librerías disponibles en R, y están en constante actualización y expansión. Algunas de las más populares incluyen ggplot2
para visualización de datos, tidyverse
para manipulación de datos y caret
para aprendizaje automático.
En esta sesión, le vamos a dar la orden a R de verificar si cada una de las librerías que utilizaremos ya está instalada. Si no es así, la deberá de instalar y posteriormente cargarla.
2 Descarga de precios
R nos permite conectarnos a la base de datos de diversas plataformas en línea y descargar información financiera, como precios, dividendos o los estados financieros.
En este ejercicio nos conectaremos a Yahoo Finance
y descargaremos los pecios históricos de 6 activos financieros: Tesla, Apple, Amazon, Shopify, Netflix, Coca-Cola Company, American Express Company, el Bitcoin, el ETF SPY y el ETF TLT. Para ello, utilizaremos la función 'getSymbols'
y un bucle tipo 'for'
.
Tomaremos como periodo de análisis del 1 de enero de 2020 a la fecha de ayer, 23 de febrero de 2023 y tomaremos los precios diarios.
# Definir los tickers de cada activo
<- c("TSLA", "AAPL", "AMZN", "BTC-USD", "SPY","TLT","SHOP","NFLX","KO","AXP")
symbols
# Establecer las fechas de inicio y fin de la descarga de precios
<- "2020-01-01"
start_date <- Sys.Date() # fecha de hoy (en realidad baja los precios de un dia anterior)
end_date
# Creación de una tabla de datos vacía para almacenar los precios
<- NULL
prices_df
# Rutina para la descarga de los precios
suppressWarnings(
# bucle entre los distintos tickers y descarga de los precios
for (i in symbols) {
# Uso de la función getSymbolspara descargar desde Yahoo Finance
<-na.omit(cbind(prices_df,
prices_dfgetSymbols(i, from = start_date,to = end_date,
periodicity="daily",
auto.assign = FALSE)[,6]))
}
)
# Nombrar las columnas de los precios descargados
colnames(prices_df)<-symbols
# Impresion de las primeras filas de la tabla de precios
head(prices_df)
TSLA AAPL AMZN BTC-USD SPY TLT SHOP NFLX
2020-01-02 28.68400 73.44939 94.9005 6985.470 309.6949 129.5631 40.781 329.81
2020-01-03 29.53400 72.73534 93.7485 7344.884 307.3498 131.5584 40.429 325.90
2020-01-06 30.10267 73.31488 95.1440 7769.219 308.5223 130.8114 41.333 335.83
2020-01-07 31.27067 72.97008 95.3430 8163.692 307.6549 130.1683 41.450 330.75
2020-01-08 32.80933 74.14391 94.5985 8079.863 309.2946 129.3078 41.810 339.26
2020-01-09 32.08933 75.71878 95.0525 7879.071 311.3917 129.7617 43.020 335.66
KO AXP
2020-01-02 50.06427 120.6530
2020-01-03 49.79113 119.4547
2020-01-06 49.77293 118.9370
2020-01-07 49.39056 118.3138
2020-01-08 49.48160 120.3558
2020-01-09 50.38292 122.5321
3 Cálculo de los rendimientos
En esta sección comenzaremos a analizar el comportamiento de los precios de los activos selecccionados. En una primera etapa calcularemos la variación diaria
de los precios. Posteriormente, haremos el análisis de los rendimientos acumulados
, y finalmente, vamos a comparar
los resultados entre las diferentes alternativas de inversión
.
3.1 Rendimientos diarios
Para el cálculo de los rendimientos diarios, en los mercados financieros generalmente trabajamos normalizando los valores. Para ello, los transformamos aplicando logaritmos, ya que con ello podemos trabajar más fácilmente e interpretar de manera más adecuada la manera en la que se generan ganancias (o pérdidas) de manera contínua.
Además de lo anterior, trabajar con logaritmos nos permite interpretar las variaciones como cambios porcentuales, lo que a su vez interpretamos como rendimientos. De esta manera, calculamos los rendimientos diarios como la diferencia de los logaritmos de dos precios.
# Creacion de una tabla de datos solo con los rendimientos diarios
<-na.omit(diff(log(prices_df))) #diferencia de los logaritmos de los precios
returnscolnames(returns)<-symbols
head(returns)
TSLA AAPL AMZN BTC-USD SPY
2020-01-03 0.029202666 -0.009769333 -0.012213310 0.05017175 -0.007601184
2020-01-06 0.019071630 0.007936271 0.014775869 0.05616562 0.003807766
2020-01-07 0.038066697 -0.004714123 0.002089435 0.04952689 -0.002815529
2020-01-08 0.048032578 0.015958414 -0.007839285 -0.01032167 0.005315355
2020-01-09 -0.022189378 0.021018347 0.004787698 -0.02516485 0.006757604
2020-01-10 -0.006649369 0.002257984 -0.009455159 0.03583702 -0.002881736
TLT SHOP NFLX KO AXP
2020-01-03 0.015282725 -0.008668864 -0.01192616 -0.0054707243 -0.009981903
2020-01-06 -0.005694338 0.022113838 0.03001447 -0.0003655134 -0.004343414
2020-01-07 -0.004928110 0.002826693 -0.01524224 -0.0077121105 -0.005253129
2020-01-08 -0.006632527 0.008647664 0.02540400 0.0018416111 0.017112188
2020-01-09 0.003504105 0.028529555 -0.01066805 0.0180514454 0.017920553
2020-01-10 0.008851513 -0.002397106 -0.01988908 0.0034273071 -0.004155371
3.2 Rendimientos acumulados
Con el cálculo de los rendimientos acumulados vamos a ver la evolución de los beneficios (o pérdidas) de hacer una inversión en cada uno de los instrumentos seleccionados.
# Creacion de una tabla de datos solo con los rendimientos diarios acumulados
<-as.data.frame(cumsum(returns))
returns.cum$DATES<-as.Date(row.names(returns.cum)) returns.cum
3.3 Comparación de los rendimientos acumulados
Finalmente, para tener una visión más clara de las alternativas de inversión, hacemos una gráfica con los rendimientos acumulados desde el inicio del periodo de análisis (2020 a la fecha).
La gráfica está hecha en base 0, por lo que cualquier valor menor a esta referencia significa pérdida de valor, mientras que si se encuentra por arriba, significa rendimiento positivo.
# Uso de la funcion ggplot para graficar los rendimientos acumulados de cada activo
ggplot(data=returns.cum)+
geom_line(aes(x=DATES, y=SPY),colour="green", linewidth=1.6)+
geom_line(aes(x=DATES, y=TSLA),colour="gray", linewidth=1)+
geom_line(aes(x=DATES, y=AAPL),colour="cyan", linewidth=1)+
geom_line(aes(x=DATES, y=AMZN),colour="darkgreen", linewidth=1)+
geom_line(aes(x=DATES, y=`BTC-USD`),colour="yellow", linewidth=1)+
geom_line(aes(x=DATES, y=TLT),colour="blue", linewidth=1)+
geom_line(aes(x=DATES, y=SHOP),colour="red", linewidth=1)+
geom_line(aes(x=DATES, y=NFLX),colour="brown", linewidth=1)+
geom_line(aes(x=DATES, y=KO),colour="navyblue", linewidth=1)+
geom_line(aes(x=DATES, y=AXP),colour="salmon", linewidth=1)
La gráfica nos permite ver fácilmente que en estos poco más de dos años, el Bitcoin, Tesla y Apple han tenido la mayor revalorización
, mientras que Amazon y Shopify casi no han incrementado su valor
. También se puede observar que el ETF TLT
, conformado por instrumentos de deuda ha tenido rendimientos negativos.
4 Análisis Técnico del Bitcoin
Vamos a detenernos a ver con más detalle el comportamiento del Bitcoin
. en esta sección vamos a agregar algunas funciones de Análisis Técnico
, que nos ayuda a analizar características acerca de las diferentes tendencias que puede presentar el precio de algún instrumento.
En este caso, vamos a hacer una gráfica del precio del Bitcoin considerando el periodo del 1 de enro de 2015 a la fecha y agregaremos varios elementode Análisis Técnico como las Bandas de Bollinger
, Momentum, Promedios Móviles, Indice de Fuerza Relativa y la Volatilidad
.
Comenzamos primero con una gráfica sencilla de velas en la que se pueden observar los movimientos intradía y el volumen de operación de cada día.
En segundo lugar hacemos una gráfica nueva con los elementos de análisis técnico.
#Descarga de los precios
suppressWarnings({
<-getSymbols("BTC-USD",from="2015-01-01", to=Sys.Date(),
BTCperiodicity="daily",auto.assign = FALSE)
#Gráfica inicial de velas
chartSeries(BTC)
#Gráfica con fondo blanco
chartSeries(BTC, name = "Precios diarios del Bitcoin",
theme="white",
#elementos de análisis técnico
TA=c(addRSI(),addBBands(), addMomentum(n=5), addSMA(30),
addSMA(200), addEMA(10),
addVolatility(), addVo(),
addMACD(fast=12,slow=26,signal=9,type="EMA")))
})
5 Comparación de varias opciones de inversión
En esta sección vamos a ampliar nuestro análisis al comparar directamente varios instrumentos de inversión demanera visual.
En primer lugar comenzaremos con una gráfica sencilla del precio de Apple, Tesla y Amazon. Posteriormente modificaremos el tipo de gráfica para hacerla dinámica y en tercer lugar le agregaremos los movimientos diarios de cada uno de los activos analizados.
5.1 Gráfica de la evolución del valor de Apple (y Tesla)
En esta primera parte utilizaremos la funación chartseries
para graficar los precios históricos de Apple y Tesla
<-prices_df$AAPL
Apple<-prices_df$TSLA
TeslachartSeries(Apple, theme="white") #grafica sólo con Apple
addTA(Tesla, on=1, col="blue") #En esta gráfica se agregan los precios de Tesla
Como se puede observar, al agregar la serie de precios de Teslala gráfica ya no se aprecia bien, ya que la escala no se ajusta a los niveles de precios de Tesla. Para corregir esta situación, vamos a utilizar un tipo de gráfico dinámico que sí se ajuste a precios con diferntes escalas.
5.2 Gráfica con Apple, Tesla, amazon y SPY ETF
En primer lugar bajamos los precios que nos faltan. Posteriormente definimos un nuevo tipo de gráfica que se llama hchart
en la que pondremos, una por una, las alternativas de inversión con colores diferentes.
Como vamos a ver, se trata de una gráfica dinámica e interactiva que nos permite movernos a lo largo del tiempo y por diferentes periodos.
#definicion de las variables con los precios
<-prices_df$AMZN
Amazon<-prices_df$SPY
SPY<-prices_df$NFLX
Netflix<-prices_df$KO
CocaCola
hchart(Apple, name="Apple", color="maroon") %>% #creacion de la grafica con Apple
hc_add_series(Tesla, name="Tesla" , color="yellow") %>% #Agregamos Tesla
hc_add_series(Amazon, name="Amazon" , color="cyan") %>% #Agregamos Amazon
hc_add_series(SPY, name="SPY" , color="green")%>% #Agregamos el SPY
hc_add_series(Netflix, name="NFLX" , color="orangered")%>% #Agregamos Netflix
hc_add_series(CocaCola, name="KO" , color="salmon") #Agregamos Coca-Cola
5.3 Gráfica de velas
5.4 Apple
La gráfica de velas nos permite ver las variaciones que tuvo el precio de una acción dentro de una sesión. Con ello, podemos analizar también la volatilidad promedio, es decir, el riesgo.
Para esta gráfica necesitamos contar co precios a apertura, de cierre, mínimo y máximo de cada sesión. Vamos a concectarnos nuevamente a Yahoo Finance para descargarlos. En eta ocasión lo haremos sólamente con Apple, Tesla y American Express.
#Descarga de precios
<-getSymbols("AAPL",from="2020-01-01", to=Sys.Date(),
AAPLperiodicity="daily",auto.assign = FALSE)
<-getSymbols("TSLA",from="2020-01-01", to=Sys.Date(),
TSLAperiodicity="daily",auto.assign = FALSE)
<-getSymbols("AXP",from="2020-01-01", to=Sys.Date(),
AMEXperiodicity="daily",auto.assign = FALSE)
hchart(AAPL, name="Apple", color="green") #gráfica sólo de Apple
5.5 Gráfica dinámica de varios activos juntos
Utilizando la misma función hchart
, agregamos las series de precios que pondremos en la misma gráfica.
hchart(AAPL, name="Apple", color="green") %>% #Precios de Apple
hc_add_series(TSLA, name="Tesla" , color="red") %>% #Precios de Tesla
hc_add_series(AMEX, name="AMEX" , color="blue")%>% #Precios de American Express
hc_add_theme(hc_theme_538()) #Formato de la gráfica
6 Creación de portafolios de Inversión
Un portafolio es una inversión que se hace en un conjunto de activos financieros. Al invertir en un portafolio en lugar de un activo único, el invoersionista puede reducir parte del riesgo al “diversificar” (distribuir) su inversión entre distintas alternativas de inversión.
Una de las cuestiones más importantes para decidir cómo conformar un portafolio tiene que ver con estimar el desempeño esperado. Por lo general, el desempeño se mide en dos dimensiones: el rendimiento esperado del portafolio y el riesgo incurrido.
La manera más tradicional de estimar el rendimiento esperado de un portafolio es a través del cálculo del rendimiento promedio obtenido durante un periodo de tiempo. Por otro lado, existen muchas formas de estimar la exposición de riesgo de una inversion. Entre ellas, quizás la más sencilla y más utilizada es la desviación estándar de los rendimientos históricos.
En esta sección vamos definir el marco base de los cálculos necesarios para construir un portafolio de inversión
6.1 Conformación de las matrices de precios, rendimientos y covarianzas
En primera instancia vamos a formar una tabla de datos con los rendimientos históricos de todos los activos que incluimos en el ejercicio.
#Rendimientos diarios de cada activo
<-apply(returns$AAPL,2,Return.annualized)
RApple<-apply(returns$TSLA,2,Return.annualized)
RTesla<-apply(returns$SPY,2,Return.annualized)
RSPY<-apply(returns$AMZN,2,Return.annualized)
RAmazon<-apply(returns$TLT,2,Return.annualized)
RTLT<-apply(returns$`BTC-USD`,2,Return.annualized)
RBit<-apply(returns$SHOP,2, Return.annualized)
RShop<-apply(returns$NFLX,2,Return.annualized)
RNetflix<-apply(returns$KO,2,Return.annualized)
RKO<-apply(returns$AXP,2,Return.annualized)
RAmex
#Tabla de rendimientos de todos los activos
<-cbind(RApple,RTesla,RSPY,RAmazon,RTLT,
Rmedios
RBit,RShop,RNetflix,RKO,RAmex)<-cbind(returns$AAPL,returns$TSLA, returns$SPY, returns$AMZN,returns$TLT,returns$`BTC-USD`,returns$SHOP,returns$NFLX,returns$KO,returns$AXP)
rendimientoscolnames(rendimientos)<-c("Apple","Tesla","SPY","Amazon", "TLT",
"Bitcoin", "Shopify","Netflix","CocaCola","Amex")
#Matriz de covarianzas
<- cov(rendimientos, use="complete.obs") cov_matrix
6.2 Comparación de los rendimientos anualizados
Para tener una primera idea de cómo conformar el portafolio, vamos a construir una tabla con la comparación de los rendimientos medios anualizados de cada activo.
<-as.data.frame(cbind(RAmazon,RApple,RBit,
rendimientos_medios
RSPY,RTesla,RTLT,RShop,
RNetflix,RKO,RAmex))
colnames(rendimientos_medios)<-c("Amazon","Apple","Bitcoin","SPY",
"Tesla","TLT","Shopify",
"Netflix","CocaCola","Amex")
<-c("Amazon","Apple","Bitcoin","SPY","Tesla",
columnas_col"TLT","Shopify","Netflix","CocaCola","Amex")
<-c("powderblue")
colores
%>%
rendimientos_medios %>%
gt tab_header(
title = "Rendimiento promedio anualizado de cada activo (%)",
subtitle = "de 01/01/2020 al 23/02/2023") %>%
fmt_percent(columns=Amazon,
decimals = 2) %>%
fmt_percent(columns=Apple,
decimals = 2) %>%
fmt_percent(columns=Bitcoin,
decimals = 2) %>%
fmt_percent(columns=SPY,
decimals = 2) %>%
fmt_percent(columns=Tesla,
decimals = 2) %>%
fmt_percent(columns=TLT,
decimals = 2) %>%
fmt_percent(columns=Shopify,
decimals = 2) %>%
fmt_percent(columns=Netflix,
decimals = 2) %>%
fmt_percent(columns=CocaCola,
decimals = 2) %>%
fmt_percent(columns=Amex,
decimals = 2) %>%
tab_style(
locations = cells_column_labels(columns = everything()),
style = list(
#Give a thick border below
cell_borders(sides = "bottom", weight = px(3)),
#Make text bold
cell_text(weight = "bold")
)%>%
) data_color(columns=columnas_col,
colors=colores) %>%
#Apply different style to the title
tab_style(
locations = cells_title(groups = "title"),
style = list(
cell_text(weight = "bold", size = 24)
)%>%
) tab_options(heading.background.color = "#EFFBFC",
table.font.color = "#323232",
column_labels.background.color = "#FFEFDB80",
table_body.border.top.color = "#323232",
heading.border.bottom.color = "#323232",
row_group.border.top.color = "#323232") %>%
tab_style(locations = cells_column_labels(columns = everything()),
style = cell_text(align = "center"))
Rendimiento promedio anualizado de cada activo (%) | |||||||||
de 01/01/2020 al 23/02/2023 | |||||||||
Amazon | Apple | Bitcoin | SPY | Tesla | TLT | Shopify | Netflix | CocaCola | Amex |
---|---|---|---|---|---|---|---|---|---|
−7.22% | 17.19% | 11.60% | 5.07% | 42.61% | −9.18% | −22.63% | −14.10% | 2.79% | 2.04% |
6.3 Comparación del nivel de riesgo de cada inversión
Ahora haremos una tabla para comparar el nivel de riesgo de cada inversión.
#Calculo de la desviación estándar de los rendimientos de cada activo
<-apply(returns$AAPL,2,StdDev.annualized)
stApple<-apply(returns$TSLA,2,StdDev.annualized)
stTesla<-apply(returns$SPY,2,StdDev.annualized)
stSPY<-apply(returns$AMZN,2,StdDev.annualized)
stAmazon<-apply(returns$TLT,2,StdDev.annualized)
stTLT<-apply(returns$`BTC-USD`,2,StdDev.annualized)
stBit<-apply(returns$SHOP,2, StdDev.annualized)
SShop<-apply(returns$NFLX,2,StdDev.annualized)
SNetflix<-apply(returns$KO,2,StdDev.annualized)
SKO<-apply(returns$AXP,2,StdDev.annualized)
SAmex
#Tabla de las desviaciones estándar
<-as.data.frame(cbind(stAmazon,stApple,stBit,stSPY,stTesla,
riesgo_medio
stTLT,SShop,SNetflix,SKO,SAmex))
colnames(riesgo_medio)<-c("Amazon","Apple","Bitcoin","SPY","Tesla",
"TLT","Shopify","Netflix","CocaCola","Amex")
<-c("Amazon","Apple","SPY","TLT",
columnas_col2"Netflix","CocaCola","Amex")
%>%
riesgo_medio%>%
gt tab_header(
title = "Riesgo promedio anualizado de cada activo (%)",
subtitle = "de 01/01/2020 al 23/02/2023") %>%
fmt_percent(columns=Amazon,
decimals = 2) %>%
fmt_percent(columns=Apple,
decimals = 2) %>%
fmt_percent(columns=Bitcoin,
decimals = 2) %>%
fmt_percent(columns=SPY,
decimals = 2) %>%
fmt_percent(columns=Tesla,
decimals = 2) %>%
fmt_percent(columns=TLT,
decimals = 2) %>%
fmt_percent(columns=Shopify,
decimals = 2) %>%
fmt_percent(columns=Netflix,
decimals = 2) %>%
fmt_percent(columns=CocaCola,
decimals = 2) %>%
fmt_percent(columns=Amex,
decimals = 2) %>%
tab_style(
locations = cells_column_labels(columns = everything()),
style = list(
#Give a thick border below
cell_borders(sides = "bottom", weight = px(3)),
#Make text bold
cell_text(weight = "bold")
)%>%
) data_color(columns=Bitcoin,
colors="indianred") %>%
data_color(columns=Tesla,
colors="indianred") %>%
data_color(columns=Shopify,
colors="indianred") %>%
data_color(columns=columnas_col2,
colors=colores) %>%
#Apply different style to the title
tab_style(
locations = cells_title(groups = "title"),
style = list(
cell_text(weight = "bold", size = 24)
)%>%
) tab_options(heading.background.color = "#EFFBFC",
table.font.color = "#323232",
column_labels.background.color = "#FFEFDB80",
table_body.border.top.color = "#323232",
heading.border.bottom.color = "#323232",
row_group.border.top.color = "#323232") %>%
tab_style(locations = cells_column_labels(columns = everything()),
style = cell_text(align = "center"))
Riesgo promedio anualizado de cada activo (%) | |||||||||
de 01/01/2020 al 23/02/2023 | |||||||||
Amazon | Apple | Bitcoin | SPY | Tesla | TLT | Shopify | Netflix | CocaCola | Amex |
---|---|---|---|---|---|---|---|---|---|
39.41% | 36.52% | 73.04% | 24.80% | 72.53% | 18.90% | 72.64% | 53.43% | 24.43% | 44.43% |
7 Simulación de portafolios de inversión
En esta sección vamos a generar combinaciones de portafolios de inversión. Una de las vistudes más especiales de R es la capacidad de hacer operaciones complejas en relativamente poco tiempo.
En este ejercicio tenemos 1,000,000 de diferentes combinaciones y vamos buscar la que tiene el mejor desempeño. Para medir esto, consideraremos un indicador llamado Indice de Sharpe,
que pondera el rendimiento de cada portafolio con su nivel de riesgo.
# parametros iniciales
<-1000000 #número de portafolios a simular
sim<-10 # numero de alternativas de inversion en cada portafolio
nt<-0.11 #tasa de interes "libre de riesgo"
tasa_interes<-c("Apple","Tesla","SPY","Amazon", "TLT","Bitcoin",
Activos"Shopify","Netflix","CocaCola","Amex")
<-matrix(0,sim,3+nt)
portcolnames(port)<-c("Rendimiento","Riesgo","Sharpe",Activos)
#bucle generador de la matriz de portafolios de inversion
for(i in 1:sim){
<-(runif(10,0,1)) #random weights
we<-sum(we)
s<-we/s #
we<-we%*%t(Rmedios)
rendimiento_portafolio<-sqrt(t(we)%*%cov_matrix%*%we*252)
riesgo_portafolio<-rendimiento_portafolio-tasa_interes/riesgo_portafolio
Sharpe1]<-rendimiento_portafolio
port[i,2]<-riesgo_portafolio
port[i,3]<-Sharpe
port[i,4:(3+nt)]<-we
port[i, }
7.1 Gráfica de los portafolios simulados
En esta grafica vamos poder identificar lo que se conoce como frontera eficiente, que es el rango de los portafolios factibles con el mejor rendimiento posible para cada nivel de riesgo.
Vamos autilizar una función nueva para graficar que se llama ggplot
<-as.data.frame(port)
port2ggplot(port2, aes(x=Riesgo,y=Rendimiento, color=Sharpe))+ geom_point(alpha=.4)
7.2 Identificación del portafolio óptimo
La pregunta que se nos viene a la mente es ¿cuál de todos estos portafolios es el mejor? Para responder esta pregunta, vamos a idenfiticar la combinación que cuenta con el Indice de Sharpe más alto.
En el código que sigue, encontramos ese portafolio y lo marcamos con un punto rojo dentro de la gráfica.
#Identificación del portafolio óptimo
<- port2[port2$Sharpe==max(port2$Sharpe),]
portafolio_optimo
ggplot(port2, aes(x=Riesgo,y=Rendimiento, color=Sharpe))+
geom_point(alpha=.4)+
geom_point(data=portafolio_optimo, aes(x=Riesgo, y=Rendimiento),
color="darkred", size=3)
7.3 Composición del portafolio óptimo
Ya vimos cuál es el portafolio que tiene el mejor desempeño en la gráfica. Ahora vamos a ver, en una tabla, cómo se compone.
#parametros de la tabla
<-c("Rendimiento","Riesgo","Sharpe")
columnas_col<-c("gray")
colores<-c("Apple","Amazon","SPY","TLT", "Netflix", "CocaCola","Amex")
columnas_col2<-c("azure2")
colores2
%>%
portafolio_optimo %>%
gt tab_header(
title = "Composición del portafolio óptimo",
subtitle = "% de inversión en cada activo"
%>%
) fmt_percent(columns=Rendimiento,
decimals = 2) %>%
fmt_percent(columns=Riesgo,
decimals = 2) %>%
fmt_percent(columns=Sharpe,
decimals = 2) %>%
fmt_percent(columns=Apple,
decimals = 2) %>%
fmt_percent(columns=Tesla,
decimals = 2) %>%
fmt_percent(columns=SPY,
decimals = 2) %>%
fmt_percent(columns=Amazon,
decimals = 2) %>%
fmt_percent(columns=TLT,
decimals = 2) %>%
fmt_percent(columns=Bitcoin,
decimals = 2) %>%
fmt_percent(columns=Shopify,
decimals = 2) %>%
fmt_percent(columns=Netflix,
decimals = 2) %>%
fmt_percent(columns=CocaCola,
decimals = 2) %>%
fmt_percent(columns=Amex,
decimals = 2) %>%
tab_style(
locations = cells_column_labels(columns = everything()),
style = list(
#Give a thick border below
cell_borders(sides = "bottom", weight = px(3)),
#Make text bold
cell_text(weight = "bold")
)%>%
) #Apply different style to the title
tab_style(
locations = cells_title(groups = "title"),
style = list(
cell_text(weight = "bold", size = 24)
)%>%
) data_color(columns=columnas_col,
colors=colores) %>%
data_color(columns=Bitcoin,
colors="forestgreen") %>%
data_color(columns=Tesla,
colors="forestgreen") %>%
data_color(columns=Shopify,
colors="forestgreen") %>%
data_color(columns=columnas_col2,
colors=colores2) %>%
tab_options(heading.background.color = "#EFFBFC",
table.font.color = "#323232",
column_labels.background.color = "#FFEFDB80",
table_body.border.top.color = "#323232",
heading.border.bottom.color = "#323232",
row_group.border.top.color = "#323232") %>%
tab_style(locations = cells_column_labels(columns = everything()),
style = cell_text(align = "center"))
Composición del portafolio óptimo | ||||||||||||
% de inversión en cada activo | ||||||||||||
Rendimiento | Riesgo | Sharpe | Apple | Tesla | SPY | Amazon | TLT | Bitcoin | Shopify | Netflix | CocaCola | Amex |
---|---|---|---|---|---|---|---|---|---|---|---|---|
20.16% | 48.10% | −2.71% | 8.85% | 35.92% | 1.45% | 1.75% | 6.67% | 39.15% | 0.31% | 3.70% | 0.78% | 1.42% |
7.4 Conjunto de portafolios factibles con restricciones de riesgo
Para reducir la exposición al riesgo del portafolio, vamos a limitar que no se pueda tener más del 20% del portafolio invertido en Bitcoin, acciones de Tesla o acciones de Shopify.
Vamos a acotar también el conjunto de portafolios para que sólo se muestren los que tengan rendimientos positivos.
<-filter(port2,Bitcoin<0.2,Tesla<0.2,Shopify<0.2,Rendimiento>0) port3
7.5 Identificación del mejor portafolio
Gráfica del conjunto de portafolios factibles con las restricciones propuestas
<- port3[port3$Sharpe==max(port3$Sharpe),]
portafolio_optimo2
ggplot(port3, aes(x=Riesgo,y=Rendimiento, color=Sharpe))+
geom_point(alpha=.4)+
geom_point(data=portafolio_optimo2, aes(x=Riesgo, y=Rendimiento),
color="darkred", size=3)
7.6 Conformación del portafolio
Finalmente, mostramos la composición del portafolio óptimo con restricciones
%>%
portafolio_optimo2 %>%
gt tab_header(
title = "Composición del portafolio óptimo",
subtitle = "% de inversión en cada activo"
%>%
) fmt_percent(columns=Rendimiento,
decimals = 2) %>%
fmt_percent(columns=Riesgo,
decimals = 2) %>%
fmt_percent(columns=Sharpe,
decimals = 2) %>%
fmt_percent(columns=Apple,
decimals = 2) %>%
fmt_percent(columns=Tesla,
decimals = 2) %>%
fmt_percent(columns=SPY,
decimals = 2) %>%
fmt_percent(columns=Amazon,
decimals = 2) %>%
fmt_percent(columns=TLT,
decimals = 2) %>%
fmt_percent(columns=Bitcoin,
decimals = 2) %>%
fmt_percent(columns=Shopify,
decimals = 2) %>%
fmt_percent(columns=Netflix,
decimals = 2) %>%
fmt_percent(columns=CocaCola,
decimals = 2) %>%
fmt_percent(columns=Amex,
decimals = 2) %>%
tab_style(
locations = cells_column_labels(columns = everything()),
style = list(
#Give a thick border below
cell_borders(sides = "bottom", weight = px(3)),
#Make text bold
cell_text(weight = "bold")
)%>%
) #Apply different style to the title
tab_style(
locations = cells_title(groups = "title"),
style = list(
cell_text(weight = "bold", size = 24)
)%>%
) data_color(columns=columnas_col,
colors=colores) %>%
data_color(columns=Bitcoin,
colors="khaki") %>%
data_color(columns=Tesla,
colors="khaki") %>%
data_color(columns=Shopify,
colors="khaki") %>%
data_color(columns=columnas_col2,
colors=colores2) %>%
tab_options(heading.background.color = "#EFFBFC",
table.font.color = "#323232",
column_labels.background.color = "#FFEFDB80",
table_body.border.top.color = "#323232",
heading.border.bottom.color = "#323232",
row_group.border.top.color = "#323232") %>%
tab_style(locations = cells_column_labels(columns = everything()),
style = cell_text(align = "center"))
Composición del portafolio óptimo | ||||||||||||
% de inversión en cada activo | ||||||||||||
Rendimiento | Riesgo | Sharpe | Apple | Tesla | SPY | Amazon | TLT | Bitcoin | Shopify | Netflix | CocaCola | Amex |
---|---|---|---|---|---|---|---|---|---|---|---|---|
13.57% | 38.29% | −15.16% | 32.89% | 18.60% | 3.27% | 6.60% | 2.26% | 18.83% | 6.72% | 2.37% | 0.72% | 7.76% |
8 Valor histórico del portafolio
Para terminar vamos a ver cómo se habría comportado el valor del protafolio si hubiéramos invertido en él desde el 1 de enero de 2020.
library(scales)
Attaching package: 'scales'
The following object is masked from 'package:purrr':
discard
The following object is masked from 'package:readr':
col_factor
<-1000000
inversion<-t(as.matrix(portafolio_optimo2[4:13]))*inversion
holdings
<-as.matrix(cbind(prices_df$AAPL,prices_df$TSLA, prices_df$SPY,
portafolio$AMZN,prices_df$TLT,
prices_df$`BTC-USD`,prices_df$SHOP,
prices_df$NFLX,prices_df$KO,prices_df$AXP))
prices_df<-holdings/portafolio[1,]
acciones<-as.data.frame(portafolio%*%acciones)
valor_portafolio$fechas<-as.Date(row.names(valor_portafolio))
valor_portafoliocolnames(valor_portafolio)[1]<-"Valor"
ggplot(data=valor_portafolio, aes(x=fechas, y=Valor))+
geom_line(color="blue", linewidth=1)+
geom_area(fill="midnightblue", alpha=0.3)+
ggtitle("Valor histórico del portafolio")+
theme(plot.title = element_text(size=20, face="bold",
margin = margin(10, 0, 10, 0)))+
labs(x="Fechas", y="$ mxn")+
scale_y_continuous(labels = comma)+
geom_hline(yintercept = inversion, colour="red", size=1)
Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
ℹ Please use `linewidth` instead.