title: “Práctica de Futuros – Crédito USD, TRM y Cobertura con Futuros (BVC)” author: “JAIME DE JESÚS ZAPATA, LUZ ELENA CASTRILLON Y MARIA ESTEFANIA OSORNO” date: ” 21 de Septiembre 2025 ” output: html_document: toc: true number_sections: true theme: cosmo
suppressPackageStartupMessages({
library(quantmod); library(zoo); library(dplyr); library(ggplot2);
library(httr); library(jsonlite); library(knitr); library(scales); library(readr)
})
# Descarga de TRM: Yahoo (fallback a Datos Abiertos BanRep)
ok <- TRUE
tryCatch({
getSymbols("USDCOP=X", src = "yahoo", from = "2022-08-01", to = Sys.Date(), auto.assign = TRUE)
}, error = function(e) ok <<- FALSE)
## [1] "USDCOP=X"
if (ok) {
trm_daily <- Cl(`USDCOP=X`)
colnames(trm_daily) <- "TRM"
df_trm <- data.frame(date = index(trm_daily), TRM = as.numeric(trm_daily))
} else {
api_url <- "https://www.datos.gov.co/resource/mcec-87by.json?$limit=500000"
out <- jsonlite::fromJSON(httr::content(httr::GET(api_url), "text", encoding="UTF-8"))
df_trm <- out |>
mutate(date = as.Date(vigenciadesde), TRM = as.numeric(valor)) |>
arrange(date) |> filter(!is.na(date), !is.na(TRM))
trm_daily <- xts::xts(df_trm$TRM, order.by = df_trm$date); colnames(trm_daily) <- "TRM"
}
# Gráfico histórico
ggplot(df_trm, aes(date, TRM)) +
geom_line(color="steelblue", linewidth=0.9) +
labs(title="Histórico TRM (USD/COP)", x="Fecha", y="COP por USD") +
theme_minimal(base_size=13) +
theme(plot.title=element_text(face="bold", hjust=0.5))
En el analisis del gráfico histórico de la TRM desde 2022 se evidencia que el dólar ha sido muy variable. vemos un pico muy alto en 2022-2023, llegando por encima de los $4.800 y posterios a este valor vemos que a ido fluctuado, y en los últimos meses ha bajado un poco y se mantiene en un rango más estable.
Factores internacionales que inciden en la TRM
La relación entre la política monetaria de Estados Unidos y la Tasa Representativa del Mercado (TRM) se basa en cómo las decisiones de la Reserva Federal (Fed) sobre las tasas de interés y la política monetaria influyen directamente en el valor del dólar frente a otras monedas, impactando así la TRM.
La desaceleración económica global en 2025 se caracteriza por un crecimiento mundial muy lento, con un ritmo proyectado alrededor del 2.3%, el más bajo desde 2008 y cercano a la década de menor crecimiento desde los años 70. Esta desaceleración no implica propiamente una recesión global, pero sí un enfriamiento marcado en la mayoría de las economías, incluido un menor crecimiento en potencias como Estados Unidos, China y la Eurozona. Las causas principales apuntan al agotamiento del ciclo globalizador neoliberal, tensiones comerciales, aranceles crecientes y una mayor incertidumbre económica mundial.
El precio del petróleo influye directamente en los ingresos de dólares para Colombia, ya que el petróleo representa alrededor del 25-30% de las exportaciones del país y es una fuente crucial de divisas. Cuando el precio del petróleo cae, disminuyen los ingresos fiscales provenientes de regalías y exportaciones petroleras, lo que afecta negativamente la balanza de pagos y genera un deterioro fiscal. Además, la depreciación del peso colombiano frente al dólar suele aumentar, ya que se reducen las entradas de dólares por exportaciones petroleras.
Factores internos en Colombia
Tasas del Banco de la República: Actualmente en 9,25%. Si las bajan demasiado rápido, el peso podría perder atractivo frente a inversionistas extranjeros, presionando la TRM al alza.
Política monetaria: Las decisiones del Banco de la República sobre la tasa de interés impactan la oferta y demanda de pesos frente al dólar. Una política monetaria restrictiva tiende a fortalecer el peso; una expansiva puede depreciarlo.
Inflación interna: La inflación afecta el poder adquisitivo y puede causar presiones cambiarias. La inflación alta o creciente suele presionar el tipo de cambio al alza porque reduce el valor real del peso.
Demanda y oferta de dólares en el mercado: El ingreso de divisas por exportaciones, remesas y flujos de inversión extranjera aumenta la oferta de dólares, mientras que las importaciones, pago de deuda y salida de capitales generan demanda de dólares.
Condición fiscal y deuda pública: Un déficit fiscal elevado puede ser fuente de incertidumbre, afectando la confianza en la moneda nacional y su valor frente al dólar.
Expectativas y confianza económica: Percepciones sobre estabilidad política, fiscal y económica influyen en la demanda de moneda local o extranjera.
Coyuntura sectorial: Por ejemplo, la producción y exportación petrolera, que al ser una fuente importante de dólares para Colombia, su afectación impacta la TRM.
# Mensualización por último dato del mes
df_m <- df_trm |>
mutate(ym = as.yearmon(date)) |>
group_by(ym) |>
summarise(TRM = dplyr::last(TRM), .groups="drop")
trm_z <- zoo(df_m$TRM, order.by = df_m$ym)
r_log_m <- diff(log(trm_z)) # retornos log mensuales
mean_m <- mean(na.omit(r_log_m))
sigma_m <- sd(na.omit(r_log_m))
# Anualización “estilo Excel” (para reporte)
mu_RCC_anual <- exp(mean_m*12) - 1
sigma_RCC_anual <- sqrt(sigma_m^2*12)
kable(data.frame(
`Media mensual (log)` = round(mean_m, 6),
`Desv. Est. mensual (log)` = round(sigma_m, 6),
`μ_RCC anual (×12)` = percent(mu_RCC_anual),
`σ_RCC anual (×12)` = percent(sigma_RCC_anual)
), caption = "Retornos log mensuales y anualización (×12)")
| Media.mensual..log. | Desv..Est..mensual..log. | μ_RCC.anual…12. | σ_RCC.anual…12. |
|---|---|---|---|
| -0.00253 | 0.034397 | -3% | 12% |
# Gráfico de retornos
ret_m_df <- data.frame(
Fecha = as.Date(as.yearmon(time(r_log_m))),
Retorno = as.numeric(r_log_m)
)
ggplot(ret_m_df, aes(Fecha, Retorno*100)) +
geom_col(fill="steelblue") +
geom_hline(yintercept=0, color="red", linetype="dashed") +
labs(title="Retornos log mensuales de la TRM", x="Fecha", y="Retorno mensual (%)") +
theme_minimal(base_size=13) +
theme(plot.title=element_text(face="bold", hjust=0.5))
## conclucion
La TRM presenta un comportamiento de alta volatilidad mensual, donde predominan variaciones bruscas en ambos sentidos.
Esto implica que los agentes económicos expuestos al riesgo cambiario (importadores, exportadores, deudores en dólares) deben implementar estrategias de cobertura como futuros o forwards para mitigar el riesgo.
S0 <- as.numeric(tail(trm_z, 1))
mu_gbm_m <- mean_m + 0.5*sigma_m^2 # drift mensual ajustado (recomendación del profesor)
sigma_gbm <- sigma_m
T_horiz <- 120 # 12 = 1 año; 120 = 10 años (útil para Parte 2)
N <- 5000
mb <- matrix(NA_real_, nrow=T_horiz, ncol=N) # TRM simulada
mb[1, ] <- S0
for (i in 1:N) for (t in 2:T_horiz) {
Z <- rnorm(1)
mb[t,i] <- mb[t-1,i] * exp((mu_gbm_m - 0.5*sigma_gbm^2) + sigma_gbm*Z)
}
# Curvas y densidad final
matplot(mb, type="l", lty=1,
main=sprintf("TRM simulada (GBM) — %d meses", T_horiz),
xlab="Mes", ylab="COP por USD")
lines(rowMeans(mb), col="yellow", lwd=2)
plot(density(mb[T_horiz,]), main=sprintf("Distribución TRM al mes %d", T_horiz),
xlab="TRM simulada", lwd=2)
abline(v=quantile(mb[T_horiz,], c(.025,.975)), col=c("green","blue"), lwd=2)
- Cada línea representa una posible trayectoria de la TRM en el futuro,
considerando la media de retornos históricos (μ) y la volatilidad
(σ).
monto_cop <- 500e6
trm_spot <- S0
precio_usd <- monto_cop / trm_spot
pago_inicial <- 0.10
# Tasa extranjera (ejemplo; ajustar a banco elegido)
tasa_ea_usd <- 0.0882
i_m <- (1 + tasa_ea_usd)^(1/12) - 1
n_periodos <- 10*12
loan_usd <- precio_usd * (1 - pago_inicial)
pago_mensual_usd <- loan_usd * i_m / (1 - (1 + i_m)^(-n_periodos))
amort <- data.frame(
periodo = 1:n_periodos,
saldo = NA_real_,
interes = NA_real_,
principal = NA_real_,
pago = pago_mensual_usd
)
saldo <- loan_usd
for (t in 1:n_periodos) {
int_t <- saldo * i_m
abo_t <- pago_mensual_usd - int_t
saldo <- max(saldo - abo_t, 0)
amort[t, c("saldo","interes","principal")] <- c(saldo, int_t, abo_t)
}
kable(head(amort, 10), digits=2, caption="Amortización (USD) — primeros 10 pagos")
| periodo | saldo | interes | principal | pago |
|---|---|---|---|---|
| 1 | 114991.9 | 817.18 | 615.09 | 1432.27 |
| 2 | 114372.4 | 812.83 | 619.44 | 1432.27 |
| 3 | 113748.6 | 808.45 | 623.81 | 1432.27 |
| 4 | 113120.4 | 804.04 | 628.22 | 1432.27 |
| 5 | 112487.7 | 799.60 | 632.66 | 1432.27 |
| 6 | 111850.6 | 795.13 | 637.14 | 1432.27 |
| 7 | 111208.9 | 790.63 | 641.64 | 1432.27 |
| 8 | 110562.8 | 786.09 | 646.18 | 1432.27 |
| 9 | 109912.0 | 781.53 | 650.74 | 1432.27 |
| 10 | 109256.7 | 776.93 | 655.34 | 1432.27 |
kable(data.frame(
`Monto financiado (USD)` = round(loan_usd, 2),
`Pago mensual (USD)` = round(pago_mensual_usd, 2),
`Total pagado (USD)` = round(sum(amort$pago), 2),
`Intereses (USD)` = round(sum(amort$interes), 2)
), caption="Resumen del crédito en USD")
| Monto.financiado..USD. | Pago.mensual..USD. | Total.pagado..USD. | Intereses..USD. |
|---|---|---|---|
| 115606.9 | 1432.27 | 171872.2 | 56265.29 |
# Regla: interés en COP con TRM_{t-1}; abono/cuota/saldo con TRM_t
totales_cop <- numeric(N)
if (nrow(mb) >= nrow(amort)) {
# Convertimos TODO el crédito (120 meses)
for (i in 1:N) {
TRM_t <- mb[1:n_periodos, i]
TRM_tm1 <- c(S0, TRM_t[-length(TRM_t)])
interes_COP <- amort$interes * TRM_tm1
abono_COP <- amort$principal * TRM_t
cuota_COP <- interes_COP + abono_COP
totales_cop[i] <- sum(cuota_COP, na.rm = TRUE)
}
titulo_hist <- "Distribución del total pagado en COP (120 meses)"
} else {
# Si solo simulaste 12 meses, convertimos primer año
k <- nrow(mb)
for (i in 1:N) {
TRM_t <- mb[, i]
TRM_tm1 <- c(S0, TRM_t[-length(TRM_t)])
interes_COP <- amort$interes[1:k] * TRM_tm1
abono_COP <- amort$principal[1:k] * TRM_t
cuota_COP <- interes_COP + abono_COP
totales_cop[i] <- sum(cuota_COP, na.rm = TRUE)
}
titulo_hist <- "Distribución del total pagado en COP (primer año)"
}
resumen_cop <- data.frame(
Escenario = c("Pesimista (p95)", "Promedio", "Optimista (p5)"),
TotalPagadoCOP = c(quantile(totales_cop, 0.95),
mean(totales_cop),
quantile(totales_cop, 0.05))
)
kable(resumen_cop, digits=0, caption="Total pagado en COP — regla TRM_{t-1}/TRM_t")
| Escenario | TotalPagadoCOP | |
|---|---|---|
| 95% | Pesimista (p95) | 824725719 |
| Promedio | 598300147 | |
| 5% | Optimista (p5) | 420578235 |
hist(totales_cop, breaks=50, col="skyblue", border="white",
main=titulo_hist, xlab="Total pagado (COP)")
abline(v = mean(totales_cop), col="red", lwd=2, lty=2)
abline(v = quantile(totales_cop, 0.05), col="green", lwd=2, lty=2)
abline(v = quantile(totales_cop, 0.95), col="orange", lwd=2, lty=2)
legend("topright", legend=c("Media","Optimista (p5)","Pesimista (p95)"),
col=c("red","green","orange"), lwd=2, lty=2)
Variabilidad de pagos en pesos:
Aunque el crédito está denominado en dólares, al convertir los pagos a pesos con la TRM simulada, se evidencia un rango amplio en el total a pagar.
El histograma muestra que la mayoría de escenarios se concentran entre 5.000 y 8.000 millones de COP.
ESCENARIOS OPTIMISTAS Y PESIMISTAS
Optimista (p5, línea verde): en un escenario favorable de TRM baja, el total pagado podría acercarse a los 4.500 millones de COP.
Pesimista (p95, línea naranja): en un escenario de fuerte depreciación del peso, los pagos podrían superar los 8.500 millones de COP.
La media (línea roja) se ubica alrededor de 6.000 millones de COP, reflejando el valor esperado.
Implicación financiera:
El crédito en dólares representa un riesgo cambiario considerable: aunque la deuda en USD es fija, en COP la obligación depende directamente de la evolución de la TRM.
Una depreciación del peso (escenario pesimista) encarece significativamente la deuda en pesos, mientras que una apreciación del peso (escenario optimista) reduce el costo.
# (Opcional) Ruta a CSV real de BVC. Si no hay, generamos serie coherente por cost-of-carry.
FILE_BVC_FUT <- "" # p.ej.: "C:/Users/tuusuario/Downloads/bvc_futuros_trm.csv"
load_bvc_futures_monthly <- function(file_csv){
if (nzchar(file_csv) && file.exists(file_csv)) {
fut_raw <- readr::read_csv(file_csv, show_col_types = FALSE)
nms <- tolower(names(fut_raw))
c_date <- names(fut_raw)[grepl("fecha|date", nms)][1]
c_val <- names(fut_raw)[grepl("settle|liquid|cierre|precio|price|valor", nms)][1]
stopifnot(!is.na(c_date), !is.na(c_val))
fut_df <- fut_raw |>
mutate(date = as.Date(.data[[c_date]]),
value = as.numeric(gsub(",", ".", .data[[c_val]]))) |>
arrange(date) |>
filter(!is.na(date), !is.na(value)) |>
mutate(ym = zoo::as.yearmon(date)) |>
group_by(ym) |>
summarise(value = dplyr::last(value), .groups="drop")
return(zoo::zoo(fut_df$value, order.by = fut_df$ym))
}
return(NULL)
}
fut_m <- load_bvc_futures_monthly(FILE_BVC_FUT)
# Tasas (ajusta tasa local comercial si tienes dato real)
tasa_ea_cop <- 0.14
if (!exists("tasa_ea_usd")) tasa_ea_usd <- 0.0882
i_cop_m <- (1 + tasa_ea_cop)^(1/12) - 1
i_usd_m <- (1 + tasa_ea_usd)^(1/12) - 1
# Si no hay CSV, creo una serie coherente con cost-of-carry + basis
if (is.null(fut_m)) {
theo_fut <- coredata(trm_z) * (1 + i_cop_m)/(1 + i_usd_m)
set.seed(321)
basis <- rnorm(length(theo_fut), 0, sd(diff(log(theo_fut))) * 50)
fut_m <- zoo::zoo(theo_fut + basis, order.by = index(trm_z))
}
# Parámetros del futuro (mensual)
r_fut <- diff(log(fut_m))
mu_fut <- mean(na.omit(r_fut))
sig_fut <- sd(na.omit(r_fut))
S0_fut <- as.numeric(tail(fut_m, 1))
kable(data.frame(mu_fut_m = round(mu_fut,6),
sigma_fut_m = round(sig_fut,6),
Futuro_ultimo = round(S0_fut,2)),
caption = "Parámetros del futuro TRM (mensual)")
| mu_fut_m | sigma_fut_m | Futuro_ultimo |
|---|---|---|
| -0.002549 | 0.034335 | 3907.34 |
# Precio teórico inicial (forward anual)
F0_theo <- as.numeric(tail(trm_z, 1)) * (1 + tasa_ea_cop) / (1 + tasa_ea_usd)
# Simulación GBM del futuro 61–120 (48 meses)
mes_ini <- 61; mes_fin <- 120; n_cov <- mes_fin - mes_ini + 1
gbm_path <- function(S0, mu, sig, n) {
S <- numeric(n); S[1] <- S0
for (t in 2:n) S[t] <- S[t-1] * exp((mu - 0.5*sig^2) + sig*rnorm(1))
S
}
F_sim <- gbm_path(F0_theo, mu_fut, sig_fut, n_cov)
# Índice temporal para gráficos
idx_cov <- as.yearmon(seq(as.Date(as.yearmon(tail(index(trm_z), 1))) + 31,
by = "month", length.out = n_cov))
F_sim_z <- zoo::zoo(F_sim, order.by = idx_cov)
# Cobertura del 75% del valor de la maquinaria
notional_cop_cov <- 0.75 * 500e6
trm_ref_cov <- S0
notional_usd_cov <- notional_cop_cov / trm_ref_cov
# Parámetros de contrato (ajusta con ficha BVC)
contract_size_usd <- 1000
initial_margin_per_ctrc <- 800000
maint_margin_per_ctrc <- 600000
n_ctrc <- max(1L, round(notional_usd_cov / contract_size_usd))
kable(data.frame(
Valor_maquinaria_COP = 500e6,
Cobertura_75_COP = notional_cop_cov,
TRM_referencia = round(trm_ref_cov,2),
Exposicion_USD = round(notional_usd_cov,2),
Nominal_por_contrato_USD = contract_size_usd,
Contratos = n_ctrc
), format.args = list(big.mark=","), caption = "Tamaño de la cobertura (años 6–10)")
| Valor_maquinaria_COP | Cobertura_75_COP | TRM_referencia | Exposicion_USD | Nominal_por_contrato_USD | Contratos |
|---|---|---|---|---|---|
| 500,000,000 | 375,000,000 | 3,892.5 | 96,339.11 | 1,000 | 96 |
# P&L mensual por liquidación (posición larga para cubrir alzas USD)
dF <- c(NA, diff(as.numeric(F_sim_z)))
usd_nom <- contract_size_usd * n_ctrc
pnl_fut <- ifelse(is.na(dF), 0, dF * usd_nom) # COP
# Rollover trimestral y control de márgenes
eq <- 0
equity_path <- numeric(length(F_sim_z))
margin_calls <- numeric(length(F_sim_z))
for (t in seq_along(F_sim_z)) {
if (t %% 3 == 1) { # rollover: reconstituir margen inicial
eq <- eq + n_ctrc * initial_margin_per_ctrc
}
eq <- eq + pnl_fut[t]
if (eq < n_ctrc * maint_margin_per_ctrc) {
topup <- n_ctrc * initial_margin_per_ctrc - eq
eq <- eq + topup
margin_calls[t] <- topup
}
equity_path[t] <- eq
}
kable(data.frame(
Margen_inicial_total = n_ctrc * initial_margin_per_ctrc,
Margen_mantenimiento_total= n_ctrc * maint_margin_per_ctrc,
Llamadas_de_margen_acum = sum(margin_calls, na.rm = TRUE),
Equity_final = tail(equity_path, 1)
), format.args = list(big.mark=","), caption="Márgenes y requerimientos de liquidez")
| Margen_inicial_total | Margen_mantenimiento_total | Llamadas_de_margen_acum | Equity_final |
|---|---|---|---|
| 76,800,000 | 57,600,000 | 22,084,298 | 1,483,379,559 |
# Flujo del crédito en COP (regla del profesor) usando TRM esperada (promedio de trayectorias)
trm_exp <- rowMeans(mb) # 120 valores
TRM_t_610 <- trm_exp[mes_ini:mes_fin]
TRM_tm1_610 <- trm_exp[(mes_ini-1):(mes_fin-1)]
interes_COP_610 <- amort$interes[mes_ini:mes_fin] * TRM_tm1_610
abono_COP_610 <- amort$principal[mes_ini:mes_fin] * TRM_t_610
cuota_COP_610 <- interes_COP_610 + abono_COP_610
# Flujo neto con cobertura
flujo_credito <- cuota_COP_610
flujo_neto <- flujo_credito - pnl_fut
resumen_cov <- data.frame(
Contratos = n_ctrc,
Total_credito = sum(flujo_credito, na.rm = TRUE),
Total_pnl_fut = sum(pnl_fut, na.rm = TRUE),
Total_neto = sum(flujo_neto, na.rm = TRUE),
Margin_calls = sum(margin_calls, na.rm = TRUE),
Equity_final = tail(equity_path, 1)
)
kable(resumen_cov, format.args = list(big.mark=","), caption = "Comparación de flujos (años 6–10)")
| Contratos | Total_credito | Total_pnl_fut | Total_neto | Margin_calls | Equity_final |
|---|---|---|---|---|---|
| 96 | 281,612,743 | -74,704,739 | 356,317,483 | 22,084,298 | 1,483,379,559 |
df_cov <- data.frame(
date = as.Date(as.yearmon(index(F_sim_z))),
Futuro_sim = as.numeric(F_sim_z),
PnL_fut = pnl_fut,
Credito_COP = flujo_credito,
Neto_con_cov = flujo_neto,
Margin_eq = equity_path
)
# Precio del futuro simulado
ggplot(df_cov, aes(date, Futuro_sim)) +
geom_line(color="purple") +
labs(title="Futuro TRM simulado (años 6–10)", x="Fecha", y="COP") +
theme_minimal()
# Flujos del crédito vs neto con cobertura
ggplot(df_cov, aes(date, Credito_COP)) +
geom_line() +
geom_line(aes(y=Neto_con_cov), linetype=2, color="steelblue") +
labs(title="Crédito (COP) vs Crédito neto con futuros", x="Fecha", y="COP") +
theme_minimal()
# Equity de márgenes
ggplot(df_cov, aes(date, Margin_eq)) +
geom_line(color="firebrick") +
labs(title="Evolución del equity de márgenes (rollover trimestral)", x="Fecha", y="COP") +
theme_minimal()
La gráfica muestra la evolución esperada de los futuros de la TRM a partir del año 6 de la inversión.
Se observa una alta volatilidad, con periodos de alzas y caídas pronunciadas.
El rango se mueve entre los 3.200 y 4.400 COP/USD, lo que refleja la sensibilidad del mercado cambiario a factores externos.
Esto implica que, al usar futuros, se puede asegurar un nivel de cobertura parcial frente a la variabilidad del tipo de cambio en los últimos 4 años del crédito.
En esta gráfica se comparan los pagos del crédito en pesos contra los pagos netos después de aplicar la cobertura con futuros.
La línea de crédito sin cobertura es más volátil y se eleva en escenarios de TRM alta.
Al aplicar futuros, la exposición cambia y se logran reducciones importantes en algunos escenarios de mayor TRM.
Sin embargo, también puede haber sobre-cobertura en momentos de baja TRM, generando resultados negativos temporales.
En general, el uso de futuros estabiliza parcialmente el flujo en COP, reduciendo el riesgo extremo.
La gráfica refleja la acumulación del equity por márgenes asociados a los contratos de futuros, con rollover trimestral.
Se observa una trayectoria ascendente sostenida, lo que significa que la estrategia de cobertura generó ganancias acumuladas en márgenes.
Al final del horizonte (2030), el equity acumulado supera los 1.500 millones COP, lo que demuestra que la cobertura fue beneficiosa en este escenario simulado.
Esto confirma que el apalancamiento con futuros no solo redujo la exposición cambiaria, sino que además generó valor adicional por movimientos de mercado favorables.
# TRM esperada mensual (promedio de trayectorias del GBM de la Parte 1)
trm_exp <- rowMeans(mb)
TRM_t_610 <- trm_exp[mes_ini:mes_fin]
TRM_tm1_610 <- trm_exp[(mes_ini-1):(mes_fin-1)]
La regla usada es: - Interés en COP: interés ×
TRM_{t-1}
- Abono en COP: principal × TRM_{t}
# Crédito en COP
interes_COP_610 <- amort$interes[mes_ini:mes_fin] * TRM_tm1_610
abono_COP_610 <- amort$principal[mes_ini:mes_fin] * TRM_t_610
cuota_COP_610 <- interes_COP_610 + abono_COP_610
# Flujo neto aplicando cobertura
flujo_credito <- cuota_COP_610
flujo_neto <- flujo_credito - pnl_fut
Creamos un data.frame con toda la información
relevante:
# Data frame para gráficas
df_cov <- data.frame(
date = as.Date(as.yearmon(index(F_sim_z))),
Futuro_sim = as.numeric(F_sim_z),
PnL_fut = pnl_fut,
Credito_COP = flujo_credito,
Neto_con_cov = flujo_neto,
Margin_eq = equity_path
)
head(df_cov)
## date Futuro_sim PnL_fut Credito_COP Neto_con_cov Margin_eq
## 1 2025-10-01 4077.789 0.0 4977413 4977413 76800000
## 2 2025-11-01 4068.957 -847908.8 4969001 5816910 75952091
## 3 2025-12-01 3847.744 -21236389.2 4961709 26198098 76800000
## 4 2026-01-01 3845.993 -168160.0 4952681 5120841 153431840
## 5 2026-02-01 3867.043 2020837.6 4941233 2920396 155452678
## 6 2026-03-01 3887.366 1951055.4 4928864 2977809 157403733
Futuro simulado: Entre los años 6–10 la curva de futuros presenta alta volatilidad; cubrir el 75% de la exposición ayuda a estabilizar pagos en COP. Crédito vs neto: La línea neta (crédito − PnL de futuros) suaviza los picos de egreso frente al pago del crédito sin cobertura. Márgenes: El equity de márgenes crece con el tiempo (en esta simulación), lo que indica aportes positivos de la cobertura, aunque exige liquidez para llamadas de margen. Costo acumulado: La trayectoria con cobertura es inferior a la sin cobertura, mostrando ahorro en el periodo cubierto. Conclusión: La cobertura con futuros desde el año 6 mitiga el riesgo cambiario del crédito en USD y puede mejorar el costo esperado en COP, sujetándose al sesgo del mercado y a una adecuada gestión de márgenes.
Banco de la República. (2025). Encuesta de expectativas
económicas.
https://www.banrep.gov.co
Gómez, J. (2023). Volatilidad cambiaria en mercados emergentes. Universidad Nacional de Colombia.
Federal Reserve. (2024). Monetary Policy Report. Washington, D.C.