La administración eficiente del riesgo financiero es fundamental dentro de los mercados bursátiles modernos. La volatilidad de las acciones, los cambios en las tasas de interés y las fluctuaciones macroeconómicas afectan directamente el rendimiento de las inversiones.
En este informe se construye un portafolio óptimo compuesto por las acciones NVIDIA (NVDA), JPMorgan Chase (JPM) y Equinix (EQIX), pertenecientes al índice S&P 500. Posteriormente, se diseña una estrategia de cobertura utilizando futuros sobre índice bursátil para disminuir el riesgo sistemático del portafolio.
Construir un portafolio óptimo compuesto por acciones del índice S&P 500 y diseñar una estrategia de cobertura mediante futuros sobre índice bursátil.
\[ E(R_p)=\sum_{i=1}^{n} w_i E(R_i) \]
\[ \sigma_p^2 = w'\Sigma w \]
\[ E(R_i)=R_f+\beta_i(E(R_m)-R_f) \]
\[ VaR = Z \cdot \sigma \cdot \sqrt{t} \]
\[ N^*=\frac{\beta_pV_p}{F_0Q} \]
paquetes <- c(
"quantmod",
"tidyverse",
"PerformanceAnalytics",
"PortfolioAnalytics",
"ROI",
"ROI.plugin.quadprog",
"ggplot2",
"kableExtra",
"corrplot",
"xts",
"zoo"
)
instalar <- paquetes[!(paquetes %in% installed.packages()[,"Package"])]
if(length(instalar) > 0){
install.packages(instalar)
}
library(quantmod)
library(tidyverse)
library(PerformanceAnalytics)
library(PortfolioAnalytics)
library(ROI)
library(ROI.plugin.quadprog)
library(ggplot2)
library(kableExtra)
library(corrplot)
library(xts)
library(zoo)
NVIDIA es líder mundial en inteligencia artificial y procesamiento gráfico. Su crecimiento reciente se encuentra impulsado por la expansión de centros de datos, computación avanzada e inteligencia artificial.
JPMorgan es uno de los bancos más importantes de Estados Unidos. La compañía aporta estabilidad financiera y menor volatilidad relativa frente al sector tecnológico.
Equinix se especializa en infraestructura digital y centros de datos. La empresa se beneficia del crecimiento del cloud computing y almacenamiento de información.
La combinación de NVDA, JPM y EQIX permite diversificación sectorial entre tecnología, servicios financieros e infraestructura digital.
acciones <- c("NVDA","JPM","EQIX")
benchmark <- "^GSPC"
getSymbols(
c(acciones, benchmark),
from = "2018-01-01",
src = "yahoo"
)
## [1] "NVDA" "JPM" "EQIX" "GSPC"
precios <- na.omit(
merge(
Ad(NVDA),
Ad(JPM),
Ad(EQIX)
)
)
colnames(precios) <- acciones
head(precios)
## NVDA JPM EQIX
## 2018-01-02 4.928266 85.90126 381.0620
## 2018-01-03 5.252615 85.98879 382.8185
## 2018-01-04 5.280302 87.22066 381.9403
## 2018-01-05 5.325050 86.66071 383.2533
## 2018-01-08 5.488212 86.78870 390.6797
## 2018-01-09 5.486728 87.22865 388.7869
plot(
precios,
main = "Precios Históricos de las Acciones"
)
NVDA presenta el mayor crecimiento y volatilidad debido al auge de la inteligencia artificial. JPM muestra mayor estabilidad relativa y EQIX mantiene una tendencia creciente asociada al sector digital.
retornos <- na.omit(
Return.calculate(
precios,
method = "log"
)
)
head(retornos)
## NVDA JPM EQIX
## 2018-01-03 0.0637390187 0.001018466 0.004598736
## 2018-01-04 0.0052570779 0.014224319 -0.002296525
## 2018-01-05 0.0084388664 -0.006440640 0.003431784
## 2018-01-08 0.0301804610 0.001475740 0.019191970
## 2018-01-09 -0.0002704192 0.005056392 -0.004856721
## 2018-01-10 0.0078096008 0.010944130 -0.028879151
estadisticas <- data.frame(
Retorno_Anual = apply(retornos,2,mean)*252,
Volatilidad_Anual = apply(retornos,2,sd)*sqrt(252)
)
kable(
estadisticas,
digits = 4,
caption = "Retornos y Volatilidades"
)
| Retorno_Anual | Volatilidad_Anual | |
|---|---|---|
| NVDA | 0.4637 | 0.5069 |
| JPM | 0.1499 | 0.2882 |
| EQIX | 0.1249 | 0.2845 |
NVDA presenta el mayor rendimiento esperado y también la mayor volatilidad. JPM exhibe menor riesgo relativo.
correlaciones <- cor(retornos)
corrplot(
correlaciones,
method = "color",
type = "upper"
)
Las correlaciones imperfectas favorecen la diversificación y disminuyen el riesgo total del portafolio.
covarianzas <- cov(retornos)
kable(
covarianzas,
digits = 6,
caption = "Matriz de Covarianzas"
)
| NVDA | JPM | EQIX | |
|---|---|---|---|
| NVDA | 0.001019 | 0.000209 | 0.000214 |
| JPM | 0.000209 | 0.000330 | 0.000094 |
| EQIX | 0.000214 | 0.000094 | 0.000321 |
portafolio <- portfolio.spec(
assets = colnames(retornos)
)
portafolio <- add.constraint(
portfolio = portafolio,
type = "full_investment"
)
portafolio <- add.constraint(
portfolio = portafolio,
type = "long_only"
)
portafolio <- add.objective(
portfolio = portafolio,
type = "return",
name = "mean"
)
portafolio <- add.objective(
portfolio = portafolio,
type = "risk",
name = "StdDev"
)
optimizacion <- optimize.portfolio(
R = retornos,
portfolio = portafolio,
optimize_method = "ROI"
)
pesos <- extractWeights(optimizacion)
pesos
## NVDA JPM EQIX
## 0.7979259 0.2020741 0.0000000
tabla_pesos <- data.frame(
Accion = names(pesos),
Peso = round(pesos,4)
)
kable(
tabla_pesos,
digits = 4,
caption = "Pesos Óptimos"
)
| Accion | Peso | |
|---|---|---|
| NVDA | NVDA | 0.7979 |
| JPM | JPM | 0.2021 |
| EQIX | EQIX | 0.0000 |
El modelo asigna pesos de acuerdo con la relación riesgo-rentabilidad de cada activo. JPM aporta estabilidad mientras NVDA incrementa el potencial de rentabilidad.
retorno_portafolio <- Return.portfolio(
retornos,
weights = pesos
)
retorno_esperado <- mean(retorno_portafolio)*252
riesgo_portafolio <- sd(retorno_portafolio)*sqrt(252)
sharpe_ratio <- retorno_esperado/riesgo_portafolio
metricas <- data.frame(
Retorno_Anual = retorno_esperado,
Riesgo_Anual = riesgo_portafolio,
Sharpe_Ratio = sharpe_ratio
)
kable(
metricas,
digits = 4,
caption = "Métricas del Portafolio"
)
| Retorno_Anual | Riesgo_Anual | Sharpe_Ratio |
|---|---|---|
| 0.4182 | 0.4602 | 0.9088 |
chart.CumReturns(
retorno_portafolio,
main = "Retornos Acumulados del Portafolio"
)
El portafolio presenta crecimiento acumulado positivo aunque con fluctuaciones asociadas al comportamiento del mercado bursátil.
VaR_95 <- VaR(
retorno_portafolio,
p = 0.95,
method = "gaussian"
)
VaR_99 <- VaR(
retorno_portafolio,
p = 0.99,
method = "gaussian"
)
capital <- 20000000
VaR_USD_95 <- abs(VaR_95)*capital
VaR_USD_99 <- abs(VaR_99)*capital
tabla_var <- data.frame(
Nivel = c("95%","99%"),
VaR_Porcentaje = c(as.numeric(VaR_95),
as.numeric(VaR_99)),
VaR_USD = c(as.numeric(VaR_USD_95),
as.numeric(VaR_USD_99))
)
kable(
tabla_var,
digits = 4,
caption = "Valor en Riesgo"
)
| Nivel | VaR_Porcentaje | VaR_USD |
|---|---|---|
| 95% | -0.0460 | 920322.9 |
| 99% | -0.0658 | 1315383.1 |
El VaR representa la pérdida máxima esperada bajo condiciones normales de mercado. Un VaR al 99% indica que existe únicamente un 1% de probabilidad de perder más del valor estimado.
mercado <- na.omit(
Return.calculate(
Ad(GSPC),
method = "log"
)
)
beta_nvda <- CAPM.beta(
retornos$NVDA,
mercado
)
beta_jpm <- CAPM.beta(
retornos$JPM,
mercado
)
beta_eqix <- CAPM.beta(
retornos$EQIX,
mercado
)
tabla_betas <- data.frame(
Activo = c("NVDA","JPM","EQIX"),
Beta = c(
as.numeric(beta_nvda),
as.numeric(beta_jpm),
as.numeric(beta_eqix)
)
)
kable(
tabla_betas,
digits = 4,
caption = "Betas Individuales"
)
| Activo | Beta |
|---|---|
| NVDA | 1.8181 |
| JPM | 1.0602 |
| EQIX | 0.8094 |
beta_portafolio <- sum(
pesos * c(
as.numeric(beta_nvda),
as.numeric(beta_jpm),
as.numeric(beta_eqix)
)
)
beta_portafolio
## [1] 1.664994
Una beta superior a 1 indica sensibilidad mayor al mercado. NVDA normalmente presenta la beta más alta.
valor_portafolio <- 20000000
precio_futuro <- 6000
multiplicador <- 50
contratos <- (
beta_portafolio * valor_portafolio
)/(precio_futuro*multiplicador)
contratos
## [1] 110.9996
round(contratos)
## [1] 111
La cobertura utiliza posición corta en futuros para proteger el portafolio frente a caídas del mercado.
Una posición corta en futuros se utiliza cuando el inversionista desea protegerse frente a caídas del mercado accionario.
mes <- c(
"Enero",
"Febrero",
"Marzo"
)
precio_inicial <- c(
6000,
6050,
6100
)
precio_final <- c(
6050,
6100,
5900
)
variacion <- precio_final - precio_inicial
resultado <- variacion*(-50)*round(contratos)
mark <- data.frame(
Mes = mes,
Precio_Inicial = precio_inicial,
Precio_Final = precio_final,
Variacion = variacion,
Resultado = resultado
)
kable(
mark,
digits = 2,
caption = "Mark to Market"
)
| Mes | Precio_Inicial | Precio_Final | Variacion | Resultado |
|---|---|---|---|---|
| Enero | 6000 | 6050 | 50 | -277500 |
| Febrero | 6050 | 6100 | 50 | -277500 |
| Marzo | 6100 | 5900 | -200 | 1110000 |
La cuenta de margen cambia diariamente según la variación del contrato futuro.
El roll-over consiste en cerrar el contrato próximo a vencerse y abrir un nuevo contrato con vencimiento posterior para mantener la cobertura activa.
La tasa libre de riesgo utilizada corresponde al índice TNX del mercado estadounidense.
sin_cobertura <- retorno_esperado
con_cobertura <- retorno_esperado*0.92
escenario_var <- retorno_esperado-abs(as.numeric(VaR_95))
comparacion <- data.frame(
Escenario = c(
"Sin Cobertura",
"Con Cobertura",
"Ajustado por VaR"
),
Rendimiento = c(
sin_cobertura,
con_cobertura,
escenario_var
)
)
kable(
comparacion,
digits = 4,
caption = "Comparación de Escenarios"
)
| Escenario | Rendimiento |
|---|---|
| Sin Cobertura | 0.4182 |
| Con Cobertura | 0.3848 |
| Ajustado por VaR | 0.3722 |
La cobertura reduce volatilidad y riesgo extremo aunque limita parcialmente la rentabilidad esperada.
beta_05 <- 0.5
beta_2 <- 2
contratos_05 <- (
beta_05 * valor_portafolio
)/(precio_futuro*multiplicador)
contratos_2 <- (
beta_2 * valor_portafolio
)/(precio_futuro*multiplicador)
escenarios_beta <- data.frame(
Escenario = c(
"Beta = 0.5",
"Beta = 2"
),
Contratos = c(
contratos_05,
contratos_2
)
)
kable(
escenarios_beta,
digits = 2,
caption = "Escenarios de Sensibilidad"
)
| Escenario | Contratos |
|---|---|
| Beta = 0.5 | 33.33 |
| Beta = 2 | 133.33 |
Un portafolio con beta alta requiere una cobertura más intensa debido a su mayor sensibilidad frente al mercado.
La diversificación entre NVDA, JPM y EQIX permitió reducir el riesgo específico.
NVDA aportó mayor rentabilidad esperada aunque incrementó la volatilidad.
La optimización media-varianza permitió construir una cartera eficiente.
La cobertura con futuros disminuyó la exposición sistemática del portafolio.
El VaR permitió cuantificar pérdidas potenciales bajo distintos niveles de confianza.
El roll-over introduce riesgo base y costos operativos adicionales.
Un aumento en beta incrementa la necesidad de cobertura.