Introducción

El presente trabajo tiene como objetivo construir un portafolio óptimo de inversión utilizando tres acciones pertenecientes al índice S&P 500 y posteriormente desarrollar una estrategia de cobertura mediante contratos de futuros sobre dicho índice.

El horizonte de inversión es de cuatro años iniciando el 30 de abril de 2026 con un capital inicial de USD 20.000.000.

# Librerías

library(quantmod)
## Loading required package: xts
## Warning: package 'xts' was built under R version 4.3.3
## Loading required package: zoo
## Warning: package 'zoo' was built under R version 4.3.3
## 
## Attaching package: 'zoo'
## The following objects are masked from 'package:base':
## 
##     as.Date, as.Date.numeric
## Loading required package: TTR
## Warning: package 'TTR' was built under R version 4.3.3
## Registered S3 method overwritten by 'quantmod':
##   method            from
##   as.zoo.data.frame zoo
library(PerformanceAnalytics)
## Warning: package 'PerformanceAnalytics' was built under R version 4.3.3
## 
## Attaching package: 'PerformanceAnalytics'
## The following object is masked from 'package:graphics':
## 
##     legend
library(PortfolioAnalytics)
## Warning: package 'PortfolioAnalytics' was built under R version 4.3.3
## Loading required package: foreach
## Warning: package 'foreach' was built under R version 4.3.3
## Registered S3 method overwritten by 'PortfolioAnalytics':
##   method           from
##   print.constraint ROI
library(tidyverse)
## Warning: package 'tidyverse' was built under R version 4.3.3
## Warning: package 'tibble' was built under R version 4.3.3
## Warning: package 'tidyr' was built under R version 4.3.3
## Warning: package 'readr' was built under R version 4.3.3
## Warning: package 'purrr' was built under R version 4.3.3
## Warning: package 'dplyr' was built under R version 4.3.3
## Warning: package 'lubridate' was built under R version 4.3.3
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.1.4     ✔ readr     2.1.5
## ✔ forcats   1.0.1     ✔ stringr   1.6.0
## ✔ ggplot2   4.0.2     ✔ tibble    3.2.1
## ✔ lubridate 1.9.4     ✔ tidyr     1.3.1
## ✔ purrr     1.0.4
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ purrr::accumulate() masks foreach::accumulate()
## ✖ dplyr::filter()     masks stats::filter()
## ✖ dplyr::first()      masks xts::first()
## ✖ dplyr::lag()        masks stats::lag()
## ✖ dplyr::last()       masks xts::last()
## ✖ purrr::when()       masks foreach::when()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(ROI)
## ROI: R Optimization Infrastructure
## Registered solver plugins: nlminb, symphony, glpk, quadprog.
## Default solver: auto.
## 
## Attaching package: 'ROI'
## 
## The following objects are masked from 'package:PortfolioAnalytics':
## 
##     is.constraint, objective
library(ROI.plugin.quadprog)
## Warning: package 'ROI.plugin.quadprog' was built under R version 4.3.3
library(knitr)
library(scales)
## 
## Attaching package: 'scales'
## 
## The following object is masked from 'package:purrr':
## 
##     discard
## 
## The following object is masked from 'package:readr':
## 
##     col_factor
# Parámetros del ejercicio

capital_inicial <- 20000000

fecha_inicio <- "2016-04-30"
fecha_fin <- "2026-04-29"

acciones <- c("PG","SYK","WM")

indice <- "^GSPC"


# Descarga de datos históricos

getSymbols(c(acciones, indice),
           src = "yahoo",
           from = fecha_inicio,
           to = fecha_fin)
## [1] "PG"   "SYK"  "WM"   "GSPC"
precios <- na.omit(merge(
  Ad(PG),
  Ad(SYK),
  Ad(WM),
  Ad(GSPC)
))

colnames(precios) <- c("PG","SYK","WM","SP500")

head(precios)
##                  PG      SYK       WM   SP500
## 2016-05-02 61.64122 98.37417 49.96725 2081.43
## 2016-05-03 61.74020 97.68516 49.85062 2063.37
## 2016-05-04 62.12083 97.16619 50.32546 2051.12
## 2016-05-05 61.89246 98.53522 50.23384 2050.63
## 2016-05-06 62.52431 99.51055 50.55874 2057.14
## 2016-05-09 62.51670 99.60897 50.98360 2058.69
# Rendimientos logarítmicos


rendimientos <- na.omit(Return.calculate(precios,
                                         method = "log"))

head(rendimientos)
##                       PG           SYK           WM         SP500
## 2016-05-03  0.0016043933 -0.0070286221 -0.002336868 -0.0087144994
## 2016-05-04  0.0061461707 -0.0053268084  0.009480220 -0.0059545827
## 2016-05-05 -0.0036830689  0.0139911974 -0.001822237 -0.0002390367
## 2016-05-06  0.0101572200  0.0098496631  0.006446957  0.0031696106
## 2016-05-09 -0.0001218472  0.0009885439  0.008368146  0.0007532133
## 2016-05-10  0.0043741361  0.0038552432  0.002447723  0.0124063652
# Estadísticas descriptivas

## Retornos esperados anualizados


retornos_esperados <- colMeans(rendimientos[,1:3]) * 252

kable(data.frame(
  Acción = names(retornos_esperados),
  Retorno_Anual = round(retornos_esperados,4)
))
Acción Retorno_Anual
PG PG 0.0887
SYK SYK 0.1188
WM WM 0.1521
## Matriz de covarianza

covarianza <- cov(rendimientos[,1:3]) * 252

kable(round(covarianza,6))
PG SYK WM
PG 0.035716 0.019230 0.018355
SYK 0.019230 0.068346 0.023956
WM 0.018355 0.023956 0.037875
# Optimización media-varianza


portafolio <- portfolio.spec(assets = acciones)

portafolio <- add.constraint(
  portfolio = portafolio,
  type = "full_investment"
)

portafolio <- add.constraint(
  portfolio = portafolio,
  type = "long_only"
)

portafolio <- add.objective(
  portfolio = portafolio,
  type = "risk",
  name = "var"
)

optimizacion <- optimize.portfolio(
  R = rendimientos[,1:3],
  portfolio = portafolio,
  optimize_method = "ROI"
)

pesos <- extractWeights(optimizacion)

pesos
##        PG       SYK        WM 
## 0.4826335 0.1162577 0.4011088
# Distribución óptima del capital


distribucion <- data.frame(
  Acción = names(pesos),
  Peso = round(pesos,4),
  Inversión_USD = round(pesos * capital_inicial,2)
)

kable(distribucion)
Acción Peso Inversión_USD
PG PG 0.4826 9652669
SYK SYK 0.1163 2325154
WM WM 0.4011 8022177
# Rendimiento y volatilidad del portafolio


retorno_portafolio <- sum(retornos_esperados * pesos)

volatilidad_portafolio <- sqrt(
  t(pesos) %*%
    covarianza %*%
    pesos
)

resultado_portafolio <- data.frame(
  Retorno_Esperado = round(retorno_portafolio,4),
  Volatilidad = round(volatilidad_portafolio,4)
)

kable(resultado_portafolio)
Retorno_Esperado Volatilidad
0.1176 0.1638
# Cálculo del VaR


nivel_confianza <- 0.95

z <- qnorm(1 - nivel_confianza)

VaR <- capital_inicial * (
  retorno_portafolio/252 +
    z * (volatilidad_portafolio/sqrt(252))
)

VaR
##           [,1]
## [1,] -330146.5
# Estimación de Betas CAPM

betas <- c()

mercado <- rendimientos$SP500

for(i in acciones){

  covarianza_beta <- cov(
    rendimientos[,i],
    mercado
  )

  beta <- covarianza_beta /
    var(mercado)

  betas[i] <- beta
}

kable(data.frame(
  Acción = names(betas),
  Beta = round(betas,4)
))
Acción Beta
PG PG 0.4849
SYK SYK 0.9701
WM WM 0.5633
# Beta del portafolio

beta_portafolio <- sum(
  pesos * betas
)

beta_portafolio
## [1] 0.5727505

Cobertura con futuros

Características del futuro E-mini S&P 500

Característica Valor
Activo subyacente S&P 500
Multiplicador 50 USD
Precio futuro inicial 5200
Valor nocional 260000 USD
Margen inicial 21867 USD
Margen mantenimiento 19879 USD
Liquidación Mark-to-market
Frecuencia práctica Diaria
Frecuencia académica Mensual

Número óptimo de contratos

precio_futuro <- 5200

multiplicador <- 50

valor_contrato <- precio_futuro * multiplicador

num_contratos <- (
  beta_portafolio *
  capital_inicial
) / valor_contrato

num_contratos
## [1] 44.05773
# Simulación mark-to-market mensual

set.seed(123)

meses <- 48

cambios <- rnorm(
  meses,
  mean = 0,
  sd = 0.03
)

precios_futuros <- c(precio_futuro)

for(i in 1:meses){

  nuevo_precio <- precios_futuros[i] *
    (1 + cambios[i])

  precios_futuros <- c(
    precios_futuros,
    nuevo_precio
  )
}

ganancias <- diff(precios_futuros) *
  multiplicador *
  round(num_contratos)

tabla_mtm <- data.frame(
  Mes = 1:meses,
  Precio_Futuro = round(precios_futuros[-1],2),
  Ganancia_Perdida = round(ganancias,2)
)

kable(head(tabla_mtm,12))
Mes Precio_Futuro Ganancia_Perdida
1 5112.57 -192355.24
2 5077.26 -77668.64
3 5314.68 522322.04
4 5325.92 24732.15
5 5346.58 45446.05
6 5621.67 605202.34
7 5699.41 171013.91
8 5483.10 -475866.42
9 5370.12 -248561.60
10 5298.32 -157955.05
11 5492.89 428048.29
12 5552.18 130443.57
# Evolución histórica de las acciones


chart.CumReturns(
  rendimientos[,1:3],
  legend.loc = "topleft",
  main = "Rendimientos acumulados"
)

Conclusiones

  1. El portafolio óptimo fue construido utilizando el enfoque media-varianza de Markowitz.

  2. Las acciones PG, SYK y WM pertenecen al índice S&P 500 y presentan diversificación sectorial.

  3. La estrategia de cobertura mediante futuros sobre el S&P 500 permite reducir el riesgo sistemático del portafolio.

  4. El cálculo del número óptimo de contratos se realizó utilizando la beta del portafolio.

  5. La estrategia incorpora ajustes mensuales mark-to-market y roll-over trimestral para mantener la cobertura durante el horizonte de inversión.

# Librerías necesarias
library(quantmod)
library(PerformanceAnalytics)
library(tidyverse)


# Retornos logarítmicos periódicos


retornos <- na.omit(Return.calculate(precios, method = "log"))
head(retornos) 
##                       PG           SYK           WM         SP500
## 2016-05-03  0.0016043933 -0.0070286221 -0.002336868 -0.0087144994
## 2016-05-04  0.0061461707 -0.0053268084  0.009480220 -0.0059545827
## 2016-05-05 -0.0036830689  0.0139911974 -0.001822237 -0.0002390367
## 2016-05-06  0.0101572200  0.0098496631  0.006446957  0.0031696106
## 2016-05-09 -0.0001218472  0.0009885439  0.008368146  0.0007532133
## 2016-05-10  0.0043741361  0.0038552432  0.002447723  0.0124063652
#Retorno promedio anual
# Supongamos datos diarios
frecuencia <- 252  # días hábiles en bolsa

retorno_anual_promedio <- colMeans(retornos) * frecuencia
retorno_anual_promedio
##         PG        SYK         WM      SP500 
## 0.08869234 0.11882452 0.15205534 0.12369071
# Desviacion estandar anualizada

desviacion_anual <- apply(
  rendimientos,
  2,
  sd
) * sqrt(252)

desviacion_anual
##        PG       SYK        WM     SP500 
## 0.1889868 0.2614302 0.1946145 0.1811886
# Matriz de varianzas y covarianzas
matriz_covarianza <- cov(retornos) * frecuencia
matriz_covarianza
##               PG        SYK         WM      SP500
## PG    0.03571601 0.01923032 0.01835534 0.01591849
## SYK   0.01923032 0.06834577 0.02395606 0.03184708
## WM    0.01835534 0.02395606 0.03787482 0.01849310
## SP500 0.01591849 0.03184708 0.01849310 0.03282933
# Matriz de correlaciones
matriz_correlacion <- cor(retornos)
matriz_correlacion
##              PG       SYK        WM     SP500
## PG    1.0000000 0.3892236 0.4990635 0.4648785
## SYK   0.3892236 1.0000000 0.4708519 0.6723306
## WM    0.4990635 0.4708519 1.0000000 0.5244493
## SP500 0.4648785 0.6723306 0.5244493 1.0000000

Explicación de anualización

La anualización se realiza considerando una frecuencia de 252 días hábiles bursátiles por año.

Retornos promedio: se multiplican por 252 Desviación estándar: se multiplica por √252 Covarianza: se multiplica por 252 Correlación: no requiere anualización porque es adimensional

R <- na.omit(Return.calculate(precios, method="log"))

# Retornos anualizados
mu <- colMeans(R) * 252

# Volatilidad anualizada
sigma <- apply(R, 2, sd) * sqrt(252)

# Covarianza anualizada
cov_matrix <- cov(R) * 252

# Correlación
cor_matrix <- cor(R)

mu
##         PG        SYK         WM      SP500 
## 0.08869234 0.11882452 0.15205534 0.12369071
sigma
##        PG       SYK        WM     SP500 
## 0.1889868 0.2614302 0.1946145 0.1811886
cov_matrix
##               PG        SYK         WM      SP500
## PG    0.03571601 0.01923032 0.01835534 0.01591849
## SYK   0.01923032 0.06834577 0.02395606 0.03184708
## WM    0.01835534 0.02395606 0.03787482 0.01849310
## SP500 0.01591849 0.03184708 0.01849310 0.03282933
# =========================
# PUNTO 2: RETORNOS, RIESGO Y MATRICES
# Acciones: PGR, SYK, WM
# =========================

# -------------------------
# 1. Retornos periódicos
# -------------------------

returns_daily <- na.omit(
  Return.calculate(precios[,1:3], method = "log")
)

# -------------------------
# 2. Retornos anuales promedio
# -------------------------

annual_mean_returns <- apply(returns_daily, 2, function(x) {
  mean(x) * 252
})

annual_mean_returns
##         PG        SYK         WM 
## 0.08869234 0.11882452 0.15205534
# -------------------------
# 3. Desviación estándar anualizada
# -------------------------

annual_volatility <- apply(returns_daily, 2, function(x) {
  sd(x) * sqrt(252)
})

annual_volatility
##        PG       SYK        WM 
## 0.1889868 0.2614302 0.1946145
# -------------------------
# 4. Matriz de varianzas y covarianzas
# -------------------------

cov_matrix <- cov(returns_daily) * 252
cov_matrix
##             PG        SYK         WM
## PG  0.03571601 0.01923032 0.01835534
## SYK 0.01923032 0.06834577 0.02395606
## WM  0.01835534 0.02395606 0.03787482
# -------------------------
# 5. Matriz de correlaciones
# -------------------------

cor_matrix <- cor(returns_daily)
cor_matrix
##            PG       SYK        WM
## PG  1.0000000 0.3892236 0.4990635
## SYK 0.3892236 1.0000000 0.4708519
## WM  0.4990635 0.4708519 1.0000000
# -------------------------
# 6. Frecuencia de los datos
# -------------------------

cat("Frecuencia de datos: diaria (252 observaciones aproximadas por año)\n")
## Frecuencia de datos: diaria (252 observaciones aproximadas por año)
# -------------------------
# 7. Explicación de anualización
# -------------------------

cat("
Anualización aplicada:
- Retornos: media diaria * 252
- Volatilidad: desviación estándar diaria * sqrt(252)
- Varianza y covarianza: multiplicadas por 252
- Correlaciones: no requieren anualización (adimensionales)
")
## 
## Anualización aplicada:
## - Retornos: media diaria * 252
## - Volatilidad: desviación estándar diaria * sqrt(252)
## - Varianza y covarianza: multiplicadas por 252
## - Correlaciones: no requieren anualización (adimensionales)
# ==========================================
# PUNTO 3: PORTAFOLIO ÓPTIMO MEDIA-VARIANZA
# ==========================================

library(quadprog)
library(PerformanceAnalytics)

# =========================
# 1. Inputs base
# =========================

mu <- colMeans(returns_daily) * 252          # retornos esperados anualizados
Sigma <- cov(returns_daily) * 252            # matriz de covarianzas anualizada

mu
##         PG        SYK         WM 
## 0.08869234 0.11882452 0.15205534
Sigma
##             PG        SYK         WM
## PG  0.03571601 0.01923032 0.01835534
## SYK 0.01923032 0.06834577 0.02395606
## WM  0.01835534 0.02395606 0.03787482
# =========================
# 2. Portafolio de mínima varianza (base)
# =========================

n <- ncol(Sigma)

Dmat <- 2 * Sigma
dvec <- rep(0, n)

Amat <- cbind(rep(1, n), diag(n))  # suma de pesos = 1 + no short selling
bvec <- c(1, rep(0, n))

sol <- solve.QP(Dmat, dvec, Amat, bvec, meq = 1)

weights <- sol$solution
names(weights) <- colnames(returns_daily)

weights
##        PG       SYK        WM 
## 0.4826335 0.1162577 0.4011088
# =========================
# 3. Inversión total
# =========================

capital_total <- 20000000

investment <- weights * capital_total
investment
##      PG     SYK      WM 
## 9652669 2325154 8022177
# =========================
# 4. Retorno esperado del portafolio
# =========================

port_return <- sum(weights * mu)
port_return
## [1] 0.1176109
# =========================
# 5. Riesgo del portafolio (volatilidad)
# =========================

port_vol <- sqrt(as.numeric(t(weights) %*% Sigma %*% weights))

# =========================
# 6. Sharpe Ratio (rf asumido)
# =========================

rf <- 0.04  # tasa libre de riesgo aproximada (ajustable)

sharpe <- (port_return - rf) / port_vol
sharpe
## [1] 0.4737668
# =========================
# 7. Resultados finales
# =========================

cat("===== PORTAFOLIO ÓPTIMO =====\n")
## ===== PORTAFOLIO ÓPTIMO =====
cat("Pesos óptimos:\n")
## Pesos óptimos:
print(weights)
##        PG       SYK        WM 
## 0.4826335 0.1162577 0.4011088
cat("\nInversión por activo (USD):\n")
## 
## Inversión por activo (USD):
print(investment)
##      PG     SYK      WM 
## 9652669 2325154 8022177
cat("\nRetorno esperado anual del portafolio:\n")
## 
## Retorno esperado anual del portafolio:
print(port_return)
## [1] 0.1176109
cat("\nVolatilidad anual del portafolio:\n")
## 
## Volatilidad anual del portafolio:
print(port_vol)
## [1] 0.1638167
cat("\nSharpe Ratio:\n")
## 
## Sharpe Ratio:
print(sharpe)
## [1] 0.4737668
# ==========================================
# PUNTO 4: VALUE AT RISK (VaR) MENSUAL
# ==========================================

# =========================
# 1. Parámetros del portafolio
# =========================

port_vol <- sqrt(as.numeric(t(weights) %*% Sigma %*% weights))

capital_total <- 20000000

# =========================
# 2. Ajuste a horizonte mensual
# =========================

# 21 días hábiles aprox por mes
mu_mensual <- port_return / 12
sigma_mensual <- as.numeric(port_vol / sqrt(12))

# =========================
# 3. Niveles de confianza
# =========================

z_95 <- qnorm(0.95)
z_99 <- qnorm(0.99)

# =========================
# 4. VaR porcentual mensual
# =========================

VaR_95_pct <- -(mu_mensual - z_95 * sigma_mensual)
VaR_99_pct <- -(mu_mensual - z_99 * sigma_mensual)

VaR_95_pct
## [1] 0.0679839
VaR_99_pct
## [1] 0.1002116
# =========================
# 5. VaR en dólares
# =========================

VaR_95_usd <- VaR_95_pct * capital_total
VaR_99_usd <- VaR_99_pct * capital_total

VaR_95_usd
## [1] 1359678
VaR_99_usd
## [1] 2004232
# =========================
# 6. Resultados
# =========================

cat("===== VALUE AT RISK MENSUAL =====\n")
## ===== VALUE AT RISK MENSUAL =====
cat("\nVaR 95% (5% cola):\n")
## 
## VaR 95% (5% cola):
cat("Porcentaje:", VaR_95_pct, "\n")
## Porcentaje: 0.0679839
cat("Dólares:", VaR_95_usd, "\n")
## Dólares: 1359678
cat("\nVaR 99% (1% cola):\n")
## 
## VaR 99% (1% cola):
cat("Porcentaje:", VaR_99_pct, "\n")
## Porcentaje: 0.1002116
cat("Dólares:", VaR_99_usd, "\n")
## Dólares: 2004232
# =========================
# 7. Interpretación
# =========================

cat("
INTERPRETACIÓN:

El VaR representa la pérdida máxima esperada del portafolio en un horizonte mensual
bajo condiciones normales de mercado.

- VaR 95%: pérdida que no se espera superar en el 95% de los casos.
- VaR 99%: escenario extremo de estrés (solo 1% de probabilidad de pérdida mayor).

Estos valores representan el capital que potencialmente se busca proteger mediante
estrategias de cobertura con futuros sobre el índice.

A mayor nivel de confianza, mayor pérdida potencial estimada y mayor necesidad de cobertura.
")
## 
## INTERPRETACIÓN:
## 
## El VaR representa la pérdida máxima esperada del portafolio en un horizonte mensual
## bajo condiciones normales de mercado.
## 
## - VaR 95%: pérdida que no se espera superar en el 95% de los casos.
## - VaR 99%: escenario extremo de estrés (solo 1% de probabilidad de pérdida mayor).
## 
## Estos valores representan el capital que potencialmente se busca proteger mediante
## estrategias de cobertura con futuros sobre el índice.
## 
## A mayor nivel de confianza, mayor pérdida potencial estimada y mayor necesidad de cobertura.
# ==========================================
# PUNTO 5: BETA CAPM Y BETA DEL PORTAFOLIO
# ==========================================

library(quantmod)
library(PerformanceAnalytics)

# =========================
# 1. Retornos del mercado (S&P 500)
# =========================

# Ajusta esto si tu objeto tiene otro nombre
market_returns <- na.omit(Return.calculate(Ad(GSPC), method = "log"))
market_returns <- market_returns[index(returns_daily)]

# =========================
# 2. Alinear datos
# =========================

data_all <- na.omit(merge(returns_daily, market_returns))
colnames(data_all)[ncol(data_all)] <- "MKT"

# =========================
# 3. Función para calcular beta CAPM
# =========================

calc_beta <- function(stock, market) {
  cov(stock, market) / var(market)
}

# =========================
# 4. Betas individuales
# =========================

beta_PG <- calc_beta(data_all[, "PG"], data_all[, "MKT"])
beta_SYK <- calc_beta(data_all[, "SYK"], data_all[, "MKT"])
beta_WM  <- calc_beta(data_all[, "WM"],  data_all[, "MKT"])

betas <- c(
  PG = beta_PG,
  SYK = beta_SYK,
  WM = beta_WM
)
betas
##        PG       SYK        WM 
## 0.4848864 0.9700803 0.5633104
# =========================
# 5. Beta del portafolio
# =========================

beta_portafolio <- sum(weights * betas)

beta_portafolio
## [1] 0.5727505
# =========================
# 6. Resultados finales
# =========================

cat("===== BETAS CAPM =====\n")
## ===== BETAS CAPM =====
print(betas)
##        PG       SYK        WM 
## 0.4848864 0.9700803 0.5633104
cat("\n===== BETA PORTAFOLIO =====\n")
## 
## ===== BETA PORTAFOLIO =====
print(beta_portafolio)
## [1] 0.5727505
# =========================
# 7. Interpretación
# =========================

cat("
INTERPRETACIÓN:

La beta mide la sensibilidad de cada acción frente a los movimientos del mercado.

- Beta > 1: mayor volatilidad que el mercado
- Beta < 1: menor volatilidad que el mercado
- Beta = 1: comportamiento similar al índice

La beta del portafolio es el promedio ponderado de las betas individuales,
lo que refleja el riesgo sistemático total del portafolio.

Este valor es clave para determinar la cantidad de contratos de futuros
necesarios para la estrategia de cobertura.
")
## 
## INTERPRETACIÓN:
## 
## La beta mide la sensibilidad de cada acción frente a los movimientos del mercado.
## 
## - Beta > 1: mayor volatilidad que el mercado
## - Beta < 1: menor volatilidad que el mercado
## - Beta = 1: comportamiento similar al índice
## 
## La beta del portafolio es el promedio ponderado de las betas individuales,
## lo que refleja el riesgo sistemático total del portafolio.
## 
## Este valor es clave para determinar la cantidad de contratos de futuros
## necesarios para la estrategia de cobertura.
# ==========================================
# PUNTO 6: NÚMERO ÓPTIMO DE CONTRATOS DE FUTUROS
# ==========================================

# =========================
# 1. Parámetros base
# =========================

capital_total <- 20000000

# Valor del portafolio (exposición)
V_portafolio <- capital_total

# Beta del portafolio (del punto anterior)
beta_portafolio <- beta_portafolio

# =========================
# 2. Parámetros del futuro del índice
# =========================

# Supuestos típicos S&P 500
F0 <- 5000          # precio del futuro del índice (ajustable si tienes dato real)
multiplier <- 50    # multiplicador estándar S&P 500 futures

V_futuro <- F0 * multiplier

# =========================
# 3. Número óptimo de contratos
# =========================

n_contracts_raw <- (beta_portafolio * V_portafolio) / V_futuro

n_contracts_raw
## [1] 45.82004
# =========================
# 4. Redondeo óptimo
# =========================

n_contracts_round <- round(n_contracts_raw, 0)

# Regla de decisión:
# Si cobertura es para riesgo de caída → se prefiere no subcobertura → #redondear hacia arriba si es hedge short

if (n_contracts_raw > 0) {
  n_contracts_final <- ceiling(n_contracts_raw)
} else {
  n_contracts_final <- floor(n_contracts_raw)
}

n_contracts_final
## [1] 46
# =========================
# 5. Tipo de posición
# =========================

if (beta_portafolio > 0) {
  posicion <- "CORTA (Short en futuros de índice)"
} else {
  posicion <- "LARGA (Long en futuros de índice)"
}

posicion
## [1] "CORTA (Short en futuros de índice)"
# =========================
# 6. Resultados finales
# =========================

cat("===== COBERTURA CON FUTUROS =====\n")
## ===== COBERTURA CON FUTUROS =====
cat("\nNúmero teórico de contratos:\n")
## 
## Número teórico de contratos:
print(n_contracts_raw)
## [1] 45.82004
cat("\nNúmero entero recomendado:\n")
## 
## Número entero recomendado:
print(n_contracts_final)
## [1] 46
cat("\nTipo de posición:\n")
## 
## Tipo de posición:
print(posicion)
## [1] "CORTA (Short en futuros de índice)"
# =========================
# 7. Interpretación
# =========================

cat("
INTERPRETACIÓN:

El número de contratos se obtiene ajustando la exposición del portafolio
multiplicada por su beta frente al valor nominal del contrato de futuros.

Se utiliza redondeo hacia arriba en coberturas porque es preferible
sobre-cubrir ligeramente el riesgo sistemático que dejar exposición sin cubrir.

- Si el portafolio es alcista (beta positiva), la cobertura se realiza con posición CORTA.
- Esto protege contra caídas del índice.
- Si el mercado cae, la ganancia en futuros compensa la pérdida del portafolio.
- Si el mercado sube, el portafolio gana pero el futuro pierde.

La cobertura busca reducir la volatilidad del portafolio, no maximizar retorno.
")
## 
## INTERPRETACIÓN:
## 
## El número de contratos se obtiene ajustando la exposición del portafolio
## multiplicada por su beta frente al valor nominal del contrato de futuros.
## 
## Se utiliza redondeo hacia arriba en coberturas porque es preferible
## sobre-cubrir ligeramente el riesgo sistemático que dejar exposición sin cubrir.
## 
## - Si el portafolio es alcista (beta positiva), la cobertura se realiza con posición CORTA.
## - Esto protege contra caídas del índice.
## - Si el mercado cae, la ganancia en futuros compensa la pérdida del portafolio.
## - Si el mercado sube, el portafolio gana pero el futuro pierde.
## 
## La cobertura busca reducir la volatilidad del portafolio, no maximizar retorno.
7. # ==========================================
## [1] 7
# PUNTO 7: POSICIÓN EN FUTUROS Y ANÁLISIS DE COBERTURA
# ==========================================

# Se asume que ya se tiene:
# - beta_portafolio (del CAPM)
# - n_contracts_final (del punto anterior)

# =========================
# 1. Definición de la posición
# =========================

if (beta_portafolio > 0) {
  posicion_futuros <- "POSICIÓN CORTA (SHORT en futuros del índice)"
} else {
  posicion_futuros <- "POSICIÓN LARGA (LONG en futuros del índice)"
}

posicion_futuros
## [1] "POSICIÓN CORTA (SHORT en futuros del índice)"
# =========================
# 2. Interpretación de la cobertura
# =========================

cat("===== ANÁLISIS DE LA POSICIÓN EN FUTUROS =====\n\n")
## ===== ANÁLISIS DE LA POSICIÓN EN FUTUROS =====
cat("POSICIÓN ELEGIDA:\n")
## POSICIÓN ELEGIDA:
cat(posicion_futuros, "\n\n")
## POSICIÓN CORTA (SHORT en futuros del índice)
cat("OBJETIVO DE LA COBERTURA:\n")
## OBJETIVO DE LA COBERTURA:
cat("Reducir el riesgo sistemático del portafolio accionario frente a movimientos del índice de mercado.\n\n")
## Reducir el riesgo sistemático del portafolio accionario frente a movimientos del índice de mercado.
cat("CUÁNDO SE USA POSICIÓN CORTA (SHORT):\n")
## CUÁNDO SE USA POSICIÓN CORTA (SHORT):
cat("- Cuando el inversionista YA posee acciones (posición larga en el mercado accionario)\n")
## - Cuando el inversionista YA posee acciones (posición larga en el mercado accionario)
cat("- Cuando se desea PROTEGER el portafolio ante caídas del mercado\n")
## - Cuando se desea PROTEGER el portafolio ante caídas del mercado
cat("- Se utiliza para cubrir riesgo sistemático (riesgo de mercado)\n\n")
## - Se utiliza para cubrir riesgo sistemático (riesgo de mercado)
cat("CUÁNDO SE USA POSICIÓN LARGA (LONG):\n")
## CUÁNDO SE USA POSICIÓN LARGA (LONG):
cat("- Cuando el inversionista tiene exposición negativa al mercado (por ejemplo, posiciones cortas en acciones)\n")
## - Cuando el inversionista tiene exposición negativa al mercado (por ejemplo, posiciones cortas en acciones)
cat("- Cuando se desea protegerse ante SUBIDAS del mercado\n")
## - Cuando se desea protegerse ante SUBIDAS del mercado
cat("- Es menos común en portafolios tradicionales de acciones\n\n")
## - Es menos común en portafolios tradicionales de acciones
cat("RIESGO QUE SE CUBRE:\n")
## RIESGO QUE SE CUBRE:
cat("- Riesgo sistemático del mercado (movimientos del índice)\n\n")
## - Riesgo sistemático del mercado (movimientos del índice)
cat("EFECTO SI EL MERCADO SUBE:\n")
## EFECTO SI EL MERCADO SUBE:
cat("- El portafolio de acciones GANA valor\n")
## - El portafolio de acciones GANA valor
cat("- La posición en futuros (short) GENERA PÉRDIDAS\n")
## - La posición en futuros (short) GENERA PÉRDIDAS
cat("- Resultado neto: ganancia reducida pero menor volatilidad\n\n")
## - Resultado neto: ganancia reducida pero menor volatilidad
cat("EFECTO SI EL MERCADO BAJA:\n")
## EFECTO SI EL MERCADO BAJA:
cat("- El portafolio de acciones PIERDE valor\n")
## - El portafolio de acciones PIERDE valor
cat("- La posición en futuros (short) GENERA GANANCIAS\n")
## - La posición en futuros (short) GENERA GANANCIAS
cat("- Resultado neto: pérdidas compensadas parcialmente o totalmente\n\n")
## - Resultado neto: pérdidas compensadas parcialmente o totalmente
cat("CASO CLAVE (INVERSOR CON ACCIONES):\n")
## CASO CLAVE (INVERSOR CON ACCIONES):
cat("- El inversionista tiene exposición larga en acciones\n")
## - El inversionista tiene exposición larga en acciones
cat("- Su riesgo principal es una caída del mercado\n")
## - Su riesgo principal es una caída del mercado
cat("- Por eso usa FUTUROS EN POSICIÓN CORTA como seguro financiero\n")
## - Por eso usa FUTUROS EN POSICIÓN CORTA como seguro financiero
cat("- Esta estrategia funciona como un 'seguro de portafolio'\n\n")
## - Esta estrategia funciona como un 'seguro de portafolio'
cat("CONCLUSIÓN:\n")
## CONCLUSIÓN:
cat("La cobertura con futuros no busca maximizar rentabilidad, sino estabilizar el valor del portafolio,\n")
## La cobertura con futuros no busca maximizar rentabilidad, sino estabilizar el valor del portafolio,
cat("reduciendo la exposición a movimientos del mercado mediante la neutralización del riesgo sistemático.\n")
## reduciendo la exposición a movimientos del mercado mediante la neutralización del riesgo sistemático.
# ==========================================
# PUNTO 8: FLUJOS TRIMESTRALES FUTUROS + MARGEN
# ==========================================

library(dplyr)

# =========================
# 1. Parámetros del contrato
# =========================

multiplier <- 50                 # S&P 500 futures típico
F0 <- 5000                       # precio inicial del futuro (ajustable real)
n_contracts <- n_contracts_final # del punto anterior

margin_initial <- 15000          # supuesto estándar por contrato
margin_maintenance <- 12000

# =========================
# 2. Simulación de precios mensuales del futuro
# =========================

set.seed(123)

months <- 12

future_prices <- data.frame(
  mes = 1:months,
  F_inicio = NA,
  F_fin = NA,
  cambio = NA,
  pnl_long = NA,
  pnl_short = NA,
  saldo_margen = NA,
  margin_call = NA,
  reposicion = NA
)

future_prices$F_inicio[1] <- F0

for (i in 1:months) {
  
  if (i > 1) {
    future_prices$F_inicio[i] <- future_prices$F_fin[i - 1]
  }
  
  # simulación de movimiento mensual del índice (~volatilidad)
  shock <- rnorm(1, mean = 0.003, sd = 0.04)
  
  future_prices$F_fin[i] <- future_prices$F_inicio[i] * (1 + shock)
  
  # cambio
  future_prices$cambio[i] <- future_prices$F_fin[i] - future_prices$F_inicio[i]
  
  # PnL
  future_prices$pnl_long[i] <- future_prices$cambio[i] * multiplier * n_contracts
  future_prices$pnl_short[i] <- -future_prices$pnl_long[i]
  
  # margen inicial
  if (i == 1) {
    future_prices$saldo_margen[i] <- margin_initial * n_contracts
  } else {
    future_prices$saldo_margen[i] <- future_prices$saldo_margen[i-1] + future_prices$pnl_short[i]
  }
  
  # margin call
  if (future_prices$saldo_margen[i] < margin_maintenance * n_contracts) {
    future_prices$margin_call[i] <- TRUE
    
    reposicion <- (margin_initial * n_contracts) - future_prices$saldo_margen[i]
    future_prices$reposicion[i] <- reposicion
    
    future_prices$saldo_margen[i] <- margin_initial * n_contracts
  } else {
    future_prices$margin_call[i] <- FALSE
    future_prices$reposicion[i] <- 0
  }
}

future_prices
##    mes F_inicio    F_fin     cambio   pnl_long  pnl_short saldo_margen
## 1    1 5000.000 4902.905  -97.09513 -223318.80  223318.80     690000.0
## 2    2 4902.905 4872.472  -30.43282  -69995.48   69995.48     759995.5
## 3    3 4872.472 5190.880  318.40792  732338.23 -732338.23     690000.0
## 4    4 5190.880 5221.093   30.21266   69489.13  -69489.13     620510.9
## 5    5 5221.093 5263.757   42.66421   98127.68  -98127.68     690000.0
## 6    6 5263.757 5640.656  376.89867  866866.95 -866866.95     690000.0
## 7    7 5640.656 5761.572  120.91675  278108.52 -278108.52     690000.0
## 8    8 5761.572 5487.307 -274.26495 -630809.39  630809.39    1320809.4
## 9    9 5487.307 5353.010 -134.29699 -308883.07  308883.07    1629692.5
## 10  10 5353.010 5273.644  -79.36629 -182542.48  182542.48    1812234.9
## 11  11 5273.644 5547.680  274.03580  630282.34 -630282.34    1181952.6
## 12  12 5547.680 5644.168   96.48832  221923.13 -221923.13     960029.5
##    margin_call reposicion
## 1        FALSE        0.0
## 2        FALSE        0.0
## 3         TRUE   662342.7
## 4        FALSE        0.0
## 5         TRUE   167616.8
## 6         TRUE   866866.9
## 7         TRUE   278108.5
## 8        FALSE        0.0
## 9        FALSE        0.0
## 10       FALSE        0.0
## 11       FALSE        0.0
## 12       FALSE        0.0
9. ## =========================================================
## [1] 9
## ROLLOVER DE FUTUROS, COBERTURA TRIMESTRAL Y ANÁLISIS
## =========================================================

### Explicación teórica (incluida en RMarkdown)

# La estrategia de cobertura con futuros se mantiene durante todo el horizonte de inversión (4 años),
# pero los contratos deben renovarse cada trimestre debido a los vencimientos.
#
# Este proceso se conoce como "roll-over", y consiste en:
# 1. Cerrar la posición del contrato vigente al final del trimestre.
# 2. Registrar la ganancia o pérdida realizada.
# 3. Abrir una nueva posición en el contrato del siguiente vencimiento.
#
# Este mecanismo introduce:
# - Ganancias o pérdidas realizadas en cada cierre trimestral.
# - Riesgo de base (diferencia entre precio spot y futuro).
# - Posibles variaciones en la efectividad de la cobertura.
#
# Si el inversionista está LARGO en futuros:
# - Gana si el índice sube
# - Pierde si el índice cae
#
# Si está CORTO en futuros (caso típico de cobertura de acciones):
# - Gana si el mercado cae (protección)
# - Pierde si el mercado sube (compensación de pérdidas del portafolio)
#

## =========================================================
## SUPUESTOS DE TRABAJO (DEBEN EXISTIR EN TU RMD)
## =========================================================

# Retornos del portafolio ya calculado:
# port_ret_ts  -> serie de retornos mensuales del portafolio

# Precios del índice o futuro:
# futures_prices -> data.frame con columnas:
# date, price

# Número de contratos óptimos ya calculado:
# n_contracts

# Valor del portafolio:
portfolio_value <- 20000000

# =========================================================
# CREAR OBJETO futures_prices
# =========================================================

library(dplyr)
library(lubridate)

set.seed(123)

# Número de meses
months <- 48

# Fechas mensuales
dates <- seq.Date(
  from = as.Date("2022-01-01"),
  by = "month",
  length.out = months
)

# Vector de precios
price <- numeric(months)

# Precio inicial futuro
price[1] <- 5000

# Simulación de precios
for(i in 2:months){

  shock <- rnorm(1, mean = 0.002, sd = 0.04)

  price[i] <- price[i-1] * (1 + shock)
}

# Data frame final
futures_prices <- data.frame(
  date = dates,
  price = price
)

# Verificación
head(futures_prices)
##         date    price
## 1 2022-01-01 5000.000
## 2 2022-02-01 4897.905
## 3 2022-03-01 4862.605
## 4 2022-04-01 5175.506
## 5 2022-05-01 5200.453
## 6 2022-06-01 5237.748
# =========================================================
## 1. DEFINICIÓN DE TRIMESTRES
# =========================================================

library(dplyr)
library(lubridate)

futures_prices
##          date    price
## 1  2022-01-01 5000.000
## 2  2022-02-01 4897.905
## 3  2022-03-01 4862.605
## 4  2022-04-01 5175.506
## 5  2022-05-01 5200.453
## 6  2022-06-01 5237.748
## 7  2022-07-01 5607.547
## 8  2022-08-01 5722.147
## 9  2022-09-01 5444.036
## 10 2022-10-01 5305.354
## 11 2022-11-01 5221.389
## 12 2022-12-01 5487.488
## 13 2023-01-01 5577.442
## 14 2023-02-01 5678.008
## 15 2023-03-01 5714.503
## 16 2023-04-01 5598.877
## 17 2023-05-01 6010.263
## 18 2023-06-01 6141.972
## 19 2023-07-01 5671.100
## 20 2023-08-01 5841.541
## 21 2023-09-01 5742.751
## 22 2023-10-01 5508.946
## 23 2023-11-01 5471.932
## 24 2023-12-01 5258.306
## 25 2024-01-01 5115.514
## 26 2024-02-01 4997.849
## 27 2024-03-01 4670.651
## 28 2024-04-01 4836.513
## 29 2024-05-01 4875.857
## 30 2024-06-01 4663.633
## 31 2024-07-01 4906.854
## 32 2024-08-01 5000.372
## 33 2024-09-01 4951.354
## 34 2024-10-01 5138.540
## 35 2024-11-01 5329.310
## 36 2024-12-01 5515.107
## 37 2025-01-01 5678.054
## 38 2025-02-01 5815.217
## 39 2025-03-01 5812.446
## 40 2025-04-01 5752.936
## 41 2025-05-01 5676.888
## 42 2025-06-01 5530.491
## 43 2025-07-01 5495.557
## 44 2025-08-01 5228.386
## 45 2025-09-01 5692.448
## 46 2025-10-01 5978.883
## 47 2025-11-01 5722.244
## 48 2025-12-01 5641.472
futures_prices <- futures_prices %>%
  mutate(date = as.Date(date),
         quarter = paste0(year(date), "-Q", quarter(date)))

# Precio inicial y final por trimestre
quarterly <- futures_prices %>%
  group_by(quarter) %>%
  summarise(
    price_ini = first(price),
    price_fin = last(price),
    var_price = price_fin - price_ini,
    pct_change = var_price / price_ini
  )

# =========================================================
## 2. GANANCIAS/ PÉRDIDAS FUTUROS (POSICIÓN CORTA)
# =========================================================

# Valor por punto del contrato (ajustar si tienes especificación real)
contract_multiplier <- 50  # ejemplo tipo S&P 500 future

quarterly <- quarterly %>%
  mutate(
    pnl_long = n_contracts * contract_multiplier * var_price,
    pnl_short = -pnl_long   # cobertura típica (posición corta)
  )

# =========================================================
## 3. EFECTO SOBRE PORTAFOLIO CUBIERTO
# =========================================================

# Simulación de valor del portafolio con cobertura
quarterly <- quarterly %>%
  mutate(
    portfolio_change = portfolio_value * pct_change,  # efecto mercado
    hedged_portfolio = portfolio_change + pnl_short
  )

# =========================================================
## 4. ROLL-OVER TRIMESTRAL
# =========================================================

# Ganancia o pérdida acumulada por roll-over
quarterly <- quarterly %>%
  mutate(
    cumulative_hedge_pnl = cumsum(pnl_short),
    cumulative_portfolio = cumsum(portfolio_change),
    cumulative_hedged = cumsum(hedged_portfolio)
  )

# =========================================================
## 5. ANÁLISIS DE RESULTADOS
# =========================================================

print(quarterly)
## # A tibble: 16 × 12
##    quarter price_ini price_fin var_price pct_change  pnl_long pnl_short
##    <chr>       <dbl>     <dbl>     <dbl>      <dbl>     <dbl>     <dbl>
##  1 2022-Q1     5000      4863.    -137.    -0.0275   -316008.   316008.
##  2 2022-Q2     5176.     5238.      62.2    0.0120    143158.  -143158.
##  3 2022-Q3     5608.     5444.    -164.    -0.0292   -376075.   376075.
##  4 2022-Q4     5305.     5487.     182.     0.0343    418908.  -418908.
##  5 2023-Q1     5577.     5715.     137.     0.0246    315239.  -315239.
##  6 2023-Q2     5599.     6142.     543.     0.0970   1249119. -1249119.
##  7 2023-Q3     5671.     5743.      71.7    0.0126    164796.  -164796.
##  8 2023-Q4     5509.     5258.    -251.    -0.0455   -576471.   576471.
##  9 2024-Q1     5116.     4671.    -445.    -0.0870  -1023184.  1023184.
## 10 2024-Q2     4837.     4664.    -173.    -0.0357   -397623.   397623.
## 11 2024-Q3     4907.     4951.      44.5    0.00907   102349.  -102349.
## 12 2024-Q4     5139.     5515.     377.     0.0733    866104.  -866104.
## 13 2025-Q1     5678.     5812.     134.     0.0237    309102.  -309102.
## 14 2025-Q2     5753.     5530.    -222.    -0.0387   -511622.   511622.
## 15 2025-Q3     5496.     5692.     197.     0.0358    452850.  -452850.
## 16 2025-Q4     5979.     5641.    -337.    -0.0564   -776046.   776046.
## # ℹ 5 more variables: portfolio_change <dbl>, hedged_portfolio <dbl>,
## #   cumulative_hedge_pnl <dbl>, cumulative_portfolio <dbl>,
## #   cumulative_hedged <dbl>
# Interpretación automática básica
cat("\nINTERPRETACIÓN:\n")
## 
## INTERPRETACIÓN:
cat("1. La posición corta en futuros protege contra caídas del mercado.\n")
## 1. La posición corta en futuros protege contra caídas del mercado.
cat("2. El roll-over genera ajustes periódicos en ganancias/pérdidas.\n")
## 2. El roll-over genera ajustes periódicos en ganancias/pérdidas.
cat("3. Existe riesgo de base si el futuro no replica perfectamente el spot.\n")
## 3. Existe riesgo de base si el futuro no replica perfectamente el spot.
cat("4. Si el mercado sube, la cobertura reduce ganancias del portafolio.\n")
## 4. Si el mercado sube, la cobertura reduce ganancias del portafolio.
cat("5. Si el mercado cae, la cobertura compensa pérdidas.\n")
## 5. Si el mercado cae, la cobertura compensa pérdidas.
# =========================================================
## 6. ESCENARIOS: LARGO VS CORTO
# =========================================================

scenario <- data.frame(
  scenario = c("Long futures", "Short futures"),
  market_up = c("Gana", "Pierde (hedge)"),
  market_down = c("Pierde", "Gana (protección)"),
  use_case = c("Especulación alcista", "Cobertura de portafolio accionario")
)

print(scenario)
##        scenario      market_up       market_down
## 1  Long futures           Gana            Pierde
## 2 Short futures Pierde (hedge) Gana (protección)
##                             use_case
## 1               Especulación alcista
## 2 Cobertura de portafolio accionario
10. ## =========================================================
## [1] 10
## VALOR ESPERADO DE LA COBERTURA TRIMESTRAL (Rf - TNX)
## =========================================================

### Explicación teórica

# La tasa libre de riesgo se aproxima usando el rendimiento del bono del Tesoro de EE.UU.
# En este ejercicio se utiliza el indicador ^TNX (CBOE 10-Year Treasury Yield) como proxy.
#
# Justificación:
# - Representa una tasa libre de riesgo de largo plazo
# - Es ampliamente usada en modelos CAPM y valoración de portafolios
# - Permite descontar flujos y comparar rendimiento ajustado por riesgo
#
# Se calcula el valor esperado del portafolio:
# 1. SIN COBERTURA
# 2. CON COBERTURA (ajustado por futuros)
# 3. AJUSTADO POR TASA LIBRE DE RIESGO (benchmark)

## =========================================================
## 1. TASA LIBRE DE RIESGO (TNX)
## =========================================================

# Puedes ingresar manualmente el valor observado en la fecha inicial
# Ejemplo: TNX = 4.20% anual

rf_annual <- 0.042  # 4.2% ejemplo (AJUSTAR CON TU DATO REAL)

# Conversión a tasa trimestral
rf_quarterly <- (1 + rf_annual)^(1/4) - 1

cat("Tasa libre de riesgo anual:", rf_annual, "\n")
## Tasa libre de riesgo anual: 0.042
cat("Tasa libre de riesgo trimestral:", rf_quarterly, "\n")
## Tasa libre de riesgo trimestral: 0.01033856
## =========================================================
## 2. RETORNO ESPERADO DEL PORTAFOLIO
## =========================================================

# Se asume que ya tienes:
# port_expected_return -> retorno esperado anual del portafolio
# port_value -> 20,000,000 USD

port_value <- 20000000

# conversión a trimestral
port_expected_q <- (1 + port_return)^(1/4) - 1

## =========================================================
## 3. PORTAFOLIO SIN COBERTURA
## =========================================================

expected_value_no_hedge <- port_value * (1 + port_expected_q)

## =========================================================
## 4. PORTAFOLIO CON COBERTURA (FUTUROS)
## =========================================================

# La cobertura reduce riesgo sistemático (beta), pero no elimina el retorno esperado completo

# supongamos beta del portafolio ya calculada:
# beta_portfolio

market_risk_premium_q <- port_expected_q - rf_quarterly

# retorno ajustado por cobertura (simplificado CAPM hedge effect)
expected_return_hedged <- rf_quarterly + beta_portafolio * market_risk_premium_q

expected_value_hedged <- port_value * (1 + expected_return_hedged)

## =========================================================
## 5. COMPARACIÓN DIRECTA
## =========================================================

comparison <- data.frame(
  Scenario = c("Sin cobertura", "Con cobertura"),
  Expected_Return_Quarter = c(port_expected_q, expected_return_hedged),
  Expected_Value_USD = c(expected_value_no_hedge, expected_value_hedged)
)

print(comparison)
##        Scenario Expected_Return_Quarter Expected_Value_USD
## 1 Sin cobertura              0.02818830           20563766
## 2 Con cobertura              0.02056201           20411240
## =========================================================
## 6. INTERPRETACIÓN FINANCIERA
## =========================================================

cat("\nINTERPRETACIÓN:\n")
## 
## INTERPRETACIÓN:
cat("1. La tasa libre de riesgo (^TNX) representa el retorno mínimo sin riesgo.\n")
## 1. La tasa libre de riesgo (^TNX) representa el retorno mínimo sin riesgo.
cat("2. El portafolio sin cobertura mantiene mayor exposición al riesgo de mercado.\n")
## 2. El portafolio sin cobertura mantiene mayor exposición al riesgo de mercado.
cat("3. La cobertura reduce la sensibilidad (beta) frente al índice.\n")
## 3. La cobertura reduce la sensibilidad (beta) frente al índice.
cat("4. Esto generalmente reduce tanto el riesgo como el retorno esperado.\n")
## 4. Esto generalmente reduce tanto el riesgo como el retorno esperado.
cat("5. La cobertura no elimina el riesgo total, solo el riesgo sistemático.\n")
## 5. La cobertura no elimina el riesgo total, solo el riesgo sistemático.
cat("\nCONCLUSIÓN:\n")
## 
## CONCLUSIÓN:
cat("- La cobertura reduce volatilidad (riesgo)\n")
## - La cobertura reduce volatilidad (riesgo)
cat("- También reduce el retorno esperado\n")
## - También reduce el retorno esperado
cat("- Es un intercambio riesgo-retorno típico de estrategias de hedge\n")
## - Es un intercambio riesgo-retorno típico de estrategias de hedge
11. ## =========================================================
## [1] 11
## RENDIMIENTO ESPERADO MENSUAL Y VALOR DE LA CARTERA
## (SIN COBERTURA / CON COBERTURA / AJUSTADO POR VaR)
## =========================================================

### Explicación teórica

# El rendimiento del portafolio se evalúa bajo tres escenarios:
#
# 1. SIN COBERTURA:
#    - Refleja el retorno total del portafolio accionario
#
# 2. CON COBERTURA (FUTUROS):
#    - Reduce riesgo sistemático (beta)
#    - Reduce variabilidad del retorno esperado
#
# 3. AJUSTADO POR VaR:
#    - Incorpora escenarios extremos de pérdida (cola de distribución)
#
# Además, se considera el efecto de dividendos:
# - Los dividendos aumentan el retorno total de la acción
# - Se suman al rendimiento esperado del portafolio

## =========================================================
## 1. DATOS BASE
## =========================================================

portfolio_value <- 20000000

# Supuestos ya calculados previamente:
# mu_portfolio_annual  -> retorno esperado anual
# beta_portfolio
# rf_annual

rf_monthly <- (1 + rf_annual)^(1/12) - 1
mu_monthly <- (1 + port_return)^(1/12) - 1

## =========================================================
## 2. EFECTO DE DIVIDENDOS
## =========================================================

# Dividend yield promedio estimado (puedes ajustar según PGR, SYK, WM)
# Ejemplo típico S&P 500:

dividend_yield_annual <- 0.015  # 1.5% anual (ajustar si tienes datos reales)
dividend_monthly <- (1 + dividend_yield_annual)^(1/12) - 1

# Retorno total incluyendo dividendos
mu_monthly_total <- mu_monthly + dividend_monthly

## =========================================================
## 3. PORTAFOLIO SIN COBERTURA
## =========================================================

expected_no_hedge_value <- portfolio_value * (1 + mu_monthly_total)

## =========================================================
## 4. PORTAFOLIO CON COBERTURA (FUTUROS)
## =========================================================

# La cobertura reduce exposición al riesgo de mercado

market_premium_monthly <- mu_monthly - rf_monthly

mu_hedged_monthly <- rf_monthly + beta_portafolio * market_premium_monthly + dividend_monthly

expected_hedged_value <- portfolio_value * (1 + mu_hedged_monthly)

## =========================================================
## 5. AJUSTE POR ESCENARIOS VaR
## =========================================================

# VaR ya calculado previamente:
# VaR_95, VaR_99 en porcentaje mensual

# Escenario conservador: ajuste por pérdida esperada (aprox)
var_adjustment <- VaR_95_pct # usar el VaR 95% como escenario base

mu_var_adjusted <- mu_monthly_total - abs(var_adjustment)

expected_var_value <- portfolio_value * (1 + mu_var_adjusted)

## =========================================================
## 6. COMPARACIÓN FINAL
## =========================================================

comparison <- data.frame(
  Scenario = c("Sin cobertura", "Con cobertura", "Ajustado por VaR"),
  Monthly_Return = c(mu_monthly_total, mu_hedged_monthly, mu_var_adjusted),
  Expected_Value_USD = c(expected_no_hedge_value,
                         expected_hedged_value,
                         expected_var_value)
)

print(comparison)
##           Scenario Monthly_Return Expected_Value_USD
## 1    Sin cobertura    0.010550658           20211013
## 2    Con cobertura    0.008040656           20160813
## 3 Ajustado por VaR   -0.057433238           18851335
## =========================================================
## 7. INTERPRETACIÓN FINANCIERA
## =========================================================

cat("\nINTERPRETACIÓN:\n")
## 
## INTERPRETACIÓN:
cat("1. SIN COBERTURA:\n")
## 1. SIN COBERTURA:
cat("- Mayor retorno esperado\n")
## - Mayor retorno esperado
cat("- Mayor exposición al riesgo de mercado\n\n")
## - Mayor exposición al riesgo de mercado
cat("2. CON COBERTURA:\n")
## 2. CON COBERTURA:
cat("- Reduce volatilidad del portafolio\n")
## - Reduce volatilidad del portafolio
cat("- Reduce retorno esperado por eliminación parcial del riesgo sistemático\n\n")
## - Reduce retorno esperado por eliminación parcial del riesgo sistemático
cat("3. AJUSTE POR VaR:\n")
## 3. AJUSTE POR VaR:
cat("- Representa escenarios extremos de pérdida\n")
## - Representa escenarios extremos de pérdida
cat("- Útil para análisis de riesgo en crisis de mercado\n\n")
## - Útil para análisis de riesgo en crisis de mercado
cat("4. EFECTO DE DIVIDENDOS:\n")
## 4. EFECTO DE DIVIDENDOS:
cat("- Aumentan el retorno total del portafolio\n")
## - Aumentan el retorno total del portafolio
cat("- Funcionan como flujo adicional de ingresos\n")
## - Funcionan como flujo adicional de ingresos
cat("- Reducen el impacto negativo de la volatilidad del precio\n\n")
## - Reducen el impacto negativo de la volatilidad del precio
cat("CONCLUSIÓN:\n")
## CONCLUSIÓN:
cat("- El portafolio sin cobertura maximiza retorno esperado\n")
## - El portafolio sin cobertura maximiza retorno esperado
cat("- El portafolio cubierto estabiliza resultados\n")
## - El portafolio cubierto estabiliza resultados
cat("- El VaR muestra el riesgo extremo potencial\n")
## - El VaR muestra el riesgo extremo potencial
12. ## =========================================================
## [1] 12
## ANÁLISIS DE COBERTURA SEGÚN DIFERENTES BETAS (0.5 y 2)
## =========================================================

### Explicación teórica

# La beta mide la sensibilidad del portafolio frente al mercado.
#
# - Beta < 1  → menor riesgo sistemático que el mercado
# - Beta = 1  → igual al mercado
# - Beta > 1  → mayor sensibilidad al mercado
#
# En cobertura con futuros:
# Hedge Ratio = Beta del portafolio
#
# Número de contratos:
# N = (Beta * Valor Portafolio) / (Valor contrato futuro)

## =========================================================
## 1. PARÁMETROS BASE
## =========================================================

portfolio_value <- 20000000

# Valor del contrato de futuros (ajustar según S&P 500 futuro real)
contract_multiplier <- 50

# Precio del índice o futuro (ejemplo)
futures_price <- 5000

contract_value <- contract_multiplier * futures_price

cat("Valor contrato futuro:", contract_value, "\n")
## Valor contrato futuro: 250000
## =========================================================
## 2. FUNCIÓN DE CÁLCULO DE CONTRATOS
## =========================================================

calc_contracts <- function(beta, portfolio_value, contract_value) {
  n_contracts <- (beta * portfolio_value) / contract_value
  return(n_contracts)
}

## =========================================================
## 3. ESCENARIO 1: BETA = 0.5
## =========================================================

beta_1 <- 0.5

n_contracts_1 <- calc_contracts(beta_1, portfolio_value, contract_value)

systematic_exposure_1 <- beta_1 * portfolio_value

cat("\n=== ESCENARIO BETA = 0.5 ===\n")
## 
## === ESCENARIO BETA = 0.5 ===
cat("Número de contratos:", n_contracts_1, "\n")
## Número de contratos: 40
cat("Exposición sistemática:", systematic_exposure_1, "\n")
## Exposición sistemática: 1e+07
# Interpretación sensibilidad
cat("Sensibilidad: baja exposición al mercado\n")
## Sensibilidad: baja exposición al mercado
## =========================================================
## 4. ESCENARIO 2: BETA = 2
## =========================================================

beta_2 <- 2

n_contracts_2 <- calc_contracts(beta_2, portfolio_value, contract_value)

systematic_exposure_2 <- beta_2 * portfolio_value

cat("\n=== ESCENARIO BETA = 2 ===\n")
## 
## === ESCENARIO BETA = 2 ===
cat("Número de contratos:", n_contracts_2, "\n")
## Número de contratos: 160
cat("Exposición sistemática:", systematic_exposure_2, "\n")
## Exposición sistemática: 4e+07
cat("Sensibilidad: alta exposición al mercado\n")
## Sensibilidad: alta exposición al mercado
## =========================================================
## 5. COMPARACIÓN DE COBERTURA
## =========================================================

comparison <- data.frame(
  Beta = c(0.5, 2),
  Contracts = c(n_contracts_1, n_contracts_2),
  Systematic_Exposure = c(systematic_exposure_1, systematic_exposure_2),
  Interpretation = c(
    "Cobertura ligera (baja sensibilidad)",
    "Cobertura intensa (alta sensibilidad)"
  )
)

print(comparison)
##   Beta Contracts Systematic_Exposure                        Interpretation
## 1  0.5        40               1e+07  Cobertura ligera (baja sensibilidad)
## 2  2.0       160               4e+07 Cobertura intensa (alta sensibilidad)
## =========================================================
## 6. INTERPRETACIÓN FINANCIERA
## =========================================================

cat("\nINTERPRETACIÓN:\n")
## 
## INTERPRETACIÓN:
cat("1. BETA = 0.5:\n")
## 1. BETA = 0.5:
cat("- El portafolio es defensivo\n")
## - El portafolio es defensivo
cat("- Requiere pocos contratos de futuros\n")
## - Requiere pocos contratos de futuros
cat("- Menor exposición al riesgo sistemático\n\n")
## - Menor exposición al riesgo sistemático
cat("2. BETA = 2:\n")
## 2. BETA = 2:
cat("- El portafolio es agresivo\n")
## - El portafolio es agresivo
cat("- Requiere el doble de cobertura aproximadamente\n")
## - Requiere el doble de cobertura aproximadamente
cat("- Alta sensibilidad a movimientos del índice\n\n")
## - Alta sensibilidad a movimientos del índice
cat("3. CONCLUSIÓN GENERAL:\n")
## 3. CONCLUSIÓN GENERAL:
cat("- A mayor beta, mayor exposición al riesgo de mercado\n")
## - A mayor beta, mayor exposición al riesgo de mercado
cat("- Por lo tanto, se necesitan más contratos para cubrirlo\n")
## - Por lo tanto, se necesitan más contratos para cubrirlo
cat("- La cobertura busca neutralizar la exposición sistemática\n")
## - La cobertura busca neutralizar la exposición sistemática
cat("- Un portafolio con beta alta amplifica ganancias y pérdidas\n")
## - Un portafolio con beta alta amplifica ganancias y pérdidas