La práctica consiste en obtener una maquinaria amarilla comprada en EEUU y pagada a cuotas fijas (sistema de pago francés) en USD. Debido a los factores de volatilidad de tasa de cambio COP/USD y al tratarse de un crédito a largo plazo, se busca obtener compensaciones de las liquidaciones de contratos de futuros del mismo subyacente (TRM) durante los ultimos 4 años de la vida del crédito, debido a la expectativa al alza que podría tener la divisa en Colombia.
La Tasa Representativa del Mercado (TRM) es el indicador que refleja el valor promedio diario del dólar estadounidense frente al peso colombiano. Este tipo de cambio es esencial en la economía nacional, ya que influye en las decisiones empresariales, en la planificación financiera del gobierno y en la formulación de la política monetaria. En contextos de volatilidad internacional y recuperación económica, comprender la dinámica de la TRM permite anticipar escenarios y tomar decisiones informadas a nivel empresarial y macroeconómico (Banco de la República, Informe de Política Monetaria, 2025).
Durante 2024, la TRM presentó una tendencia alcista con un promedio anual de COP 4.329 por dólar y una variación del 15,36%, reflejando una depreciación del peso colombiano. Esta depreciación implica que se requirió una mayor cantidad de pesos para adquirir un dólar, lo cual se traduce en un encarecimiento de las importaciones y una presión inflacionaria sobre los bienes transables. El comportamiento está asociado a factores como la incertidumbre política, la salida de capitales y la percepción de riesgo por parte de los inversionistas extranjeros.
En abril de 2025, la inflación interanual en Colombia fue de 5,16%, superior al 4,46% observado en marzo. Este repunte se explicó por factores estacionales como la Semana Santa y el aumento en los precios de alimentos, bebidas sin alcohol, hospedaje y servicios de hotelería (DANE, 2025). Pese a una inflación de 7,16% registrada en abril de 2024, los esfuerzos por alcanzar la meta del 3% fijada por el Banco de la República se han ralentizado.
La economía colombiana muestra una recuperación moderada, con un crecimiento estimado del 2,6% en 2025 y una proyección de 3,4% para 2026. Esta mejora estaría sustentada en una política monetaria más flexible y en la reducción gradual de la inflación (Banco de la República, Informe de Política Monetaria, 2025). En cuanto a las tasas de interés, la Junta Directiva del Banco de la República redujo en diciembre de 2024 la tasa de interés en 25 puntos básicos, ubicándola en 9%. Esta se mantuvo en enero de 2025, con el objetivo de apoyar la actividad económica y encaminar la inflación hacia su meta.
Según la Encuesta Mensual de Expectativas (EME) del Banco de la República de abril de 2025, se prevé una relativa estabilidad en la TRM durante el resto del año. El Ministerio de Hacienda estima un promedio de COP 4.266, mientras que el Banco de la República proyecta COP 4.209 para el cierre de 2025. Estas diferencias se explican por los distintos supuestos utilizados: el Ministerio asume un escenario de persistencia en los choques externos, mientras que el Banco contempla una mejora gradual en los flujos de capital y el precio del petróleo (Banco de la República, EME, abril 2025; Ministerio de Hacienda, Boletín Fiscal, 2025).
Los factores que inciden en la TRM pueden dividirse en externos e internos:
Factores Externos: Un aumento en las tasas de interés por parte de la Reserva Federal de EE. UU. tiende a fortalecer el dólar, dado que los inversores buscan mayores rendimientos, lo que puede generar una salida de capitales de economías emergentes como la colombiana. Esto eleva la demanda de dólares, presionando al alza la TRM (Federal Reserve, 2024). Además, los precios del petróleo, las tensiones comerciales globales y la calificación crediticia del país también influyen significativamente.
Factores Internos: La política monetaria del Banco de la República, el nivel de inflación interna, la cuenta corriente y los flujos de inversión extranjera directa (IED) son determinantes importantes. Un deterioro en la balanza comercial o una reducción en la IED puede traducirse en menor disponibilidad de dólares, presionando la TRM al alza. La credibilidad en la política fiscal también afecta las expectativas del tipo de cambio.
Entre los principales riesgos que podrían alterar las proyecciones de la TRM se encuentran: • Riesgos Políticos: Inestabilidad en las reformas fiscales o laborales podría reducir la confianza inversionista.
• Riesgos Internacionales: Una recesión en EE. UU. o Europa disminuiría la demanda de exportaciones colombianas, debilitando el peso.
• Volatilidad de los Commodities: Caídas en los precios del petróleo afectarían negativamente los ingresos de divisas.
1. Paridad del Poder Adquisitivo (PPA): Si la TRM está significativamente por encima del nivel de PPA estimado, podría estar sobrevaluada, sugiriendo un posible ajuste a la baja en el largo plazo.
2. Diferencial de Tasas de Interés: Una mayor tasa de interés en Colombia respecto a EE. UU. puede atraer capitales, apreciando el peso. No obstante, si el diferencial se reduce o se invierte, puede darse una salida de capitales.
3. Cuenta Corriente y Balanza Comercial: Un déficit creciente en la cuenta corriente implica mayor demanda de dólares para financiarlo, presionando al alza la TRM.
4. Flujos de Inversión Extranjera Directa y de Portafolio: La entrada de capitales reduce la presión sobre el tipo de cambio, mientras que su salida la incrementa.
La depreciación del peso o incremento de TRM a menudo desatan presiones inflacionarias muy significativas, ya que bienes y servicios importados, junto con los insumos monetizados para la producción en el país, se vuelven más costosos en su moneda doméstica. En este sentido, la efectividad de la “pass-through” directa sobre los costos se dispara al consumidor final y, por lo tanto, sube la inflación general:
Además, una inflación continua y sin relación con nuestros socios comerciales consumidorá el poder adquisitivo del peso colombiano propiamente dicho. “En términos resumidos de sobreun equidad el poder adquisitivo, la moneda relativa, debe si desea favorecimientos relucir relativamente por la inestabilidad en el largo plazo, esta discrepancia inflacionaria ejerce unas presiones naturales a la devaluación de la TRM para equilibrar el poder adquisitivo. Sin embargo, los fundamentos de política monetaria del Banco de la República en términos de inflación entre otras cosas, particularmente el aumento de las tasas de interés, puede modificar la respuesta de flujos de capital: este impacto comprable la oferta y demanda de divisas que afecta, por lo tanto, ERP. Todo este fenómeno es fundamental para macroeconómico sólidos.
library(readr)
library(dplyr)
library(lubridate)
library(FinCal)
library(FinancialMath)
library(ggplot2)
library(reshape2)
library(FinancialMath)
library(tidyr)
Por medio de la simulación se busca mostrar por lo menos en los primeros 5 años una trayectoria que va acorde con la actualización de proyecciones económicas para Colombia publicada por Bancolombia, la cual conjunto con información presentada por el Banco de la República, presentan un pronóstico que evidencia una tendencia al alza a lo largo del tiempo, teniendo un techo máximo de $4700.
Teniendo en cuenta el componente cíclico que se ha evidenciado a lo largo de la historia de la cotización de la TRM, la cual presenta diferentes tendencias por factores internos y externos, se espera elegir una trayectoria que muestre unas leves caídas en su cotización, pero que siga conservando la tendencia alcista que se ha evidenciado a lo largo de los últimos 20 años. Debido a que las proyecciones presentadas para los siguientes 5 años, no se evidencia valores esperados que superen los 5000, se mantendrá el mismo supuesto para tener un margen de 200-300 para no sobrevalorar finalmente los flujos de cajas y tener un escenario más real de acuerdo a las proyecciones disponibles a fecha de hoy.
Para la construcción de la simulación se tomara el histórico de la TRM de los últimos 5 años hasta la actualidad, estos datos son obtenidos directamente del sitio web oficial del Banco de la República.
Se agrupará el histórico diario de forma mensual tomando los días 15 de cada mes para obtener los párametros directamentes mensuales y evitar el sesgo que se pueda obtener al mensualizar un parámetro diario
trm<-read.csv2("TRM.csv")
trm<-trm %>% rename(Fecha = 'Periodo.MMM.DD..AAAA.')
trm<-trm %>% rename(TRM = 'Tasa.Representativa.del.Mercado..TRM.')
trm<-trm %>% mutate(Fecha = dmy(Fecha))
trm<-trm %>% filter(Fecha >= as.Date("2020-01-01"))
#Agrupar mensualmente
trm_mensual<-trm %>% filter(Fecha >= as.Date("2020-01-15") & Fecha <=as.Date("2025-05-15"))
trm_mensual <- trm_mensual %>% mutate(Periodo = floor_date(Fecha, unit = "month")) %>%
group_by(Periodo) %>% summarise(TRM_mensual = mean(TRM, na.rm = TRUE))
#Calcular parametros para simular
retornos_trm<- diff(log(trm_mensual$TRM_mensual))
r_trm<-exp(mean(retornos_trm)) - 1
sigma_trm <- sd(retornos_trm)
print(r_trm)
## [1] 0.003716333
print(sigma_trm)
## [1] 0.03524845
Se podría pensar que al obtener un rendimiento mensual tan cercano a 0 es porque no hay mucha volatilidad en este. Sin embargo, la volatilidad es del 3%, por lo que se entiende que el rendimiento tan bajo se debe a que hay lapsos de tiempo en donde la TRM presenta caídas como lo pudo ser durante el tiempo de la pandemia causada por el COVID-19 y otros momentos en donde esta aumentó su cotización debido a conflictos externos como la guerra entre Rusia y Ucrania, conyunturas internas como el paro del 2021, políticas monetarias del Banco de la República y las expectativas sobre el país debido a las elecciones del 2022. Lo cual hace que el rendimiento se termine contrarrestando entre sí y por eso sea tan alto, lo que refleja una alta volatilidad (Portafolio, 2024).
#Simulacion TRM
T<-120 #10 años
dt<-1/12
s0<-as.numeric(last(trm_mensual[, "TRM_mensual"]))
N<-1
set.seed(2032)
vec_trm=rep(s0,N)
mb_trm=matrix(ncol=N,nrow = T)
mb_trm[1,]=vec_trm
for (i in 1:N) {
for (t in 2:T) {
mb_trm[t,i]=mb_trm[(t-1),i]*exp((r_trm-(0.5*(sigma_trm^2)))*(dt) +
sigma_trm*(dt^(1/2))*qnorm(runif(1, min = 0, max = 1)))
}
}
df_trm <- data.frame(Mes = 1:length(mb_trm), TRM = mb_trm)
ggplot(df_trm, aes(x = Mes, y = TRM)) + geom_line(color = "blue", size = 1) +
labs(title = "Trayectoria simulada de TRM", x = "Mes", y = "TRM") +
theme_minimal()+theme(plot.title = element_text(hjust = 0.5))
Para la compra de la maquinaria amarilla el valor de la TRM del día 15 de mayo del 2025, el cual fue de 4244.44. El valor a financiar fue de 60078.55 USD pagaderos mensual a 10 años.
Se usó para la simulación una tasa del 9.25% de Wells Fargo, esta tasa contiene una parte fija para cualquier cliente del 1.75% y se le añade un factor de prima de riesgo generalizado del 7.5%, la suma de estos dos componentes dan como resultado una tasa nominal con capitalización mensual
inversionCOP<-300000000
inversionUSD<-inversionCOP/s0
monto_credito<-inversionUSD*0.85
tasa_nominalUSD<-0.0925 #Capitalización mensual
tasa_efectiva_mensualUSD<-tasa_nominalUSD/12
#Credito en USD
cuotaUSD<-pmt(r=tasa_efectiva_mensualUSD,n=120,pv=-monto_credito, fv=0)
amortizacionUSD<-amort.table(Loan=monto_credito, n=120, i=tasa_nominalUSD,ic=12,pf=12)
amortizacionUSD <- amortizacionUSD$Schedule
head(amortizacionUSD)
## Year Payment Interest Paid Principal Paid Balance
## 1 0.08 769.2 463.11 306.10 59772.45
## 2 0.17 769.2 460.75 308.46 59464.00
## 3 0.25 769.2 458.37 310.83 59153.16
## 4 0.33 769.2 455.97 313.23 58839.93
## 5 0.42 769.2 453.56 315.64 58524.29
## 6 0.50 769.2 451.12 318.08 58206.21
#Credito en COP
mb_trm <- as.vector(mb_trm)
amortizacionCOP <- amortizacionUSD
columnas_amortizacion <- c("Payment", "Interest Paid", "Principal Paid", "Balance")
amortizacionCOP[ , columnas_amortizacion] <- amortizacionUSD[ , columnas_amortizacion] * mb_trm
df_pago <- data.frame(Mes = 1:nrow(amortizacionCOP),Pago = amortizacionCOP[, "Payment"])
ggplot(df_pago, aes(x = Mes, y = Pago)) + geom_line(color = "darkblue", size = 1) +
labs(title = "Evolución del Pago Mensual en COP", x = "Mes", y = "COP") +
theme_minimal() + theme(plot.title = element_text(hjust = 0.5))
El valor de la primera cuota en COP será:
cuota1_COP<-cuotaUSD*s0
print(cuota1_COP)
## [1] 3264834
Según la trayectoria simulada de la TRM, se visualiza que el punto desde donde comienza el crédito es el punto mas bajo de toda la serie. Esto indica que el pago de la cuota en el primer periodo será el más bajo de toda la simulación del crédito y cada vez tendrá que desembolsar más pesos colombianos para cumplir por una obligación financiera fijada en USD.
Por lo que podemos observar se observan aumentos con respecto a la primera cuota de hasta 3900000 aproximadamente y sobretodo en los últimos periodos el valor de la cuota presenta una tendencia al alza muy pronunciada.
El precio téorico del futuro establece la relación del precio del mismo con base a la tasa nacional e internacional y servirá para marcar un punto de partida para la simulación. Para el cálculo de este se utilizó para el caso de Colombia la tasa de los TES a un año y en el caso de EEUU la tasa libre de riesgo TBond a un año.
Se usan estas tasas estatales ya que en cada país, son las de menor riesgo y establecen el precio justo sin oportunidad de arbitraje mostrando una condicón de equilibrio lo cual haría que la simulación esté basada sobre un precio más justo (condición de paridad) y permita visaulizar una cobertura que no contenga el riesgo crediticio que podría tener por defecto una tasa comercial.
La tasa a usar del TES a un año es del 8.95% EA (Banco de la República, 2025) La tasa TBond de EEUU a un año es del 4.13% nominal con capitalización semestral (U.S. Department of the Treasury, 2025)
futures<-read.csv2("futures.csv")%>%mutate(Precio_cierre = as.numeric(gsub(",", "", Precio_cierre)))
rn<-0.0895
re<-0.0413
re<-(1+re/2)^(12)-1
F0<-as.numeric(last(futures[, "Precio_cierre"]))
FT=F0*((1+rn)/(1+re))^(1/12)
#El precio teórico del futuro basado en la paridad de tasas es:
print(FT)
## [1] 4135.643
Se usó el contrato TRXM25F para calcular los parametros de media y desviación necesarios para la simulación. Los datos descargados desde la Bolsa de Valores de Colombia (BVC) solo permitía obtener un historial de los últimos 6 meses. Dado que es poca información para definir de manera adecuada los parámetros se optó por obtenerlos con periodicidad diaria y posteriormente mensualizarlos.
#Calcular parametros para simular
retornos_futures<- diff(log(futures$Precio_cierre))
r_futures<-exp(mean(retornos_futures)) - 1
sigma_futures <- sd(retornos_futures)
#Mensualizar los parametros
r_futures<-r_futures*21
sigma_futures<-sqrt(21)*sigma_futures
#Simulacion Futuros de la TRM
T<-120 #10 años
N<-1
set.seed(8)
vec_futures=rep(FT,N)
mb_futures=matrix(ncol=N,nrow = T)
mb_futures[1,]=vec_futures
for (i in 1:N) {
for (t in 2:T) {
mb_futures[t,i]=mb_futures[(t-1),i]*exp((r_futures-(0.5*(sigma_futures^2)))*(dt) +
sigma_futures*(dt^(1/2))*qnorm(runif(1, min = 0, max = 1)))
}
}
df_future <- data.frame(Mes = 1:length(mb_futures), Futuro = mb_futures)
ggplot(df_future, aes(x = Mes, y = Futuro)) + geom_line(color = "red", size = 1) +
labs(title = "Trayectoria simulada del precio del Futuro", x = "Mes", y = "Futuro") +
theme_minimal()+theme(plot.title = element_text(hjust = 0.5))
El ejercicio propone un apalancamiento con futuros del 75%, pero la idea de esta práctica es cuestionar si con un menor porcentaje se puede lograr una cobertura que no genere en un riesgo muy grande en términos de flujo de caja a la empresa. Por lo que se decidirá trabajar con contratos de tipo TRX que permitan disminuir el número de contratos adquiridos para hacer la cobertura, ya que si se optara por un contrato de tipo TRM, por el tamaño del contrato, se incurriría en un mayor riesgo ya que este tipo de instrumento su tamaño de contrato es de 50000 USD y teniendo presente que el monto financiado es de 60000 USD por lo que o se toma 1 o 2 contratos, lo cual sería muy riesgoso debido a los grandes montos y términos de liquidación.
El numero de contratos basados en el punto inicial de apalancamiento en futuros al 75% sería:
cobertura<-inversionUSD*0.75
trx<-1000
numero_contratos<-round(cobertura/trx)
print(numero_contratos)
## [1] 53
Teniendo en cuenta que la cuota fija es de 769.20 USD, se propone realizar una cobertura con 2 contratos ya que si se hiciera una cobertura con el 75% del valor de la inversión se obtendrían un numero muy grande contratos y la volatilidad presentada de la trayectoria del futuro haría que los flujos de caja de la empresa se vean bastante comprometidos.
Lo más ideal en la cobertura con el futuro es que, si se obtiene ganancia con las liquidaciones del futuro, se compense en la cuota esas fluctuaciones de la TRM y en caso de que se generen pérdidas, estas no sean muy grandes y comprometan aún más el flujo de caja de la empresa.
La propuesta es demostrar que con 2 contratos es suficiente para hacer una cobertura ante el riesgo de tasa de cambio. Proporcionalmente como el tamaño de cada contrato de la TRX es de 1000 dólares y la cuota es menor a ese valor, al trabajar con márgenes, se esperaría que independientemente del resultado de la liquidación mes a mes, los valores serán pequeños y mientras se pierde/gana con la liquidación del futuro se gana/pierde con el cambio de tasa con valores que sean representativamente más del 20% del valor de la cuota, para que de esta manera no se vea tan afectado el flujo de caja.
El margen de mantenimiento será del 50% trabajandolo como un estándar dentro de los ejercicios de futuros y el margen incial será del 6,3% basado en la información de apalancamiento de futuros proporcionado por la BVC.
El nominal del contrato será 4191 a fecha del 16 de mayo de 2025 proporcionado por la misma BVC.
Por lo tanto la exposición total será:
numero_contratos<-2
nominal<-4191
valor_contrato<-trx*numero_contratos
exp_total<-valor_contrato*nominal
margen_inicial<-0.063*exp_total
margen_mantenimiento<-0.5
print(exp_total)
## [1] 8382000
print(margen_inicial)
## [1] 528066
El ejercicio de cobertura comienza desde el año 6 hasta el final del crédito en el año 10. La razón de hacer la simulación del futuro fue para decidir las posiciones a tomar en cada uno de los periodos, las liquidaciones del futuro se harán cada 6 meses y al finalizar se hará un rollover, el cuál permitirá hacer un cambio de posición.
Para definir las posiciones primero se graficará conjunto con la simulación del TRM como se comportan ambos durante los últimos 4 años estableciendo los limites cada 6 meses.
# Crear dataframes
mb_trm_df <- data.frame(Mes = 1:length(mb_trm),Valor = mb_trm)
mb_futures_df <- data.frame(Mes = 1:length(mb_futures),Valor = mb_futures)
# Filtrar los datos para el rango de meses deseado (72 a 120)
mb_trm_filtrado <- mb_trm_df %>%filter(Mes >= 72 & Mes <= 120)
mb_futures_filtrado <- mb_futures_df %>%filter(Mes >= 72 & Mes <= 120)
# Crear el gráfico con ggplot2 y añadir líneas verticales
ggplot() + geom_line(data = mb_trm_filtrado, aes(x = Mes, y = Valor, color = "Simulación TRM"), linewidth = 1) + geom_line(data = mb_futures_filtrado, aes(x = Mes, y = Valor, color = "Simulación Futuros"), linewidth = 1) + geom_vline(xintercept = seq(72, 120, by = 6), linetype = "dashed", color = "grey50") + labs(title = "Simulación TRM vs. Simulación Futuros (Meses 72-120)", x = "Mes", y = "Valor", color = "Simulación") + scale_color_manual(values = c("Simulación TRM" = "blue", "Simulación Futuros" = "red")) +
theme_minimal()
Al analizar el comportamiento del futuro en los últimos 4 años, se definen las siguientes posiciones para los siguientes 8 períodos:
generar_tabla_futuros <- function(tiempo, precios_futuros, precio_futuro_inicial, valor_contrato, margen_inicial, margen_mantenimiento_porcentaje = 0.5, posicion = "larga") {
margen_mantenimiento <- margen_inicial * margen_mantenimiento_porcentaje
tabla_futuros <- data.frame(
T = tiempo,
Precio.Futuro = c(precio_futuro_inicial, precios_futuros),
Dif.PF = numeric(length(tiempo)),
Liquidacion = numeric(length(tiempo)),
Margen = numeric(length(tiempo)),
Margin.Call = character(length(tiempo))
)
tabla_futuros$Margen[1] <- margen_inicial
tabla_futuros$Dif.PF[1] <- 0
tabla_futuros$Liquidacion[1] <- 0
tabla_futuros$Margin.Call[1] <- 0
for (i in 2:nrow(tabla_futuros)) {
precio_hoy <- tabla_futuros$Precio.Futuro[i]
precio_ayer <- tabla_futuros$Precio.Futuro[i-1]
if (posicion == "larga") {
tabla_futuros$Dif.PF[i] <- precio_hoy - precio_ayer
} else if (posicion == "corta") {
tabla_futuros$Dif.PF[i] <- precio_ayer - precio_hoy
} else {
stop("La posición debe ser 'larga' o 'corta'.")
}
tabla_futuros$Liquidacion[i] <- tabla_futuros$Dif.PF[i] * valor_contrato
margen_previo <- tabla_futuros$Margen[i-1]
liquidacion_actual <- tabla_futuros$Liquidacion[i]
margin_call_previo <- ifelse(tabla_futuros$Margin.Call[i-1] != 0 & tabla_futuros$Margin.Call[i-1] != "-", as.numeric(tabla_futuros$Margin.Call[i-1]), 0)
margen_actual <- margen_previo + liquidacion_actual + margin_call_previo
tabla_futuros$Margin.Call[i] <- 0
if (margen_actual < margen_mantenimiento) {
monto_margin_call <- margen_inicial - margen_actual
tabla_futuros$Margin.Call[i] <- format(monto_margin_call, scientific = FALSE)
tabla_futuros$Margen[i] <- margen_actual # Guardar el margen ANTES del call
} else {
tabla_futuros$Margen[i] <- margen_actual
}
}
# Formatear la salida
tabla_futuros <- tabla_futuros %>%
mutate(
Dif.PF = ifelse(T == tiempo[1], 0, as.character(Dif.PF)),
Liquidacion = ifelse(T == tiempo[1], 0, as.character(format(Liquidacion, scientific = FALSE))),
Margen = format(Margen, scientific = FALSE),
Margin.Call = ifelse(Margin.Call != 0, Margin.Call, 0)
)
return(tabla_futuros)
}
Para terminos prácticos en la consolidación de la función se establece en cada periodo inicial el margen inicial, validando respectivamente al final de cada periodo que se esté sobre el margen de mantenimiento. Cuando se analicen los flujos de caja, lo que se hace es descontar al inicio de cada periodo el margen inicial para conocer el saldo real en el ejercicio.
tiempo1<-72:78
future1<-mb_futures[73:78, 1]
inicial_future1<-mb_futures[72,1]
tabla1 <- generar_tabla_futuros(tiempo1, future1, inicial_future1,
valor_contrato, margen_inicial, margen_mantenimiento,
posicion = "larga")
print(tabla1)
## T Precio.Futuro Dif.PF Liquidacion Margen Margin.Call
## 1 72 4311.150 0 0 528066.0 0
## 2 73 4312.793 1.64264173046649 3285.283 531351.3 0
## 3 74 4411.264 98.4716071838693 196943.214 728294.5 0
## 4 75 4465.365 54.1004353297976 108200.871 836495.4 0
## 5 76 4387.523 -77.8416660893154 -155683.332 680812.0 0
## 6 77 4423.402 35.8789887969297 71757.978 752570.0 0
## 7 78 4418.608 -4.7942601982686 -9588.520 742981.5 0
tiempo2<-78:84
future2<-mb_futures[79:84, 1]
inicial_future2 <-mb_futures[78, 1]
tabla2 <- generar_tabla_futuros(tiempo2, future2, inicial_future2,
valor_contrato, margen_inicial, margen_mantenimiento,
posicion = "larga")
print(tabla2)
## T Precio.Futuro Dif.PF Liquidacion Margen Margin.Call
## 1 78 4418.608 0 0 528066.0 0
## 2 79 4586.016 167.408322490057 334816.64 862882.6 0
## 3 80 4645.355 59.3390091241181 118678.02 981560.7 0
## 4 81 4786.553 141.197910402256 282395.82 1263956.5 0
## 5 82 4834.948 48.3950155114453 96790.03 1360746.5 0
## 6 83 4896.362 61.414314608207 122828.63 1483575.1 0
## 7 84 4821.607 -74.7551755497507 -149510.35 1334064.8 0
tiempo3<-84:90
future3<-mb_futures[85:90, 1]
inicial_future3 <-mb_futures[84, 1]
tabla3 <- generar_tabla_futuros(tiempo3, future3, inicial_future3,
valor_contrato, margen_inicial, margen_mantenimiento,
posicion = "larga")
print(tabla3)
## T Precio.Futuro Dif.PF Liquidacion Margen Margin.Call
## 1 84 4821.607 0 0 528066.0 0
## 2 85 4938.182 116.574570064209 233149.14 761215.1 0
## 3 86 4970.680 32.4978056406799 64995.61 826210.8 0
## 4 87 4898.385 -72.2948826349057 -144589.77 681621.0 0
## 5 88 4868.037 -30.3472761758958 -60694.55 620926.4 0
## 6 89 4804.835 -63.2027354551938 -126405.47 494521.0 0
## 7 90 4884.964 80.1292505859283 160258.50 654779.5 0
tiempo4<-90:96
future4<-mb_futures[91:96, 1]
inicial_future4<-mb_futures[90, 1]
tabla4 <- generar_tabla_futuros(tiempo4, future4, inicial_future4,
valor_contrato, margen_inicial, margen_mantenimiento,
posicion = "corta")
print(tabla4)
## T Precio.Futuro Dif.PF Liquidacion Margen Margin.Call
## 1 90 4884.964 0 0 528066.0 0
## 2 91 4805.038 79.9261452560704 159852.29 687918.3 0
## 3 92 4569.203 235.834994418438 471669.99 1159588.3 0
## 4 93 4640.103 -70.9002630328514 -141800.53 1017787.8 0
## 5 94 4563.445 76.6580868548645 153316.17 1171103.9 0
## 6 95 4591.836 -28.39098476862 -56781.97 1114322.0 0
## 7 96 4628.653 -36.8173808833099 -73634.76 1040687.2 0
tiempo5<-96:102
future5<-mb_futures[97:102, 1]
inicial_future5<-mb_futures[96, 1]
tabla5 <- generar_tabla_futuros(tiempo5, future5, inicial_future5,
valor_contrato, margen_inicial, margen_mantenimiento,
posicion = "corta")
print(tabla5)
## T Precio.Futuro Dif.PF Liquidacion Margen Margin.Call
## 1 96 4628.653 0 0 528066.0 0
## 2 97 4538.688 89.9649850434216 179929.97 707996.0 0
## 3 98 4573.286 -34.5979388555443 -69195.88 638800.1 0
## 4 99 4566.956 6.33073013483317 12661.46 651461.6 0
## 5 100 4494.241 72.7141728516572 145428.35 796889.9 0
## 6 101 4459.733 34.5088055982696 69017.61 865907.5 0
## 7 102 4589.577 -129.844186845921 -259688.37 606219.1 0
tiempo6<-102:108
future6<-mb_futures[103:108, 1]
inicial_future6<-mb_futures[102, 1]
tabla6 <- generar_tabla_futuros(tiempo6, future6, inicial_future6,
valor_contrato, margen_inicial, margen_mantenimiento,
posicion = "corta")
print(tabla6)
## T Precio.Futuro Dif.PF Liquidacion Margen Margin.Call
## 1 102 4589.577 0 0 528066.0 0
## 2 103 4463.896 125.680768837769 251361.54 779427.5 0
## 3 104 4424.359 39.5374000665997 79074.80 858502.3 0
## 4 105 4405.150 19.2086626324062 38417.33 896919.7 0
## 5 106 4475.913 -70.7625404943274 -141525.08 755394.6 0
## 6 107 4558.508 -82.5950507617181 -165190.10 590204.5 0
## 7 108 4549.868 8.63929953294974 17278.60 607483.1 0
tiempo7<-108:114
future7<-mb_futures[109:114, 1]
inicial_future7<-mb_futures[108, 1]
tabla7 <- generar_tabla_futuros(tiempo7, future7, inicial_future7,
valor_contrato, margen_inicial, margen_mantenimiento,
posicion = "larga")
print(tabla7)
## T Precio.Futuro Dif.PF Liquidacion Margen Margin.Call
## 1 108 4549.868 0 0 528066.0 0
## 2 109 4599.166 49.2982073104504 98596.41 626662.4 0
## 3 110 4719.736 120.569353760537 241138.71 867801.1 0
## 4 111 4831.403 111.667468931967 223334.94 1091136.1 0
## 5 112 4907.622 76.2182807746785 152436.56 1243572.6 0
## 6 113 5060.317 152.69578113885 305391.56 1548964.2 0
## 7 114 4962.022 -98.2954212580044 -196590.84 1352373.3 0
tiempo8<-114:120
future8<-mb_futures[115:120, 1]
inicial_future8<-mb_futures[114, 1]
tabla8<- generar_tabla_futuros(tiempo8, future8, inicial_future8,
valor_contrato, margen_inicial, margen_mantenimiento,
posicion = "corta")
print(tabla8)
## T Precio.Futuro Dif.PF Liquidacion Margen Margin.Call
## 1 114 4962.022 0 0 528066.0 0
## 2 115 4915.973 46.0486848860355 92097.37 620163.4 0
## 3 116 4842.646 73.327141865987 146654.28 766817.7 0
## 4 117 4862.895 -20.2492154192723 -40498.43 726319.2 0
## 5 118 4679.685 183.21039358611 366420.79 1092740.0 0
## 6 119 4840.013 -160.328212477489 -320656.42 772083.6 0
## 7 120 4938.891 -98.8775812107715 -197755.16 574328.4 0
Hasta el momento, sin mirar el flujo de caja de la empresa y basándonos en la información dada por las anteriores tablas, se tomó una posición correcta en cada uno de los períodos debido a que no hubo llamados al margen en ningún periodo. Esto quiere decir que el margen acumulado fue suficiente para soportar las posibles pérdidas y la afectación al flujo de caja por el momento no ha sido más grande, gracias a la buena toma de decisiones en la posición de cada período.
Para hacer este cálculo se debe de entender que el periodo inicial comienza con flujo negativo debido al margen inicial. Los siguientes periodos hasta el final muestran el efecto de las compensaciones netas obtenidas que servirán para hacer la debida cobertura a las cuotas pagadas. Esto será análizado en la parte final de este informe.
calcular_flujo_caja_futuros <- function(tabla_futuros, margen_inicial_bloque, es_primera_tabla_serie = FALSE) {
margin_call_numeric <- ifelse(tabla_futuros$Margin.Call == "0" | tabla_futuros$Margin.Call == "-" | is.na(tabla_futuros$Margin.Call),
0,
as.numeric(gsub(",", "", tabla_futuros$Margin.Call)))
liquidacion_numeric <- as.numeric(gsub(",", "", tabla_futuros$Liquidacion))
flujo_caja_por_periodo <- numeric(nrow(tabla_futuros))
if (es_primera_tabla_serie) {
flujo_caja_por_periodo[1] <- -margen_inicial_bloque
} else {
flujo_caja_por_periodo[1] <- 0
}
for (k in 2:(nrow(tabla_futuros) - 1)) {
flujo_caja_por_periodo[k] <- liquidacion_numeric[k] - margin_call_numeric[k]
}
ultimo_periodo_idx <- nrow(tabla_futuros)
flujo_caja_por_periodo[ultimo_periodo_idx] <-
liquidacion_numeric[ultimo_periodo_idx] - margin_call_numeric[ultimo_periodo_idx]
return(flujo_caja_por_periodo)
}
Se procede a ejecutar la función para calcular los flujos de caja de cada uno de los periodos y se guardarán en un objeto individualmente para luego por medio de una nueva función se puedan concatenar.
flujo_future1<-calcular_flujo_caja_futuros(tabla1,margen_inicial,es_primera_tabla_serie = TRUE)
flujo_future2<-calcular_flujo_caja_futuros(tabla2,margen_inicial)
flujo_future3<-calcular_flujo_caja_futuros(tabla3,margen_inicial)
flujo_future4<-calcular_flujo_caja_futuros(tabla4,margen_inicial)
flujo_future5<-calcular_flujo_caja_futuros(tabla5,margen_inicial)
flujo_future6<-calcular_flujo_caja_futuros(tabla6,margen_inicial)
flujo_future7<-calcular_flujo_caja_futuros(tabla7,margen_inicial)
flujo_future8<-calcular_flujo_caja_futuros(tabla8,margen_inicial)
flujos_cubiertos_temp <- c()
periodos_cubiertos_temp <- c()
lista_flujos_individuales <- list(flujo_future1,flujo_future2,flujo_future3,
flujo_future4,flujo_future5,flujo_future6,
flujo_future7,flujo_future8)
rangos_tiempo <- list(72:78, 78:84, 84:90, 90:96, 96:102, 102:108, 108:114, 114:120)
num_flujos <- length(lista_flujos_individuales)
for (i in 1:num_flujos) {
flujo_actual <- lista_flujos_individuales[[i]]
tiempos_actuales <- rangos_tiempo[[i]]
if (length(flujo_actual) != length(tiempos_actuales)) {
stop(paste0("El flujo_future", i, " tiene un número de elementos diferente a su rango de tiempo definido. Revise los datos."))
}
flujos_cubiertos_temp <- c(flujos_cubiertos_temp, flujo_actual)
periodos_cubiertos_temp <- c(periodos_cubiertos_temp, tiempos_actuales)
}
flujo_caja_cobertura_con_nombres_temp <- tapply(flujos_cubiertos_temp,
INDEX = periodos_cubiertos_temp,
FUN = sum)
flujo_caja_cobertura_ordenado <- flujo_caja_cobertura_con_nombres_temp[order(as.numeric(names(flujo_caja_cobertura_con_nombres_temp)))]
Al ejecutar esta función se obtiene los flujos de caja de los 8 períodos concatenados en un único objeto lo cual nos permite graficarlo fácilmente y entender el comportamiento de las compensaciones a lo largo de los últimos 4 años.
flujo_caja_cobertura_final <- as.numeric(flujo_caja_cobertura_ordenado)
meses <- 72:(72+length(flujo_caja_cobertura_final)-1)
df_flujo_futuro <- data.frame(Mes = meses, Flujo = flujo_caja_cobertura_final)
ggplot(df_flujo_futuro, aes(x = Mes, y = Flujo)) + geom_line(color = "steelblue", size = 1) +
geom_point(color = "darkblue", size = 1.5) + labs(title = "Flujo de caja mensual basado en las liquidaciones del futuro",
x = "Mes", y = "Flujo de Caja") + theme_minimal() + theme(plot.title = element_text(hjust = 0.5))
Como podemos observar, el comportamiento es bastante voláti, pero sobresalen más los flujos de caja por encima de 0, lo cual indican la correcto elección de las posiciones en cada uno de los periodos de liquidación del contrato de futuros. La alta volatilidad se puede explicar mediante la misma gráfica simulada del precio del futuro en los 4 años, los cuales a pesar de tomar lapsos de tiempo de 6 meses, al tener que liquidar de manera mensaul, hay movimientos muy fuertes que afectan este flujo de caja. Por lo tanto, la posición muchas veces no se puede tomar pensando unicamente en el precio inicial y el precio final al que podría cotizar el futuro, sino también en esos movimiento intermedios que más prevalecen durante los 6 meses utilizados.
Este último paso hace referencia la suma de los flujos de caja obtenidos de las liquidaciones del futuro y los flujos de caja del pago de las cuotas en los meses 72 al 120 en donde se completa el pago del crédito. Para esto primero analicemos el comportamiento de la cuota en COP su volatilidad y los máximos y mínimos que alcanza.
pagos_amortizacion_netos <- as.numeric(-1*amortizacionCOP[72:nrow(amortizacionCOP), "Payment"])
meses <- 72:(72 + length(pagos_amortizacion_netos) - 1)
df_amortizacion <- data.frame(Mes = meses, Pago = pagos_amortizacion_netos)
ggplot(df_amortizacion, aes(x = Mes, y = Pago)) + geom_line(color = "firebrick", size = 1) + geom_point(color = "darkred", size = 1.5) + labs(title = "Flujo de caja del pago de la cuota en COP sin cobertura", x = "Mes", y = "Valor del Pago") + theme_minimal() + theme(plot.title = element_text(hjust = 0.5))
print(min(amortizacionCOP[72:nrow(amortizacionCOP), "Payment"]))
## [1] 3359861
print(max(amortizacionCOP[72:nrow(amortizacionCOP), "Payment"]))
## [1] 3831465
Como se puede evidenciar, en estos últimos periodos existe un mayor riesgo que enfrenta la empresa ante una proyección al alza de la TRM. Lo cuál haría que su cuota en COP fluctue entre 3359861 y 3831465, por lo que la diferencia absoluta entre ambos valores sería un valor estimado entre lo que podría esperarse que produzca la compensación por el futuro. Se debe de tener en cuenta nuevamente que lo ideal es que si se pierde con la liquidación de los contratos con futuros, se gana pagando un menor valor en cuota, teniendo presente que pueden haber escenarios en los que se pierda por ambas partes si no hay una buena decisión en la estrategia.
Ahora veamos de forma gráfica como se comporta el flujo de caja de la cuota al sumarle la compensación hecha por las operaciones con los futuros durante los últimos 4 años (8 períodos).
flujo_compensado<-flujo_caja_cobertura_final+pagos_amortizacion_netos
df_comparacion <- data.frame(Mes = meses, Amortizacion = pagos_amortizacion_netos, Compensado = flujo_compensado)
df_largo <- pivot_longer(df_comparacion, cols = -Mes, names_to = "Tipo", values_to = "Valor")
ggplot(df_largo, aes(x = Mes, y = Valor, color = Tipo)) + geom_line(size = 1) +
geom_point(size = 1.5) + scale_color_manual(values = c("Amortizacion" = "firebrick", "Compensado" = "steelblue")) +
labs(title = "Comparación: Pagos Netos de Amortización vs Flujo Compensado",
x = "Mes", y = "Valor del Flujo", color = "Tipo de Flujo") +theme_minimal() + theme(plot.title = element_text(hjust = 0.5))
Como se puede observar, existen varias compensaciones positivas para la empresa, son aquellos puntos que logran estar sobre los 3500000. Sin embargo, la volatilidad es mucho más alta, esto es bastante lógico debido a que se está expuesto al riesgo de mercado en la cotización de futuros de TRM. Sin embargo cabe recalcar que se trabajó con una serie muy volátil que da grandes saltos en la cotización y por ende los resultados que terminan afectando la liquidación y directamente el flujo de caja compensado.
La TRM continuará siendo una variable clave para el análisis económico en Colombia. Su comportamiento dependerá de una compleja interacción de factores internos y externos. Comprender sus determinantes permite anticipar movimientos, diseñar estrategias de cobertura y tomar decisiones de inversión informadas.
Se demostró de manera gráfica que con 2 contratos en el mercado de futuros de la Bolsa de Valores de Colombia, específicamente los contratos de TRX son suficientes y se podría analizar la posibilidad de solo utilizar un contrato debido al bajo monto de la cuota, si se quiere disminuir los picos observados en la última gráfica.
También se muestra que con una buena elección de las posiciones corta o larga en cada fecha de finalización y renovación, se logra evidenciar que en su mayoría los flujos compensan con mayor fuerza a disminuir el monto a pagar de la cuota en COP.
Se presentan unos flujos que en lugar de compensar a favor de la empresa, marcaron una mayor salida del efectivo. Esto se debe a que el futuro se liquidaba de forma mensual y entre los periodos semestrales, habían movimientos en donde podía prevalecer una tendencia al alza y en otros meses a la baja. En estos casos se debe de analizar cuales son las expectativas a corto plazo para tomar la mejor elección de acuerdo a una posición corta o larga. Ya que, la serie de la simulación al futuro es muy vólatil debido a la falta de datos que hace que existan cierto sesgo en los parámetros cálculados.
Por lo mismo, una recomendación para reforzar aún más las estimaciones y el término de simulación, es acceder a información de futuros con un histórico más amplio, recopilando más información de diferentes contratos y no uno solo como fue trabajado en este caso, lo cual permita estabilizar los parámetros de media y desviación.
Banco de la República de Colombia. (2025, enero). Informe de política monetaria – Enero de 2025. Recuperado de https://www.banrep.gov.co/es/informe-politica-monetaria-enero-2025. Consultado el 21 de mayo de 2025.
Banco de la República de Colombia. (2025, abril). Encuesta de expectativas de analistas económicos (EME) – Abril de 2025. Recuperado de https://www.banrep.gov.co/es/estadisticas/encuesta-mensual-expectativas. Consultado el 21 de mayo de 2025.
Banco de la República de Colombia. (2025, abril). Pronóstico económico para EME – Abril de 2025. Recuperado de https://www.banrep.gov.co/es/estadisticas/encuesta-mensual-expectativas. Consultado el 21 de mayo de 2025.
El País. (2025, mayo 15). El PIB de Colombia crece en el primer trimestre del año 2,7 % gracias al consumo privado. Recuperado de https://elpais.com/america-colombia/2025-05-15/el-pib-de-colombia-crece-en-el-primer-trimestre-del-ano-27-gracias-al-consumo-privado.html. Consultado el 21 de mayo de 2025.
Presidencia de la República de Colombia. (2025, mayo 6). Banco de la República prevé que el costo de vida seguirá cayendo y economía seguirá recuperándose: al cierre de 2025 inflación sería de 4,4% y el PIB de 2,6%. Recuperado de https://www.presidencia.gov.co/prensa/Paginas/Banco-de-la-Republica-preve-que-el-costo-de-vida-seguira-cayendo-y-economia-250506.aspx. Consultado el 21 de mayo de 2025.
Wells Fargo. (2025). Business Lines of Credit. Recuperado de https://www.wellsfargo.com/biz/business-credit/lines-of-credit/. Consultado el 21 de mayo de 2025.
U.S. Department of the Treasury. (2025). Daily Treasury Yield Curve Rates. Recuperado de https://home.treasury.gov/resource-center/data-chart-center/interest-rates/TextView?type=daily_treasury_yield_curve&field_tdr_date_value=2025. Consultado el 21 de mayo de 2025.
Banco de la República de Colombia. (2025). Tasas Cero Cupón TES – Deuda Pública. Recuperado de https://suameca.banrep.gov.co/estadisticas-economicas/#/informacionSerie/640001/Deuda%20p%C3%BAblica/Tasas%20Cero%20Cup%C3%B3n%20TES. Consultado el 21 de mayo de 2025.
Banco de la República. (2025). Encuesta Mensual de Expectativas (EME) - Abril 2025. Recuperado de https://www.banrep.gov.co
Bolsa de Valores de Colombia. (s.f.). Derivados: descripción general. https://www.bvc.com.co/derivados-descripcion-general
Departamento Administrativo Nacional de Estadística (DANE). (2025). Informe mensual de inflación - Abril 2025. Recuperado de https://www.dane.gov.co Federal Reserve. (2024). Monetary Policy Report – July 2024. Recuperado de https://www.federalreserve.gov
Ministerio de Hacienda y Crédito Público. (2025). Boletín Fiscal y de Proyecciones Macroeconómicas - Marzo 2025. Recuperado de https://www.minhacienda.gov.co
Dolar-Colombia. (2025). Gráfica del precio del dólar en Colombia – TRM histórica 2024–2025. Recuperado el 21 de mayo de 2025, de https://www.dolar-colombia.com/grafica
Wilkinson PC. (2025). Gráfica histórica del dólar – TRM Colombia. Recuperado el 21 de mayo de 2025, de https://dolar.wilkinsonpc.com.co/dolar-trm-graficas.html