Retornos financieros

Sea P_t el precio de un activo en el tiempo t. Los retornos logarítmicos se definen como:

r_t = log(P_t / P_{t-1})

Estos retornos permiten modelar variaciones relativas del precio y son aditivos en el tiempo.

Value at Risk

El Value at Risk mide la pérdida máxima esperada para un nivel de confianza dado alpha.

VaR_alpha = cuantil de orden (1 - alpha) de la distribución de los retornos

Interpretación: con probabilidad alpha la pérdida no excede el valor VaR.

Expected Shortfall

El Expected Shortfall mide la pérdida promedio condicionada a que se supere el VaR.

ES_alpha = E[r | r <= VaR_alpha]

Esta medida captura mejor los eventos extremos que el VaR.

Enfoque empírico

Se utilizan los retornos históricos para estimar cuantiles y promedios en la cola de pérdidas.

Código en R

# Librerías
library(quantmod)
## Warning: package 'quantmod' was built under R version 4.4.3
## Cargando paquete requerido: xts
## Cargando paquete requerido: zoo
## 
## Adjuntando el paquete: 'zoo'
## The following objects are masked from 'package:base':
## 
##     as.Date, as.Date.numeric
## Cargando paquete requerido: TTR
## Warning: package 'TTR' was built under R version 4.4.3
## Registered S3 method overwritten by 'quantmod':
##   method            from
##   as.zoo.data.frame zoo
library(ggplot2)
## Warning: package 'ggplot2' was built under R version 4.4.3
# Descargar datos
getSymbols("USDCOP=X", src = "yahoo", from = "2020-01-01")
## Warning: USDCOP=X contains missing values. Some functions will not work if
## objects contain missing values in the middle of the series. Consider using
## na.omit(), na.approx(), na.fill(), etc to remove or replace them.
## [1] "USDCOP=X"
# Extraer precios de cierre
precios <- Cl(`USDCOP=X`)

# Data frame de precios
df_precios <- data.frame(
  fecha = index(precios),
  precio = as.numeric(precios)
)

# Graficar precios (corregido)
ggplot(df_precios, aes(x = fecha, y = precio)) +
  geom_line() +
  ggtitle("Serie de precios")

# Calcular retornos logarítmicos
retornos <- diff(log(precios))
retornos <- na.omit(retornos)

# Data frame de retornos
df_retornos <- data.frame(
  fecha = index(retornos),
  retorno = as.numeric(retornos)
)

# Graficar retornos
ggplot(df_retornos, aes(x = fecha, y = retorno)) +
  geom_line() +
  ggtitle("Retornos logarítmicos")

# Estimar media y varianza
media <- mean(df_retornos$retorno)
varianza <- var(df_retornos$retorno)

media
## [1] 7.708288e-05
varianza
## [1] 9.847159e-05
# Nivel de confianza
alpha <- 0.95

# VaR histórico
VaR <- quantile(df_retornos$retorno, probs = 1 - alpha)

VaR
##          5% 
## -0.01482455
# Histograma con VaR
ggplot(df_retornos, aes(x = retorno)) +
  geom_histogram(bins = 50) +
  geom_vline(xintercept = VaR, linetype = "dashed") +
  ggtitle("Distribución de retornos con VaR")

Retornos de activos

Sea un vector de retornos aleatorios R = (R_1, R_2, …, R_n)^T

El vector de medias es:

mu = E[R]

y la matriz de covarianzas es:

Sigma = Var(R)

Portafolio

Sea w = (w_1, w_2, …, w_n)^T el vector de pesos del portafolio

El retorno del portafolio es:

R_p = w^T R

El retorno esperado es:

E[R_p] = w^T mu

Varianza del portafolio

La varianza del portafolio está dada por:

Var(R_p) = w^T Sigma w

La desviación estándar es:

sigma_p = sqrt(w^T Sigma w)

Problema de optimización

Minimizar la varianza para un nivel de retorno esperado dado:

min w^T Sigma w

sujeto a:

w^T mu = mu_p
w^T 1 = 1

donde 1 es un vector de unos

Solución con multiplicadores de Lagrange

La función Lagrangiana es:

L(w, lambda_1, lambda_2) = w^T Sigma w - lambda_1 (w^T mu - mu_p) - lambda_2 (w^T 1 - 1)

Condición de primer orden:

2 Sigma w - lambda_1 mu - lambda_2 1 = 0

De donde:

w = (1/2) Sigma^{-1} (lambda_1 mu + lambda_2 1)

Frontera eficiente

Definiciones:

A = 1^T Sigma^{-1} 1
B = 1^T Sigma^{-1} mu
C = mu^T Sigma^{-1} mu

La varianza mínima para un retorno dado mu_p es:

sigma_p^2 = (A mu_p^2 - 2 B mu_p + C) / (A C - B^2)

Portafolio de mínima varianza global

w_gmv = Sigma^{-1} 1 / (1^T Sigma^{-1} 1)

Activo libre de riesgo

Sea r_f la tasa libre de riesgo

El portafolio óptimo satisface:

w* proporcional a Sigma^{-1} (mu - r_f 1)

Línea del mercado de capitales

E[R_p] = r_f + ((E[R_m] - r_f) / sigma_m) sigma_p

Activos y retornos

Sea un vector de retornos aleatorios:

\[ R = (R_1, R_2, \dots, R_n)^T \]

El vector de medias es:

\[ \mu = \mathbb{E}[R] \]

La matriz de covarianzas es:

\[ \Sigma = \mathbb{E}[(R - \mu)(R - \mu)^T] \]

Portafolio

Sea el vector de pesos:

\[ w = (w_1, w_2, \dots, w_n)^T \]

El retorno del portafolio es:

\[ R_p = w^T R \]

El retorno esperado:

\[ \mathbb{E}[R_p] = w^T \mu \]

Riesgo del portafolio

La varianza del portafolio es:

\[ \sigma_p^2 = w^T \Sigma w \]

Diversificación

Para dos activos, la varianza es:

\[ \sigma_p^2 = w_1^2 \sigma_1^2 + w_2^2 \sigma_2^2 + 2 w_1 w_2 \text{Cov}(R_1, R_2) \]

En términos de correlación:

\[ \sigma_p^2 = w_1^2 \sigma_1^2 + w_2^2 \sigma_2^2 + 2 w_1 w_2 \rho_{12} \sigma_1 \sigma_2 \]

La diversificación reduce el riesgo cuando:

\[ \rho_{12} < 1 \]

Problema de optimización

Minimizar el riesgo dado un retorno objetivo:

\[ \min_w \; w^T \Sigma w \]

sujeto a:

\[ w^T \mu = \mu_p \]

\[ w^T \mathbf{1} = 1 \]

Solución

Condición de primer orden:

\[ 2 \Sigma w - \lambda_1 \mu - \lambda_2 \mathbf{1} = 0 \]

Solución general:

\[ w = \frac{1}{2} \Sigma^{-1} (\lambda_1 \mu + \lambda_2 \mathbf{1}) \]

Frontera eficiente

Definiciones:

\[ A = \mathbf{1}^T \Sigma^{-1} \mathbf{1} \]

\[ B = \mathbf{1}^T \Sigma^{-1} \mu \]

\[ C = \mu^T \Sigma^{-1} \mu \]

Varianza mínima para retorno dado:

\[ \sigma_p^2 = \frac{A \mu_p^2 - 2 B \mu_p + C}{A C - B^2} \]

Portafolio de mínima varianza

\[ w_{gmv} = \frac{\Sigma^{-1} \mathbf{1}}{\mathbf{1}^T \Sigma^{-1} \mathbf{1}} \]

Activo libre de riesgo

Sea \(r_f\), entonces:

\[ w^* \propto \Sigma^{-1} (\mu - r_f \mathbf{1}) \]

Línea del mercado de capitales

\[ \mathbb{E}[R_p] = r_f + \frac{\mathbb{E}[R_m] - r_f}{\sigma_m} \sigma_p \]

# Librerías
library(quantmod)
library(ggplot2)
library(quadprog)

# Descargar datos de varios activos
activos <- c("AAPL", "MSFT", "GOOG", "AMZN")

getSymbols(activos, src = "yahoo", from = "2020-01-01")
## [1] "AAPL" "MSFT" "GOOG" "AMZN"
# Precios de cierre ajustados
precios <- na.omit(merge(Cl(AAPL), Cl(MSFT), Cl(GOOG), Cl(AMZN)))
colnames(precios) <- activos

# Retornos logarítmicos
retornos <- na.omit(diff(log(precios)))

# Media y matriz de covarianza
mu <- colMeans(retornos)
Sigma <- cov(retornos)

# Número de activos
n <- length(mu)

# Función para calcular portafolio eficiente
frontera_eficiente <- function(mu, Sigma, n_port = 100) {
  
  resultados <- data.frame(rend = numeric(), riesgo = numeric())
  
  # Secuencia de retornos objetivo
  target_returns <- seq(min(mu), max(mu), length.out = n_port)
  
  for (r_obj in target_returns) {
    
    Dmat <- 2 * Sigma
    dvec <- rep(0, n)
    
    Amat <- cbind(
      rep(1, n),   # suma de pesos = 1
      mu           # retorno objetivo
    )
    
    bvec <- c(1, r_obj)
    
    sol <- solve.QP(Dmat, dvec, Amat, bvec, meq = 2)
    
    w <- sol$solution
    
    riesgo <- sqrt(t(w) %*% Sigma %*% w)
    
    resultados <- rbind(resultados, c(r_obj, riesgo))
  }
  
  colnames(resultados) <- c("retorno", "riesgo")
  return(resultados)
}

# Calcular frontera eficiente
frontera <- frontera_eficiente(mu, Sigma)

# Graficar frontera eficiente
ggplot(frontera, aes(x = riesgo, y = retorno)) +
  geom_line() +
  ggtitle("Frontera eficiente de Markowitz")

# Portafolio de mínima varianza global
uno <- rep(1, n)

w_gmv <- solve(Sigma) %*% uno / as.numeric(t(uno) %*% solve(Sigma) %*% uno)

w_gmv
##            [,1]
## AAPL 0.28535501
## MSFT 0.37487519
## GOOG 0.24592296
## AMZN 0.09384684
# Riesgo y retorno del GMV
ret_gmv <- sum(w_gmv * mu)
riesgo_gmv <- sqrt(t(w_gmv) %*% Sigma %*% w_gmv)

ret_gmv
## [1] 0.000696512
riesgo_gmv
##            [,1]
## [1,] 0.01713038
# Simulación para ver diversificación
set.seed(123)
n_sim <- 5000

pesos <- matrix(runif(n_sim * n), ncol = n)
pesos <- pesos / rowSums(pesos)

retornos_port <- pesos %*% mu
riesgos_port <- apply(pesos, 1, function(w) sqrt(t(w) %*% Sigma %*% w))

df_sim <- data.frame(
  retorno = retornos_port,
  riesgo = riesgos_port
)

# Graficar nube de portafolios + frontera
ggplot(df_sim, aes(x = riesgo, y = retorno)) +
  geom_point(alpha = 0.3) +
  geom_line(data = frontera, color = "blue") +
  ggtitle("Diversificación de portafolios")

Definición

Un proceso estocástico \(X_t\) es continuo en media cuadrática si:

\[ \mathbb{E}[X_t^2] < \infty \]

y

\[ \lim_{s \to t} \mathbb{E}[(X_s - X_t)^2] = 0, \quad \forall t \geq 0 \]

Movimiento browniano

Para el movimiento browniano \(B_t\):

\[ B_t \sim \mathcal{N}(0,t) \]

por lo tanto:

\[ \mathbb{E}[B_t^2] = t < \infty \]

Sean \(s,t \geq 0\) y supongamos \(s > t\). Entonces:

\[ B_s - B_t \sim \mathcal{N}(0, s - t) \]

y:

\[ \mathbb{E}[(B_s - B_t)^2] = \mathrm{Var}(B_s - B_t) = s - t \]

Tomando límite:

\[ \lim_{s \to t} \mathbb{E}[(B_s - B_t)^2] = \lim_{s \to t} (s - t) = 0 \]

Proceso transformado Lipschitz

Sea \(Y_t = f(B_t)\) con \(f\) Lipschitz, es decir:

\[ |f(x) - f(y)| \leq C |x - y| \]

Entonces:

\[ \mathbb{E}[(Y_s - Y_t)^2] = \mathbb{E}[(f(B_s) - f(B_t))^2] \]

Aplicando la condición Lipschitz:

\[ (f(B_s) - f(B_t))^2 \leq C^2 (B_s - B_t)^2 \]

Por lo tanto:

\[ \mathbb{E}[(Y_s - Y_t)^2] \leq C^2 \mathbb{E}[(B_s - B_t)^2] \]

Como:

\[ \mathbb{E}[(B_s - B_t)^2] = |s - t| \]

se tiene:

\[ \mathbb{E}[(Y_s - Y_t)^2] \leq C^2 |s - t| \]

y:

\[ \lim_{s \to t} \mathbb{E}[(Y_s - Y_t)^2] = 0 \]

Aproximación de la integral de Itô

Sea \(X_t\) continuo en media cuadrática en \([S,T]\).

Sea una partición:

\[ S = t_0 < t_1 < \cdots < t_n = T \]

Definimos la aproximación simple:

\[ \phi_n(t,\omega) = \sum_j X_{t_j}(\omega)\mathbf{1}_{[t_j, t_{j+1})}(t) \]

Por la isometría de Itô:

\[ \mathbb{E}\left[\left(\int_S^T X_t dB_t - \int_S^T \phi_n(t) dB_t \right)^2\right] = \mathbb{E}\left[\int_S^T (X_t - \phi_n(t))^2 dt\right] \]

Aplicando Fubini:

\[ \mathbb{E}\left[\int_S^T (X_t - \phi_n(t))^2 dt\right] = \int_S^T \mathbb{E}[(X_t - \phi_n(t))^2] dt \]

Esto equivale a:

\[ \int_S^T \mathbb{E}[(X_t - X_{t_j})^2] dt \]

Para \(t \in [t_j, t_{j+1})\).

Por continuidad en media cuadrática:

\[ \forall \epsilon > 0, \exists \delta > 0 \text{ tal que } |t - t_j| < \delta \Rightarrow \mathbb{E}[(X_t - X_{t_j})^2] < \epsilon \]

Si:

\[ \max \Delta t_j < \delta \]

entonces:

\[ \int_S^T \mathbb{E}[(X_t - \phi_n(t))^2] dt < \epsilon (T - S) \]

Por lo tanto:

\[ \lim_{n \to \infty} \mathbb{E}\left[\left(\int_S^T X_t dB_t - \int_S^T \phi_n(t) dB_t \right)^2\right] = 0 \]