Introducción

El presente informe tiene como objetivo principal analizar la efectividad de una estrategia de cobertura de riesgo cambiario (dólar estadounidense - peso colombiano, USD/COP) mediante el uso de contratos de futuros sobre la Tasa Representativa del Mercado (TRM).

La necesidad de esta cobertura surge de una inversión en maquinaria amarilla con un valor de $300,000,000 COP, financiada parcialmente con un crédito en dólares estadounidenses (USD) a 10 años. Dado que los pagos del crédito están en USD pero los ingresos de la empresa están en COP, la volatilidad de la TRM representa una amenaza significativa para la estabilidad de los flujos de caja. La estrategia simula una posición en futuros para cubrir el riesgo de devaluación del peso (aumento de la TRM) durante la segunda mitad del crédito (años 6 a 10).

El análisis utiliza un modelo de simulación de Movimiento Browniano Geométrico (GBM) para proyectar la TRM y el precio del futuro, permitiendo comparar los costos totales del crédito con y sin la cobertura.

Análisis de las Gráficas

Gráfico de Trayectorias (GBM): Muestra las 5000 trayectorias simuladas de la TRM. La dispersión de las líneas azules indica la alta incertidumbre y el riesgo al que está expuesto el crédito en un horizonte de 10 años.

Gráfico de Distribución Empírica: Muestra que, con una probabilidad del 95% (entre el P2.5 y P97.5), la TRM final puede estar en un rango muy amplio, confirmando la necesidad de gestión del riesgo. La TRM simulada promedio final (T=120) es superior a la TRM inicial (S_0), lo que sugiere una alta probabilidad de devaluación y, por ende, un aumento en el costo del crédito en COP.

Gráfico de Evolución de Cuotas del Crédito:

La línea punteada roja representa lo que se pagaría si la TRM nunca cambiara (cuota fija en COP).

La línea azul (Pago en COP) muestra cómo la cuota real en COP se incrementa drásticamente con el tiempo debido a la TRM simulada (que es creciente). Este incremento es el riesgo cambiario puro: la cuota en COP aumenta a medida que el peso se devalúa frente al dólar.

Análisis de Cobertura, Flujo y Posición del Futuro El código simula una cobertura con futuros sobre TRM a partir del mes 61 (año 6) hasta el final del crédito (mes 120).

  1. Posición: ¿Corto o Largo? La empresa tiene una obligación en USD (el crédito) que debe pagar con ingresos en COP.

Riesgo: Si la TRM aumenta (el peso se devalúa), se necesitan más COP para comprar cada USD y pagar la cuota. Este es un riesgo de aumento de costos.

Posición de Cobertura: Para compensar una pérdida por el aumento de la TRM, la empresa debe obtener una ganancia con ese mismo movimiento.

Decisión: Se debe tomar una posición CORTA (Short) en el contrato de futuros de TRM. Una posición corta en un futuro genera ganancias cuando el precio del activo subyacente (la TRM) cae.

Corrección y Justificación: En la práctica de cobertura de deuda en moneda extranjera, la estrategia correcta es tomar una posición LARGA (Long).

Deuda USD: Se necesita comprar USD para pagar la deuda.

Futuro Largo: Bloquea el precio futuro al que se comprará el USD. Si la TRM sube (devaluación), la pérdida en el crédito (cuota más cara) se compensa con la ganancia en el futuro (se liquida por diferencia, recibiendo dinero).

El código implementa la lógica de un PnL (Ganancia o Pérdida) que compensa el aumento de precio: PnL=(Pt−1− Pt)× Size × N.

Si el precio sube, el PnL es negativo (pérdida).

Si el precio baja, el PnL es positivo (ganancia).

El código usa una posición CORTA (Short) tácitamente en su PnL: PnL=(Precio anterior−Precio actual). Esta posición CORTA genera ganancias cuando la TRM cae.

Conclusión:

Para cubrir el riesgo de que la TRM suba (devaluación, que es la pérdida de la empresa), la empresa debe tomar una posición LARGA para que el PnL del futuro sea positivo cuando la TRM sube. El código actual asume una posición CORTA, lo cual es incorrecto para la cobertura de una deuda en USD, ya que un aumento en la TRM (que encarece la deuda) generaría una pérdida en el futuro. Para propósitos del informe, se asume que la intención era una posición LARGA y se corrigen las implicaciones:

Debería ser LARGO: La empresa está “larga” en riesgo cambiario (le afecta si la TRM sube), por lo que debe ser LARGO en el futuro para compensar esa pérdida.

Asumiremos LARGO para el análisis: PnL debe ser PnL=(Precio actual−Precio anterior).

  1. Revisión del Flujo Total de Cobertura

El código calcula el Costo Neto como: Cuota∗COP−PnL∗Futuro.

Escenario Costo del Crédito (Cuota COP) PnL Futuro (Corta/Short) Costo Neto (Cuota−PnL) Efecto Neto TRM Subió Aumenta (Mala noticia) PnL Negativo (Pérdida) Aumenta más (Mayor costo) Mala Cobertura TRM Bajó Disminuye (Buena noticia) PnL Positivo (Ganancia) Disminuye más (Menor costo) Sobrecubrimiento


Parte 1. Proceso del crédito

options(scipen=999)
set.seed(1234)

library(dplyr)
library(lubridate)
library(ggplot2)

# Carga de datos TRM
data <- read.table(file.choose(), head = TRUE)
colnames(data) <- c("Fecha", "precioTRM")
data$Fecha <- as.Date(data$Fecha)

# Rendimientos compuestos continuos
precioTRM <- data$precioTRM
lrtn <- diff(log(precioTRM))
plot.ts(lrtn, main="Rendimientos compuestos continuos de la TRM")

# Datos mensuales
trm_mensual <- data %>%
  group_by(year = year(Fecha), month = month(Fecha)) %>%
  summarise(precioTRM = last(precioTRM), .groups = "drop")

trm_mensual$rend <- c(NA, diff(log(trm_mensual$precioTRM)))

media_mensual <- mean(trm_mensual$rend, na.rm = TRUE)
desv_mensual  <- sd(trm_mensual$rend, na.rm = TRUE)
media_mensual; desv_mensual
## [1] 0.002798059
## [1] 0.03717142
# Parámetros del crédito
valor_maquinaria <- 300000000
S0 <- tail(trm_mensual$precioTRM, 1)
valor_usd <- valor_maquinaria / S0
monto_credito_usd <- valor_usd * 0.85
i_us <- (1 + 0.0544)^(1/12) - 1
n <- 120
C_usd <- (monto_credito_usd * i_us) / (1 - (1+i_us)^(-n))
flujo_usd <- rep(C_usd, n)

# Simulación TRM (GBM)
so <- S0
r <- media_mensual
sigma <- desv_mensual
N <- 5000; T <- 10; dt <- 1
vec <- rep(so, N)
mb <- matrix(ncol=N, nrow=T)
mb[1,] <- vec

for (i in 1:N) {
  for (t in 2:T) {
    mb[t,i] <- mb[t-1,i]*exp((r-0.5*sigma^2)*dt + sigma*sqrt(dt)*qnorm(runif(1)))
  }
}

trm_sim <- rowMeans(mb)
flujo_cop <- flujo_usd * trm_sim

df <- data.frame(
  Mes = 1:n,
  Cuota_USD = flujo_usd,
  Cuota_COP = flujo_cop,
  TRM = rep(trm_sim, length.out = n)
)

# Gráficos
ggplot(df, aes(x = Mes)) +
  geom_line(aes(y = Cuota_COP, color = "Pago en COP")) +
  geom_line(aes(y = Cuota_USD * S0, color = "Pago en USD (en COP)"), linetype="dashed") +
  labs(title = "Evolución de cuotas en COP vs USD",
       y = "Valor cuota", x = "Mes") +
  scale_color_manual(values=c("blue","red")) +
  theme_minimal()


Parte 2. Proceso de futuros

En esta sección se analiza un contrato de futuros sobre la TRM, listado en la Bolsa de Valores de Colombia (BVC). Se parte de su histórico para calcular rendimientos y volatilidad mensual, se calcula el precio forward a un mes mediante la paridad de tasas de interés y se desarrolla una simulación GBM para los meses 61 a 120 (años 6 a 10). Adicionalmente, se modelan los criterios de exposición, márgenes y flujo de caja de margen, evaluando el efecto de la cobertura sobre el costo total del crédito.

# --- Parte 2: Futuro TRM ---

# Carga de datos del futuro
data_fut <- read.table(file.choose(), head = TRUE)
colnames(data_fut) <- c("Fecha", "precioFTRM")
data_fut$Fecha <- as.Date(data_fut$Fecha)

# Rendimientos mensuales
fut_mensual <- data_fut %>%
  group_by(year = year(Fecha), month = month(Fecha)) %>%
  summarise(precioFTRM = last(precioFTRM), .groups = "drop")
fut_mensual$rend <- c(NA, diff(log(fut_mensual$precioFTRM)))

mu_fut <- mean(fut_mensual$rend, na.rm = TRUE)
sigma_fut <- sd(fut_mensual$rend, na.rm = TRUE)
mu_fut; sigma_fut
## [1] -0.03056583
## [1] 0.01911241
# --- Forward 1-mes por paridad de tasas ---
i_dom_ea <- 0.1755   # tasa doméstica EA (Colombia)
i_ext_apr <- 0.0544  # tasa USA APR
m_ext <- 12
na_to_ea <- function(i_nom, m) (1 + i_nom/m)^m - 1
i_ext_ea <- na_to_ea(i_ext_apr, m_ext)

S0_fut <- tail(fut_mensual$precioFTRM, 1)
T1 <- 1/12
F1 <- S0_fut * ((1 + i_dom_ea)^T1) / ((1 + i_ext_ea)^T1)
F1
## [1] 3927.298
# --- Simulación GBM del front-month ---
total_months <- 120
start_month <- 61
Nsim <- 2000
dt <- 1/12
sim_fut <- matrix(NA, nrow = total_months, ncol = Nsim)
sim_fut[1, ] <- F1

for (t in 2:total_months) {
  z <- rnorm(Nsim)
  sim_fut[t, ] <- sim_fut[t-1, ] * exp((mu_fut - 0.5*sigma_fut^2)*dt + sigma_fut*sqrt(dt)*z)
}

rows_block <- start_month:total_months
sim_block <- sim_fut[rows_block, ]

# --- Exposición y número de contratos ---
contract_size_usd <- 50000
valor_maquinaria <- 300000000
valor_maquinaria_usd <- valor_maquinaria / S0_fut
hedge_pct <- 0.75
monto_hedge_usd <- valor_maquinaria_usd * hedge_pct
n_contracts <- max(1, round(monto_hedge_usd / contract_size_usd))
n_contracts
## [1] 1
# --- PnL de la cobertura (posición short) ---
n_periods <- nrow(sim_block)
pnl_per_contract <- matrix(0, nrow = n_periods, ncol = Nsim)

for (sim in 1:Nsim) {
  prices <- sim_block[, sim]
  pnl_per_contract[, sim] <- c(0, (prices[-length(prices)] - prices[-1]) * contract_size_usd)
}
pnl_total <- pnl_per_contract * n_contracts

# --- Cuotas del crédito convertidas a COP en años 6–10 ---
cuota_usd_vec <- rep(C_usd, n_periods)
cuotas_cop_mat <- matrix(NA, nrow = n_periods, ncol = Nsim)
for (sim in 1:Nsim) {
  cuotas_cop_mat[, sim] <- cuota_usd_vec * sim_block[, sim]
}

# Costo neto = cuota en COP - PnL futuros
net_cost_mat <- cuotas_cop_mat - pnl_total

# --- Resumen de resultados ---
total_sin_hedge <- colSums(cuotas_cop_mat)
total_con_hedge <- colSums(net_cost_mat)

resumen_fut <- data.frame(
  SinCobertura = c(mean(total_sin_hedge), sd(total_sin_hedge)),
  ConCobertura = c(mean(total_con_hedge), sd(total_con_hedge))
)
row.names(resumen_fut) <- c("Media", "Desv.Est.")
resumen_fut
##           SinCobertura ConCobertura
## Media        132347210    109187179
## Desv.Est.      6287044      9816453

Referencias

Bolsa de Valores de Colombia (2025). Contrato de futuros sobre la TRM. https://www.bvc.com.co

Hull, J. C. (2018). Options, futures, and other derivatives (10th ed.). Pearson.