1 1. Resumen

Objetivo del ejercicio. Financiar la compra de maquinaria amarilla por $350.000.000 COP mediante un crédito en EE. UU. y evaluar una cobertura con forward de divisas sobre el 75,00% del valor a partir del año 6.

Decisión metodológica. Se modela un crédito equivalente tipo francés en USD con pagos trimestrales a 10 años. Para la cobertura, se implementan 4 forwards anuales (años 6 a 9) y se aplica su tasa a 75% de las cuatro cuotas trimestrales de cada año cubierto. Esta aproximación se explicita porque el enunciado exige “4 forwards de 1 año”.

2 2. Contexto, fuente del crédito y supuestos

Bank of America publica que es SBA Preferred Lender y que el programa SBA 504 puede utilizarse para compra de equipos, incluyendo maquinaria de largo plazo, con cuota inicial típica del 10% y plazo de hasta 10 años para equipo (Bank of America 2026). A su vez, un referente público del mercado SBA 504 reportó una tasa fija efectiva de 5,61% para 10 años en marzo de 2026, con financiamiento de hasta 90% y baja cuota inicial (Growth Corp 2026b, 2026a).

Por ello, el informe adopta el siguiente supuesto pedagógico: se aproxima la estructura 504 real (banco + CDC) por un crédito equivalente único en USD, totalmente amortizable, con sistema francés y tasa efectiva anual de 5,61%.

tabla_supuestos <- tibble::tibble(
  supuesto = c(
    "Valor de la maquinaria",
    "Cuota inicial",
    "Monto financiado",
    "Plazo del crédito",
    "Pagos por año",
    "Sistema de amortización",
    "Tasa anual crédito en USD",
    "Cobertura forward sobre el crédito",
    "Inicio de cobertura",
    "Número de forwards anuales",
    "Tasa comercial USD para forward",
    "Tasa comercial COP para forward"
  ),
  valor = c(
    formatear_moneda_cop(params$monto_maquinaria_cop),
    formatear_porcentaje(params$porcentaje_cuota_inicial),
    formatear_porcentaje(1 - params$porcentaje_cuota_inicial),
    paste(params$plazo_anios_credito, "años"),
    params$pagos_por_anio,
    "Francés, cuotas trimestrales",
    formatear_porcentaje(params$tasa_credito_usd_anual),
    formatear_porcentaje(params$porcentaje_cobertura_forward),
    paste("Año", params$anio_inicio_cobertura),
    params$anios_cobertura,
    formatear_porcentaje(params$tasa_comercial_usa_anual),
    formatear_porcentaje(params$tasa_comercial_colombia_anual)
  )
)

knitr::kable(tabla_supuestos, col.names = c("Supuesto", "Valor"))
Supuesto Valor
Valor de la maquinaria $350.000.000 COP
Cuota inicial 10,00%
Monto financiado 90,00%
Plazo del crédito 10 años
Pagos por año 4
Sistema de amortización Francés, cuotas trimestrales
Tasa anual crédito en USD 5,61%
Cobertura forward sobre el crédito 75,00%
Inicio de cobertura Año 6
Número de forwards anuales 4
Tasa comercial USD para forward 6,75%
Tasa comercial COP para forward 11,22%

3 3. Análisis fundamental de la TRM

BBVA Research identifica que la tasa de cambio en Colombia sigue influida por la fortaleza global del dólar, las condiciones financieras internacionales, los precios de materias primas y, a nivel interno, por el déficit fiscal, la cuenta corriente y la percepción de riesgo país. En su escenario base, proyecta un tipo de cambio promedio cercano a COP 3.750 por dólar en 2026 y alrededor de COP 3.817 en 2027, con una trayectoria de depreciación gradual y alta volatilidad (BBVA Research 2026). Por su parte, el Banco de la República reporta una tasa de política monetaria de 10,25% vigente desde el 2 de febrero de 2026 (Banco de la República 2026). Esa combinación sugiere que el peso podría sostener episodios de volatilidad con sesgo depreciativo si se mantienen las tensiones externas e internas.

serie_spot_diaria <- obtener_serie_spot_usdcop(
  fecha_inicio = params$fecha_inicio_historica,
  precio_spot_manual_respaldo = params$precio_spot_manual_respaldo,
  semilla = params$semilla
) %>%
  dplyr::mutate(
    precio_spot = acotar_trm(
      precio_spot,
      trm_minima = params$trm_minima_simulada,
      trm_maxima = params$trm_maxima_simulada
    )
  )

serie_spot_mensual <- construir_serie_mensual(serie_spot_diaria)

precio_spot_actual <- dplyr::last(serie_spot_diaria$precio_spot)
fecha_spot_actual <- dplyr::last(serie_spot_diaria$fecha)

retornos_mensuales <- serie_spot_mensual %>%
  dplyr::mutate(retorno_log_mensual = c(NA_real_, diff(log(precio_spot)))) %>%
  dplyr::filter(!is.na(retorno_log_mensual))

media_mensual_retornos <- mean(retornos_mensuales$retorno_log_mensual)
desviacion_mensual_retornos <- sd(retornos_mensuales$retorno_log_mensual)
exceso_curtosis_retornos <- calcular_exceso_curtosis(retornos_mensuales$retorno_log_mensual)
grados_libertad_t <- estimar_grados_libertad_t(retornos_mensuales$retorno_log_mensual)

forward_teorico_anual_hoy <- precio_spot_actual * (
  (1 + params$tasa_comercial_colombia_anual) /
  (1 + params$tasa_comercial_usa_anual)
)

prima_forward_hoy <- forward_teorico_anual_hoy / precio_spot_actual - 1
tabla_variables_mercado <- tibble::tibble(
  variable = c(
    "Fecha del último spot descargado",
    "TRM / spot USD-COP usado en el proyecto",
    "Media mensual de retornos logarítmicos",
    "Desviación estándar mensual",
    "Exceso de curtosis muestral",
    "Grados de libertad estimados para T-Student",
    "Tasa comercial USD para forward",
    "Tasa comercial COP para forward",
    "Forward teórico anual hoy",
    "Prima forward teórica",
    "Fuente de datos"
  ),
  valor = c(
    as.character(fecha_spot_actual),
    formatear_moneda_cop(precio_spot_actual, 2),
    formatear_porcentaje(media_mensual_retornos, 4),
    formatear_porcentaje(desviacion_mensual_retornos, 4),
    round(exceso_curtosis_retornos, 4),
    round(grados_libertad_t, 2),
    formatear_porcentaje(params$tasa_comercial_usa_anual),
    formatear_porcentaje(params$tasa_comercial_colombia_anual),
    formatear_moneda_cop(forward_teorico_anual_hoy, 2),
    formatear_porcentaje(prima_forward_hoy),
    unique(serie_spot_diaria$fuente)
  )
)

knitr::kable(tabla_variables_mercado, col.names = c("Variable", "Valor"))
Variable Valor
Fecha del último spot descargado 2026-03-30
TRM / spot USD-COP usado en el proyecto $3.654,61 COP
Media mensual de retornos logarítmicos 0,0939%
Desviación estándar mensual 2,7996%
Exceso de curtosis muestral 3.9549
Grados de libertad estimados para T-Student 5.52
Tasa comercial USD para forward 6,75%
Tasa comercial COP para forward 11,22%
Forward teórico anual hoy $3.807,64 COP
Prima forward teórica 4,19%
Fuente de datos Yahoo Finance (USDCOP=X)
ggplot(serie_spot_diaria, aes(x = fecha, y = precio_spot)) +
  geom_line(linewidth = 0.7) +
  labs(
    title = "Serie histórica del USD/COP descargada automáticamente",
    subtitle = unique(serie_spot_diaria$fuente),
    x = "Fecha",
    y = "Pesos colombianos por dólar"
  ) +
  scale_y_continuous(labels = scales::label_number(big.mark = ".", decimal.mark = ","))

ggplot(retornos_mensuales, aes(x = retorno_log_mensual)) +
  geom_histogram(aes(y = after_stat(density)), bins = 35, alpha = 0.7) +
  stat_function(
    fun = dnorm,
    args = list(mean = media_mensual_retornos, sd = desviacion_mensual_retornos),
    linewidth = 1
  ) +
  labs(
    title = "Retornos logarítmicos mensuales del USD/COP",
    subtitle = "Se superpone una densidad normal con media y desviación muestral",
    x = "Retorno logarítmico mensual",
    y = "Densidad"
  ) +
  scale_x_continuous(labels = scales::percent_format(accuracy = 0.1, decimal.mark = ","))

4 4. Simulación del crédito de la maquinaria en USD

valor_maquinaria_cop <- params$monto_maquinaria_cop
valor_maquinaria_usd <- valor_maquinaria_cop / precio_spot_actual

cuota_inicial_usd <- valor_maquinaria_usd * params$porcentaje_cuota_inicial
monto_credito_usd <- valor_maquinaria_usd - cuota_inicial_usd

numero_cuotas <- params$plazo_anios_credito * params$pagos_por_anio
tasa_trimestral_credito_usd <- (1 + params$tasa_credito_usd_anual)^(1 / params$pagos_por_anio) - 1

tabla_credito_usd <- crear_tabla_amortizacion(
  monto = monto_credito_usd,
  tasa_periodica = tasa_trimestral_credito_usd,
  numero_periodos = numero_cuotas,
  fecha_inicio = Sys.Date(),
  frecuencia_meses = 12 / params$pagos_por_anio
) %>%
  dplyr::mutate(
    mes_pago = seq(3, by = 3, length.out = dplyr::n()),
    anio_credito = ceiling(numero_cuota / params$pagos_por_anio)
  )

cuota_trimestral_usd <- tabla_credito_usd$cuota_usd[1]

resumen_credito_usd <- tibble::tibble(
  concepto = c(
    "Valor maquinaria en USD",
    "Cuota inicial en USD",
    "Monto del crédito en USD",
    "Tasa trimestral efectiva",
    "Número de cuotas",
    "Cuota trimestral"
  ),
  valor = c(
    formatear_moneda_usd(valor_maquinaria_usd),
    formatear_moneda_usd(cuota_inicial_usd),
    formatear_moneda_usd(monto_credito_usd),
    formatear_porcentaje(tasa_trimestral_credito_usd),
    numero_cuotas,
    formatear_moneda_usd(cuota_trimestral_usd)
  )
)

knitr::kable(resumen_credito_usd, col.names = c("Concepto", "Valor"))
Concepto Valor
Valor maquinaria en USD USD 95,769.45
Cuota inicial en USD USD 9,576.95
Monto del crédito en USD USD 86,192.51
Tasa trimestral efectiva 1,37%
Número de cuotas 40
Cuota trimestral USD 2,815.29

5 6. Cálculo de retornos mensuales, desviación estándar y simulación MBG mensual

meses_simulados <- params$plazo_anios_credito * 12

matriz_rutas_normal <- simular_mbg(
  precio_inicial = precio_spot_actual,
  media_mensual = media_mensual_retornos,
  desviacion_mensual = desviacion_mensual_retornos,
  meses = meses_simulados,
  numero_rutas = params$numero_rutas,
  distribucion = "normal",
  grados_libertad = grados_libertad_t,
  semilla = params$semilla,
  trm_minima = params$trm_minima_simulada,
  trm_maxima = params$trm_maxima_simulada
)

matriz_rutas_t_student <- simular_mbg(
  precio_inicial = precio_spot_actual,
  media_mensual = media_mensual_retornos,
  desviacion_mensual = desviacion_mensual_retornos,
  meses = meses_simulados,
  numero_rutas = params$numero_rutas,
  distribucion = "t_student",
  grados_libertad = grados_libertad_t,
  semilla = params$semilla + 1,
  trm_minima = params$trm_minima_simulada,
  trm_maxima = params$trm_maxima_simulada
)

muestra_rutas <- dplyr::bind_rows(
  crear_muestra_rutas(matriz_rutas_normal, "Normal"),
  crear_muestra_rutas(matriz_rutas_t_student, "T-Student")
)

escenarios_trm_por_distribucion <- dplyr::bind_rows(
  construir_escenarios_trm(matriz_rutas_normal) %>% dplyr::mutate(distribucion = "Normal"),
  construir_escenarios_trm(matriz_rutas_t_student) %>% dplyr::mutate(distribucion = "T-Student")
)

escenarios_trm_largos <- escenarios_trm_por_distribucion %>%
  tidyr::pivot_longer(
    cols = c(trm_minima, trm_media, trm_maxima),
    names_to = "escenario",
    values_to = "trm"
  ) %>%
  dplyr::mutate(
    escenario = dplyr::recode(
      escenario,
      trm_minima = "TRM mínima",
      trm_media = "TRM media",
      trm_maxima = "TRM máxima"
    )
  )

escenarios_trm_consolidada <- construir_escenarios_trm(
  rbind(matriz_rutas_normal, matriz_rutas_t_student)
)

tabla_resumen_escenarios_trm <- tibble::tibble(
  escenario = c("TRM mínima", "TRM media", "TRM máxima"),
  trm_mes_0 = c(
    escenarios_trm_consolidada$trm_minima[1],
    escenarios_trm_consolidada$trm_media[1],
    escenarios_trm_consolidada$trm_maxima[1]
  ),
  trm_promedio_horizonte = c(
    mean(escenarios_trm_consolidada$trm_minima),
    mean(escenarios_trm_consolidada$trm_media),
    mean(escenarios_trm_consolidada$trm_maxima)
  ),
  trm_mes_final = c(
    dplyr::last(escenarios_trm_consolidada$trm_minima),
    dplyr::last(escenarios_trm_consolidada$trm_media),
    dplyr::last(escenarios_trm_consolidada$trm_maxima)
  )
)

knitr::kable(
  tabla_resumen_escenarios_trm %>%
    dplyr::mutate(
      trm_mes_0 = round(trm_mes_0, 2),
      trm_promedio_horizonte = round(trm_promedio_horizonte, 2),
      trm_mes_final = round(trm_mes_final, 2)
    ),
  col.names = c("Escenario", "TRM mes 0", "TRM promedio horizonte", "TRM mes final")
)
Escenario TRM mes 0 TRM promedio horizonte TRM mes final
TRM mínima 3655 2518 2500
TRM media 3655 3873 4020
TRM máxima 3655 4982 5000
tabla_retornos_mensuales <- retornos_mensuales %>%
  dplyr::transmute(
    fecha = fecha,
    precio_spot = precio_spot,
    retorno_log_mensual = retorno_log_mensual,
    retorno_simple_mensual = exp(retorno_log_mensual) - 1
  )

DT::datatable(
  tabla_retornos_mensuales %>%
    dplyr::mutate(
      precio_spot = round(precio_spot, 2),
      retorno_log_mensual = round(retorno_log_mensual, 5),
      retorno_simple_mensual = round(retorno_simple_mensual, 5)
    ),
  extensions = "Buttons",
  options = list(dom = "Bfrtip", buttons = c("copy", "csv", "excel"), pageLength = 10, scrollX = TRUE),
  rownames = FALSE
)
tabla_estadisticos_mensuales <- tibble::tibble(
  concepto = c(
    "Número de observaciones mensuales",
    "Media mensual de retornos logarítmicos",
    "Desviación estándar mensual",
    "Exceso de curtosis",
    "Grados de libertad estimados para T-Student",
    "TRM mínima permitida en simulación",
    "TRM máxima permitida en simulación"
  ),
  valor = c(
    nrow(retornos_mensuales),
    formatear_porcentaje(media_mensual_retornos, 4),
    formatear_porcentaje(desviacion_mensual_retornos, 4),
    round(exceso_curtosis_retornos, 4),
    round(grados_libertad_t, 2),
    formatear_moneda_cop(params$trm_minima_simulada, 0),
    formatear_moneda_cop(params$trm_maxima_simulada, 0)
  )
)

knitr::kable(tabla_estadisticos_mensuales, col.names = c("Concepto", "Valor"))
Concepto Valor
Número de observaciones mensuales 269
Media mensual de retornos logarítmicos 0,0939%
Desviación estándar mensual 2,7996%
Exceso de curtosis 3.9549
Grados de libertad estimados para T-Student 5.52
TRM mínima permitida en simulación $2.500 COP
TRM máxima permitida en simulación $5.000 COP
ggplot(retornos_mensuales, aes(x = fecha, y = retorno_log_mensual)) +
  geom_line(linewidth = 0.7) +
  geom_hline(yintercept = 0, linetype = "dashed")

ggplot(muestra_rutas, aes(x = mes, y = precio_spot, group = numero_ruta)) +
  geom_line(alpha = 0.15) +
  facet_wrap(~ distribucion) +
  labs(
    title = "Muestra de rutas simuladas de la TRM",
    subtitle = "Las trayectorias se acotan entre COP 2.500 y COP 5.000 por USD",
    x = "Mes",
    y = "TRM simulada (COP/USD)"
  ) +
  coord_cartesian(ylim = c(params$trm_minima_simulada, params$trm_maxima_simulada)) +
  scale_y_continuous(labels = scales::label_number(big.mark = ".", decimal.mark = ","))

ggplot(escenarios_trm_largos, aes(x = mes, y = trm, linetype = escenario)) +
  geom_line(linewidth = 1) +
  facet_wrap(~ distribucion) +
  labs(
    title = "TRM mínima, media y máxima de las simulaciones",
    subtitle = "Escenarios construidos sobre rutas acotadas entre COP 2.500 y COP 5.000",
    x = "Mes",
    y = "TRM simulada (COP/USD)",
    linetype = "Escenario"
  ) +
  coord_cartesian(ylim = c(params$trm_minima_simulada, params$trm_maxima_simulada)) +
  scale_y_continuous(labels = scales::label_number(big.mark = ".", decimal.mark = ","))

6 5. Recreación del crédito en pesos bajo TRM mínima, media y máxima

trm_minima_pagos <- extraer_trm_escenario_pagos(
  escenarios_trm_consolidada,
  tabla_credito_usd$mes_pago,
  "trm_minima"
)

trm_media_pagos <- extraer_trm_escenario_pagos(
  escenarios_trm_consolidada,
  tabla_credito_usd$mes_pago,
  "trm_media"
)

trm_maxima_pagos <- extraer_trm_escenario_pagos(
  escenarios_trm_consolidada,
  tabla_credito_usd$mes_pago,
  "trm_maxima"
)

tabla_credito_cop_trm_minima <- crear_tabla_credito_cop_escenario(
  tabla_credito_usd,
  trm_minima_pagos,
  "TRM mínima"
)

tabla_credito_cop_trm_media <- crear_tabla_credito_cop_escenario(
  tabla_credito_usd,
  trm_media_pagos,
  "TRM media"
)

tabla_credito_cop_trm_maxima <- crear_tabla_credito_cop_escenario(
  tabla_credito_usd,
  trm_maxima_pagos,
  "TRM máxima"
)


DT::datatable(
  tabla_credito_cop_trm_minima %>%
    dplyr::mutate(
      trm_escenario = round(trm_escenario, 2),
      saldo_inicial_cop = round(saldo_inicial_cop, 0),
      interes_cop = round(interes_cop, 0),
      abono_capital_cop = round(abono_capital_cop, 0),
      cuota_cop = round(cuota_cop, 0),
      saldo_final_cop = round(saldo_final_cop, 0)
    ) %>%
    dplyr::select(
      numero_cuota, fecha_pago, anio_credito, trm_escenario,
      saldo_inicial_cop, interes_cop, abono_capital_cop, cuota_cop, saldo_final_cop
    ),
  extensions = "Buttons",
  options = list(dom = "Bfrtip", buttons = c("copy", "csv", "excel"), pageLength = 10, scrollX = TRUE),
  rownames = FALSE,
  caption = "Tabla de amortización en COP con escenario de TRM mínima"
)
DT::datatable(
  tabla_credito_cop_trm_media %>%
    dplyr::mutate(
      trm_escenario = round(trm_escenario, 2),
      saldo_inicial_cop = round(saldo_inicial_cop, 0),
      interes_cop = round(interes_cop, 0),
      abono_capital_cop = round(abono_capital_cop, 0),
      cuota_cop = round(cuota_cop, 0),
      saldo_final_cop = round(saldo_final_cop, 0)
    ) %>%
    dplyr::select(
      numero_cuota, fecha_pago, anio_credito, trm_escenario,
      saldo_inicial_cop, interes_cop, abono_capital_cop, cuota_cop, saldo_final_cop
    ),
  extensions = "Buttons",
  options = list(dom = "Bfrtip", buttons = c("copy", "csv", "excel"), pageLength = 10, scrollX = TRUE),
  rownames = FALSE,
  caption = "Tabla de amortización en COP con escenario de TRM media"
)
DT::datatable(
  tabla_credito_cop_trm_maxima %>%
    dplyr::mutate(
      trm_escenario = round(trm_escenario, 2),
      saldo_inicial_cop = round(saldo_inicial_cop, 0),
      interes_cop = round(interes_cop, 0),
      abono_capital_cop = round(abono_capital_cop, 0),
      cuota_cop = round(cuota_cop, 0),
      saldo_final_cop = round(saldo_final_cop, 0)
    ) %>%
    dplyr::select(
      numero_cuota, fecha_pago, anio_credito, trm_escenario,
      saldo_inicial_cop, interes_cop, abono_capital_cop, cuota_cop, saldo_final_cop
    ),
  extensions = "Buttons",
  options = list(dom = "Bfrtip", buttons = c("copy", "csv", "excel"), pageLength = 10, scrollX = TRUE),
  rownames = FALSE,
  caption = "Tabla de amortización en COP con escenario de TRM máxima"
)

7 7. Proceso de forward de divisas

resultado_cobertura_normal <- aplicar_cobertura_forward(
  tabla_amortizacion = tabla_credito_usd,
  matriz_rutas_spot = matriz_rutas_normal,
  porcentaje_cobertura = params$porcentaje_cobertura_forward,
  anio_inicio_cobertura = params$anio_inicio_cobertura,
  anios_cobertura = params$anios_cobertura,
  tasa_usd_anual = params$tasa_comercial_usa_anual,
  tasa_cop_anual = params$tasa_comercial_colombia_anual
)

resultado_cobertura_t_student <- aplicar_cobertura_forward(
  tabla_amortizacion = tabla_credito_usd,
  matriz_rutas_spot = matriz_rutas_t_student,
  porcentaje_cobertura = params$porcentaje_cobertura_forward,
  anio_inicio_cobertura = params$anio_inicio_cobertura,
  anios_cobertura = params$anios_cobertura,
  tasa_usd_anual = params$tasa_comercial_usa_anual,
  tasa_cop_anual = params$tasa_comercial_colombia_anual
)

tabla_riesgo_total <- dplyr::bind_rows(
  resumir_riesgo_total(resultado_cobertura_normal$resumen_total_rutas, "Normal"),
  resumir_riesgo_total(resultado_cobertura_t_student$resumen_total_rutas, "T-Student")
)

8 8. Eventos en los que la inversión se ve protegida y cuándo no

tabla_proteccion_anual <- dplyr::bind_rows(
  resultado_cobertura_normal$resumen_anual %>% dplyr::mutate(distribucion = "Normal"),
  resultado_cobertura_t_student$resumen_anual %>% dplyr::mutate(distribucion = "T-Student")
) %>%
  dplyr::filter(cubierto) %>%
  dplyr::select(
    distribucion, anio_credito, probabilidad_proteccion,
    ahorro_medio_cop, costo_spot_medio_cop, costo_cubierto_medio_cop, tasa_forward_promedio
  )

DT::datatable(
  tabla_proteccion_anual %>%
    dplyr::mutate(
      probabilidad_proteccion = round(probabilidad_proteccion, 4),
      ahorro_medio_cop = round(ahorro_medio_cop, 0),
      costo_spot_medio_cop = round(costo_spot_medio_cop, 0),
      costo_cubierto_medio_cop = round(costo_cubierto_medio_cop, 0),
      tasa_forward_promedio = round(tasa_forward_promedio, 2)
    ),
  extensions = "Buttons",
  options = list(dom = "Bfrtip", buttons = c("copy", "csv", "excel"), pageLength = 8, scrollX = TRUE),
  rownames = FALSE
)

9 9. Comparación del flujo total: crédito sin cobertura vs crédito con forward

tabla_riesgo_total_formateada <- tabla_riesgo_total %>%
  dplyr::mutate(
    costo_esperado_sin_cobertura_cop = formatear_moneda_cop(costo_esperado_sin_cobertura_cop),
    costo_esperado_cubierto_cop = formatear_moneda_cop(costo_esperado_cubierto_cop),
    desviacion_sin_cobertura_cop = formatear_moneda_cop(desviacion_sin_cobertura_cop),
    desviacion_cubierto_cop = formatear_moneda_cop(desviacion_cubierto_cop),
    percentil_95_sin_cobertura_cop = formatear_moneda_cop(percentil_95_sin_cobertura_cop),
    percentil_95_cubierto_cop = formatear_moneda_cop(percentil_95_cubierto_cop),
    cvar_95_sin_cobertura_cop = formatear_moneda_cop(cvar_95_sin_cobertura_cop),
    cvar_95_cubierto_cop = formatear_moneda_cop(cvar_95_cubierto_cop),
    ahorro_promedio_total_cop = formatear_moneda_cop(ahorro_promedio_total_cop),
    probabilidad_proteccion = formatear_porcentaje(probabilidad_proteccion),
    reduccion_percentil_95 = formatear_porcentaje(reduccion_percentil_95),
    reduccion_cvar_95 = formatear_porcentaje(reduccion_cvar_95)
  )

knitr::kable(tabla_riesgo_total_formateada)
distribucion costo_esperado_sin_cobertura_cop costo_esperado_cubierto_cop desviacion_sin_cobertura_cop desviacion_cubierto_cop percentil_95_sin_cobertura_cop percentil_95_cubierto_cop cvar_95_sin_cobertura_cop cvar_95_cubierto_cop ahorro_promedio_total_cop probabilidad_proteccion reduccion_percentil_95 reduccion_cvar_95
Normal $437.543.309 COP $442.575.221 COP $63.669.061 COP $64.327.092 COP $535.632.915 COP $542.761.981 COP $543.592.851 COP $550.623.088 COP -$5.031.912 COP 8,30% -1,33% -1,29%
T-Student $435.805.149 COP $440.734.157 COP $63.105.140 COP $63.793.385 COP $534.613.941 COP $541.464.548 COP $543.350.161 COP $550.373.034 COP -$4.929.008 COP 9,05% -1,28% -1,29%

10 10. Conclusión y recomendación

fila_normal <- tabla_riesgo_total %>% dplyr::filter(distribucion == "Normal")
fila_t <- tabla_riesgo_total %>% dplyr::filter(distribucion == "T-Student")

beneficio_por_riesgo <- (fila_normal$reduccion_cvar_95 > 0) | (fila_t$reduccion_cvar_95 > 0)
beneficio_por_costo <- (fila_normal$ahorro_promedio_total_cop > 0) | (fila_t$ahorro_promedio_total_cop > 0)

if (beneficio_por_riesgo && beneficio_por_costo) {
  cat("**Conclusión principal:** la cobertura forward fue beneficiosa tanto como seguro cambiario como en flujo esperado.")
} else if (beneficio_por_riesgo && !beneficio_por_costo) {
  cat("**Conclusión principal:** la cobertura forward mejora la protección frente a escenarios extremos, aunque no siempre minimiza el costo promedio.")
} else if (!beneficio_por_riesgo && beneficio_por_costo) {
  cat("**Conclusión principal:** la cobertura mejora el costo promedio, pero no reduce suficientemente el riesgo extremo.")
} else {
  cat("**Conclusión principal:** con los supuestos y la muestra descargada, la cobertura forward no mejora de forma clara ni el costo promedio ni la cola de pérdidas.")
}

Conclusión principal: con los supuestos y la muestra descargada, la cobertura forward no mejora de forma clara ni el costo promedio ni la cola de pérdidas.

11 11. Exportación de tablas para anexos

Referencias

Banco de la República. 2026. “Informe de Política Monetaria – Enero de 2026.” 2026. https://www.banrep.gov.co/es/informe-de-politica-monetaria.
Bank of America. 2026. “What Is an SBA Loan and How Do i Qualify?” 2026. https://business.bankofamerica.com/en/resources/what-is-an-sba-loan.
BBVA Research. 2026. “Situación Colombia – Marzo 2026.” 2026. https://www.bbvaresearch.com/wp-content/uploads/2026/03/20260311_TextoSC_Marzo2026.pdf.
Growth Corp. 2026a. “Machinery & Equipment Financing.” 2026. https://www.growthcorp.com/equipment/.
———. 2026b. “SBA 504 Rate Pricing.” 2026. https://www.growthcorp.com/sba-504-rate-pricing/.