La Frontera Eficiente de Markowitz

La Frontera Eficiente, desarrollada por Harry Markowitz, constituye una base fundamental de la teoría moderna de carteras. Esta propuesta, que fue presentada en 1952, posibilita el reconocimiento de agrupaciones de activos que maximizan el rendimiento esperado para un grado determinado de riesgo. En este artículo se describen los principios matemáticos del concepto, así como su ejecución en R paso a paso.

Principios matemáticos

Rendimiento Esperado

El rendimiento esperado de una cartera (\(E[R_p]\)) se calcula como la suma ponderada de los rendimientos esperados de los activos individuales:

\[ E[R_p] = \sum_{i=1}^{n} w_i \, E[R_i] \]

Covarianza

La covarianza es una medida de la correlación entre los rendimientos de dos activos. En particular, muestra cómo las ganancias de dos activos fluctúan en conjunto. Cuando dos activos tienen una tendencia a subir y bajar simultáneamente, su covarianza será positiva. Si uno aumenta y el otro disminuye, tendrán una covarianza negativa.

\[ \operatorname{Cov}(X, Y) = \frac{1}{n} \sum_{i=1}^{n} (X_i - \mu_X)(Y_i - \mu_Y) \]

donde:

Varianza de la cartera

La varianza de la cartera (\(\operatorname{Var}(R_p)\)) mide el riesgo total de la cartera y se calcula utilizando las varianzas y covarianzas de los activos:

\[ \operatorname{Var}(R_p) = \sum_{i=1}^{n} \sum_{j=1}^{n} w_i w_j \, \operatorname{Cov}(R_i, R_j) \]

donde:

Tengamos presente que la varianza es el resultado de sumar los cuadrados de cada una de las diferencias entre los rendimientos. En tal caso, la desviación se obtiene al tomar cada retorno, restarle la media y elevarlo al cuadrado para eliminar el signo.

La fórmula anterior también se puede expresar como:

\[ \sigma_p^2 = \sum_{i=1}^{n} \sum_{j=1}^{n} w_i w_j \, \operatorname{Cov}(R_i, R_j) \]

Ejecución en R

A continuación expondremos los pasos para analizar un conjunto de activos en R.

Paso 1: obtener serie histórica

Instalación de bibliotecas y datos diarios.

library(quantmod)
library(ggplot2)
library(plotly)
library(dplyr)

# Tickers
tickers <- c("AAPL", "MSFT", "GOOGL", "AMZN")

# Descargar datos
getSymbols(tickers, from = "2015-01-01", to = "2024-01-01")
## [1] "AAPL"  "MSFT"  "GOOGL" "AMZN"
# Extraer precios ajustados
prices <- merge(Ad(AAPL), Ad(MSFT), Ad(GOOGL), Ad(AMZN))
colnames(prices) <- tickers

# Rendimientos diarios
returns <- na.omit(ROC(prices, type = "discrete"))

Paso 2: Rendimientos anuales y matriz de covarianza

Cálculo de rendimientos esperiados y matriz de covarianza anual de los activos de la cartera

# Rendimientos esperados anualizados
expected_returns <- colMeans(returns) * 252 # días bursatiles

# Matriz de covarianza anualizada
cov_matrix <- cov(returns) * 252  # días bursatiles

# Función de desempeño del portafolio
portfolio_performance <- function(weights, expected_returns, cov_matrix) {
  ret <- sum(weights * expected_returns)
  vol <- sqrt(t(weights) %*% cov_matrix %*% weights)
  return(c(ret, vol))
}

Paso 3: Cálculo de rendimineto y riesgo

Función para calcular el rendimiento y riesgo de una cartera.

# Función de desempeño del portafolio
portfolio_performance <- function(weights, expected_returns, cov_matrix) {
  ret <- sum(weights * expected_returns)
  vol <- sqrt(t(weights) %*% cov_matrix %*% weights)
  return(c(ret, vol))
}

Paso 4: Múltiples portafolio

Este paso construye y examina diversas combinaciones de pesos para los activos, con el propósito de determinar cuáles están situados en la Frontera Eficiente.

# Simulación Monte Carlo
num_portfolios <- 10000
results <- matrix(0, nrow = num_portfolios, ncol = 3)
weights_record <- matrix(0, nrow = num_portfolios, ncol = length(tickers))

for(i in 1:num_portfolios){
  
  weights <- runif(length(tickers))
  weights <- weights / sum(weights)
  
  perf <- portfolio_performance(weights, expected_returns, cov_matrix)
  
  ret <- perf[1]
  vol <- perf[2]
  
  results[i,1] <- ret
  results[i,2] <- vol
  results[i,3] <- ret / vol
  
  weights_record[i,] <- weights
}

Paso 5: Agrupación de los resultados

# DataFrames
results_df <- data.frame(
  Rendimiento = results[,1],
  Volatilidad = results[,2],
  Sharpe = results[,3]
)

weights_df <- as.data.frame(weights_record)
colnames(weights_df) <- tickers

final_df <- cbind(results_df, weights_df)

Paso 6: Identificación de frontera eficiente

Identificamos los portafolios con el mejor ratio de Sharpe y la mínima volatilidad.

# Portafolio con máximo Sharpe
max_sharpe_idx <- which.max(results_df$Sharpe)
max_sharpe_port <- results_df[max_sharpe_idx,]

# Portafolio con mínima volatilidad
min_vol_idx <- which.min(results_df$Volatilidad)
min_vol_port <- results_df[min_vol_idx,]

Paso 7: Gráficamos los resultados

# Gráfica frontera eficiente
grafica <- ggplot(results_df, aes(x = Volatilidad, y = Rendimiento, color = Sharpe)) +
  geom_point(alpha = 0.6) +
  scale_color_viridis_c() +
  geom_point(data = max_sharpe_port, aes(x = Volatilidad, y = Rendimiento),
             color = "red", size = 4) +
  geom_point(data = min_vol_port, aes(x = Volatilidad, y = Rendimiento),
             color = "blue", size = 4) +
  labs(title = "Frontera Eficiente de Markowitz",
       x = "Volatilidad",
       y = "Rendimiento Esperado")
## Pesos del portafolio con mayor Sharpe:
##           AAPL      MSFT       GOOGL      AMZN
## 4699 0.2945025 0.4200802 0.004599782 0.2808175
## 
## Portafolio con mayor Sharpe:
##      Rendimiento Volatilidad   Sharpe
## 4699   0.2887453   0.2599641 1.110712
## 
## Pesos del portafolio de mínima volatilidad:
##           AAPL      MSFT     GOOGL       AMZN
## 3714 0.3067269 0.3076696 0.3084275 0.07717595
## 
## Portafolio de mínima volatilidad:
##      Rendimiento Volatilidad   Sharpe
## 3714   0.2653145   0.2518568 1.053434

Conclusiones

La formulación de la Frontera Eficiente, basada en la teoría de Harry Markowitz, permite comprender la relación fundamental entre riesgo y rendimiento, destacando el papel de la diversificación en la optimización de carteras.

La implementación en R constituye una herramienta eficaz para operacionalizar el modelo matemático, facilitando su comprensión mediante la simulación y visualización de portafolios eficientes, aun cuando los datos utilizados tengan un carácter ilustrativo.

Los resultados obtenidos, de naturaleza demostrativa, confirman el comportamiento teórico esperado del modelo, evidenciando el intercambio entre riesgo y retorno y la relevancia de la correlación entre activos.

En términos aplicados, el modelo proporciona un marco conceptual sólido para el análisis de inversiones; no obstante, su validez depende de supuestos que pueden no cumplirse plenamente en contextos reales.