# Paquetes
library(readxl)
## Warning: package 'readxl' was built under R version 4.3.3
library(dplyr)
## Warning: package 'dplyr' was built under R version 4.3.3
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
library(ggplot2)
library(knitr)
library(scales)

options(scipen = 999)   # evitar notacion cientifica en tablas/graficos

# 0. PARÁMETROS GLOBALES

set.seed(123)              # reproducibilidad

# Parámetros del crédito en USD (AJUSTAR tasa con banco real)
tasa_ea_usd <- 0.065       # Tasa EA del crédito en dólares

# Tasas para forwards (AJUSTAR con tasas de referencia reales)
i_usa <- 0.05              # EA USA
i_col <- 0.12              # EA Colombia

# Parámetros de simulación
n_sim  <- 1000             # nº simulaciones
df_t   <- 3                # grados de libertad t-Student (colas pesadas)

# Datos de la inversión
monto_cop <- 350000000     # 350 millones COP
plazo_anos <- 10
n_trimestres <- plazo_anos * 4

########################################
# 1. TRM HISTÓRICA, RETORNOS Y ANÁLISIS BÁSICO
########################################

# Cargar TRM histórica (AJUSTAR RUTA)
trm_raw <- read_excel("C:/Analisis/trm.xlsx.xlsx")

trm <- trm_raw %>%
  mutate(
    Fecha = as.Date(Fecha),
    TRM   = as.numeric(TRM)
  ) %>%
  arrange(Fecha)

# Chequeo básico de la TRM
summary(trm$TRM)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max.    NA's 
##    1748    2361    3151    3137    3888    5061       3
# Gráfico de TRM histórica
ggplot(trm, aes(x = Fecha, y = TRM)) +
  geom_line(color = "steelblue") +
  theme_minimal() +
  labs(title = "TRM historica",
       x = "Fecha",
       y = "COP/USD")
## Warning: Removed 3 rows containing missing values or values outside the scale range
## (`geom_line()`).

# Cálculo de retornos diarios logarítmicos
trm <- trm %>%
  mutate(Retorno_d = log(TRM / lag(TRM))) %>%
  filter(!is.na(Retorno_d))

mu_d  <- mean(trm$Retorno_d)
sd_d  <- sd(trm$Retorno_d)
vol_anual <- sd_d * sqrt(252)

kable(data.frame(
  Metrica = c("Retorno diario medio", "Volatilidad diaria", "Volatilidad anual"),
  Valor   = c(mu_d, sd_d, vol_anual)
), digits = 6, caption = "Estadísticas básicas de la TRM (diarias)")
Estadísticas básicas de la TRM (diarias)
Metrica Valor
Retorno diario medio 0.000123
Volatilidad diaria 0.006220
Volatilidad anual 0.098739
# Histograma de retornos diarios
ggplot(trm, aes(x = Retorno_d)) +
  geom_histogram(bins = 50, color = "white", fill = "steelblue") +
  theme_minimal() +
  labs(title = "Distribucion de retornos diarios de la TRM",
       x = "Retorno diario logaritmico",
       y = "Frecuencia")

########################################
# 2. RETORNOS MENSUALES Y SIMULACIONES BMG
########################################

# Serie mensual: última TRM de cada mes
trm_mensual <- trm %>%
  mutate(Mes = format(Fecha, "%Y-%m")) %>%
  group_by(Mes) %>%
  summarise(TRM = last(TRM), .groups = "drop") %>%
  arrange(Mes) %>%
  mutate(Retorno_m = log(TRM / lag(TRM))) %>%
  filter(!is.na(Retorno_m))

mu_m <- mean(trm_mensual$Retorno_m)
sd_m <- sd(trm_mensual$Retorno_m)

kable(data.frame(
  Metrica = c("Retorno mensual medio", "Desviacion estandar mensual"),
  Valor   = c(mu_m, sd_m)
), digits = 6, caption = "Estadisticas de la TRM (mensuales)")
Estadisticas de la TRM (mensuales)
Metrica Valor
Retorno mensual medio 0.003716
Desviacion estandar mensual 0.037340
# Histograma de retornos mensuales
ggplot(trm_mensual, aes(x = Retorno_m)) +
  geom_histogram(bins = 30, color = "white", fill = "darkgreen") +
  theme_minimal() +
  labs(title = "Distribucion de retornos mensuales de la TRM",
       x = "Retorno mensual logaritmico",
       y = "Frecuencia")

# Parámetros simulación mensual
trm_hoy  <- tail(trm$TRM, 1)
n_meses  <- 12

# Simulación BMG con Normal
sim_normal <- matrix(NA, nrow = n_meses, ncol = n_sim)
for (j in 1:n_sim) {
  Z <- rnorm(n_meses)
  sim_normal[, j] <- trm_hoy * exp(cumsum((mu_m - 0.5 * sd_m^2) + sd_m * Z))
}

# Simulación BMG con t-Student (ajustada a varianza 1)
sim_t <- matrix(NA, nrow = n_meses, ncol = n_sim)
for (j in 1:n_sim) {
  Z_raw <- rt(n_meses, df = df_t)
  Z <- Z_raw / sqrt(df_t / (df_t - 2))  # ajuste de escala
  sim_t[, j] <- trm_hoy * exp(cumsum((mu_m - 0.5 * sd_m^2) + sd_m * Z))
}

# Gráfico de algunas trayectorias (Normal)
matplot(sim_normal[, 1:20], type = "l", lty = 1,
        col = alpha("blue", 0.4),
        main = "Simulacion TRM - BMG Normal (12 meses)",
        xlab = "Mes", ylab = "TRM (COP/USD)")

# Gráfico de algunas trayectorias (t-Student)
matplot(sim_t[, 1:20], type = "l", lty = 1,
        col = alpha("red", 0.4),
        main = "Simulacion TRM - BMG t-Student (12 meses)",
        xlab = "Mes", ylab = "TRM (COP/USD)")

# Percentiles (VaR / escenario) de TRM a 12 meses
trm_12m_normal <- sim_normal[n_meses, ]
trm_12m_t      <- sim_t[n_meses, ]

resumen_trm_12m <- data.frame(
  Modelo = c("Normal", "t-Student"),
  P5     = c(quantile(trm_12m_normal, 0.05),
             quantile(trm_12m_t,      0.05)),
  P50    = c(median(trm_12m_normal),
             median(trm_12m_t)),
  P95    = c(quantile(trm_12m_normal, 0.95),
             quantile(trm_12m_t,      0.95))
)

kable(resumen_trm_12m, digits = 2,
      caption = "TRM proyectada a 12 meses: percentiles 5%, 50% y 95%")
TRM proyectada a 12 meses: percentiles 5%, 50% y 95%
Modelo P5 P50 P95
Normal 3066.07 3811.95 4668.40
t-Student 3100.89 3794.59 4663.29
########################################
# 3. CRÉDITO EN USD (SISTEMA FRANCÉS, TRIMESTRAL, 10 AÑOS)
########################################

# Valor maquinaria en USD
monto_usd <- monto_cop / trm_hoy

# 10% de pago inicial
pago_inicial_usd <- 0.10 * monto_usd

# 90% financiado
credito_usd <- 0.90 * monto_usd

# Tasa trimestral equivalente
i_trimestral_usd <- (1 + tasa_ea_usd)^(1/4) - 1

# Cuota trimestral (sistema francés)
cuota_usd <- credito_usd * (i_trimestral_usd / (1 - (1 + i_trimestral_usd)^(-n_trimestres)))

resumen_credito <- data.frame(
  Concepto = c("Monto equivalente en USD (350M COP)",
               "Pago inicial 10% (USD)",
               "Monto financiado 90% (USD)",
               "Cuota trimestral (USD)",
               "Numero de cuotas (trimestres)",
               "Tasa EA USD",
               "Tasa trimestral USD"),
  Valor = c(monto_usd,
            pago_inicial_usd,
            credito_usd,
            cuota_usd,
            n_trimestres,
            tasa_ea_usd,
            i_trimestral_usd)
)

kable(resumen_credito, digits = 4, caption = "Resumen del credito en USD")
Resumen del credito en USD
Concepto Valor
Monto equivalente en USD (350M COP) 95396.7004
Pago inicial 10% (USD) 9539.6700
Monto financiado 90% (USD) 85857.0303
Cuota trimestral (USD) 2915.6425
Numero de cuotas (trimestres) 40.0000
Tasa EA USD 0.0650
Tasa trimestral USD 0.0159
# Tabla de amortización en USD
periodo       <- 1:n_trimestres
saldo_ini     <- numeric(n_trimestres)
interes       <- numeric(n_trimestres)
abono_capital <- numeric(n_trimestres)
saldo_fin     <- numeric(n_trimestres)

for (t in 1:n_trimestres) {
  if (t == 1) {
    saldo_ini[t] <- credito_usd
  } else {
    saldo_ini[t] <- saldo_fin[t - 1]
  }
  interes[t]       <- saldo_ini[t] * i_trimestral_usd
  abono_capital[t] <- cuota_usd - interes[t]
  saldo_fin[t]     <- saldo_ini[t] - abono_capital[t]
}

tabla_usd <- data.frame(
  Periodo      = periodo,
  Saldo_Inicio = saldo_ini,
  Interes      = interes,
  Abono        = abono_capital,
  Cuota        = rep(cuota_usd, n_trimestres),
  Saldo_Final  = saldo_fin
)

kable(rbind(head(tabla_usd, 5), tail(tabla_usd, 5)),
      digits = 2,
      caption = "Tabla de amortización del crédito en USD (primeros y últimos periodos)")
Tabla de amortización del crédito en USD (primeros y últimos periodos)
Periodo Saldo_Inicio Interes Abono Cuota Saldo_Final
1 1 85857.03 1362.40 1553.24 2915.64 84303.79
2 2 84303.79 1337.76 1577.89 2915.64 82725.91
3 3 82725.91 1312.72 1602.92 2915.64 81122.98
4 4 81122.98 1287.28 1628.36 2915.64 79494.62
5 5 79494.62 1261.44 1654.20 2915.64 77840.42
36 36 13909.12 220.71 2694.93 2915.64 11214.19
37 37 11214.19 177.95 2737.69 2915.64 8476.50
38 38 8476.50 134.51 2781.13 2915.64 5695.37
39 39 5695.37 90.38 2825.27 2915.64 2870.10
40 40 2870.10 45.54 2870.10 2915.64 0.00
########################################
# 4. CRÉDITO RECREADO EN COP (SIN COBERTURA)
########################################

# A partir de retornos mensuales, pasamos a trimestrales
mu_t <- 3 * mu_m           # retorno esperado trimestral
sd_t <- sd_m * sqrt(3)     # desviación estándar trimestral

n_sim_tri <- n_sim
sim_trm_tri <- matrix(NA, nrow = n_trimestres, ncol = n_sim_tri)

for (j in 1:n_sim_tri) {
  Z <- rnorm(n_trimestres)
  sim_trm_tri[, j] <- trm_hoy * exp(cumsum((mu_t - 0.5 * sd_t^2) + sd_t * Z))
}

# TRM esperada por trimestre (promedio de las simulaciones)
trm_proj_mean <- rowMeans(sim_trm_tri)

# Flujo en COP sin cobertura (cuota USD * TRM esperada)
flujo_cop_sin <- cuota_usd * trm_proj_mean

tabla_cop <- data.frame(
  Periodo           = 1:n_trimestres,
  TRM_Esperada      = trm_proj_mean,
  Cuota_USD         = cuota_usd,
  Cuota_COP_sin_cob = flujo_cop_sin
)

kable(rbind(head(tabla_cop, 5), tail(tabla_cop, 5)),
      digits = 2,
      caption = "Cuotas del credito en COP sin cobertura (primeros y ultimos periodos)")
Cuotas del credito en COP sin cobertura (primeros y ultimos periodos)
Periodo TRM_Esperada Cuota_USD Cuota_COP_sin_cob
1 1 3718.32 2915.64 10841279
2 2 3754.51 2915.64 10946810
3 3 3790.93 2915.64 11052987
4 4 3836.65 2915.64 11186289
5 5 3882.72 2915.64 11320636
36 36 5573.17 2915.64 16249358
37 37 5647.22 2915.64 16465275
38 38 5712.11 2915.64 16654467
39 39 5793.87 2915.64 16892852
40 40 5857.24 2915.64 17077623
########################################
# 5. FORWARD DE DIVISAS (75% DESDE AÑO 6, 4 FORWARDS DE 1 AÑO)
########################################

# Forwards de 1 año para años 6, 7, 8 y 9
anos_fwd <- 6:9
S0 <- trm_hoy

F_anos <- S0 * ((1 + i_col) / (1 + i_usa))^anos_fwd

tabla_forward <- data.frame(
  Anio    = anos_fwd,
  Forward = F_anos
)

kable(tabla_forward, digits = 2,
      caption = "Forwards anuales implicitos (a partir de hoy)")
Forwards anuales implicitos (a partir de hoy)
Anio Forward
6 5403.90
7 5764.16
8 6148.43
9 6558.33
# Función: trimestre -> año
anio_desde_trimestre <- function(t) {
  ceiling(t / 4)   # cada 4 trimestres = 1 año
}

# Cobertura 75% de la cuota desde año 6 a 9
pct_cobertura <- 0.75
cuota_cubierta_usd    <- pct_cobertura * cuota_usd
cuota_descubierta_usd <- (1 - pct_cobertura) * cuota_usd

flujo_cop_con <- numeric(n_trimestres)

for (t in 1:n_trimestres) {
  anio_t <- anio_desde_trimestre(t)
  
  if (anio_t < 6 || anio_t > 9) {
    # Sin cobertura
    flujo_cop_con[t] <- cuota_usd * trm_proj_mean[t]
  } else {
    # Cobertura 75% con forward
    F_t <- F_anos[which(anos_fwd == anio_t)]
    flujo_cop_con[t] <-
      cuota_cubierta_usd    * F_t +
      cuota_descubierta_usd * trm_proj_mean[t]
  }
}

tabla_cop$Cuota_COP_con_cob <- flujo_cop_con
tabla_cop$Impacto_cobertura <- tabla_cop$Cuota_COP_sin_cob - tabla_cop$Cuota_COP_con_cob

kable(rbind(head(tabla_cop, 5), tail(tabla_cop, 5)),
      digits = 2,
      caption = "Flujos en COP con y sin cobertura (primeros y ultimos periodos)")
Flujos en COP con y sin cobertura (primeros y ultimos periodos)
Periodo TRM_Esperada Cuota_USD Cuota_COP_sin_cob Cuota_COP_con_cob Impacto_cobertura
1 1 3718.32 2915.64 10841279 10841279 0
2 2 3754.51 2915.64 10946810 10946810 0
3 3 3790.93 2915.64 11052987 11052987 0
4 4 3836.65 2915.64 11186289 11186289 0
5 5 3882.72 2915.64 11320636 11320636 0
36 36 5573.17 2915.64 16249358 18403646 -2154288
37 37 5647.22 2915.64 16465275 16465275 0
38 38 5712.11 2915.64 16654467 16654467 0
39 39 5793.87 2915.64 16892852 16892852 0
40 40 5857.24 2915.64 17077623 17077623 0
########################################
# 6. COMPARACIÓN, RIESGO Y MÉTRICAS ADICIONALES
########################################

# Comparación gráfica
plot(tabla_cop$Periodo, tabla_cop$Cuota_COP_sin_cob, type = "l", lwd = 2,
     col = "blue", xlab = "Periodo (trimestre)", ylab = "Cuota en COP",
     main = "Credito en COP: con y sin cobertura cambiaria")

lines(tabla_cop$Periodo, tabla_cop$Cuota_COP_con_cob,
      lwd = 2, col = "red", lty = 2)

abline(v = 5*4 + 0.5, lty = 3, col = "darkgray")  # inicio aprox. año 6

legend("topright",
       legend = c("Sin cobertura", "Con cobertura (75% desde ano 6)"),
       col = c("blue", "red"),
       lty = c(1, 2), lwd = 2, bty = "n")

# Volatilidad de las cuotas en COP
sd_sin <- sd(tabla_cop$Cuota_COP_sin_cob)
sd_con <- sd(tabla_cop$Cuota_COP_con_cob)

sd_sin_rel <- sd_sin / mean(tabla_cop$Cuota_COP_sin_cob)
sd_con_rel <- sd_con / mean(tabla_cop$Cuota_COP_con_cob)

kable(data.frame(
  Escenario        = c("Sin cobertura", "Con cobertura"),
  Vol_abs          = c(sd_sin, sd_con),
  Vol_rel_porcent  = c(sd_sin_rel, sd_con_rel) * 100
), digits = 2,
caption = "Volatilidad absoluta y relativa de las cuotas en COP")
Volatilidad absoluta y relativa de las cuotas en COP
Escenario Vol_abs Vol_rel_porcent
Sin cobertura 1882199 13.64
Con cobertura 2530855 17.46
# Costo total nominal y VPN en COP
total_sin <- sum(tabla_cop$Cuota_COP_sin_cob)
total_con <- sum(tabla_cop$Cuota_COP_con_cob)

i_tri_col <- (1 + i_col)^(1/4) - 1   # tasa trimestral en COP para descuento

vpn_sin <- sum(tabla_cop$Cuota_COP_sin_cob / (1 + i_tri_col)^(tabla_cop$Periodo))
vpn_con <- sum(tabla_cop$Cuota_COP_con_cob / (1 + i_tri_col)^(tabla_cop$Periodo))

kable(data.frame(
  Escenario = c("Sin cobertura", "Con cobertura"),
  Total_COP = c(total_sin, total_con),
  VPN_COP   = c(vpn_sin, vpn_con)
), digits = 2,
caption = "Costo total y VPN del credito en COP (con y sin cobertura)")
Costo total y VPN del credito en COP (con y sin cobertura)
Escenario Total_COP VPN_COP
Sin cobertura 552042539 311635936
Con cobertura 579928564 323851278
# (OPCIONAL) Simulación completa de ahorro por cobertura
total_sin_sim <- numeric(n_sim_tri)
total_con_sim <- numeric(n_sim_tri)

for (j in 1:n_sim_tri) {
  trm_path <- sim_trm_tri[, j]
  
  # Sin cobertura
  sin_j <- cuota_usd * trm_path
  
  # Con cobertura
  con_j <- numeric(n_trimestres)
  for (t in 1:n_trimestres) {
    anio_t <- anio_desde_trimestre(t)
    if (anio_t < 6 || anio_t > 9) {
      con_j[t] <- cuota_usd * trm_path[t]
    } else {
      F_t <- F_anos[which(anos_fwd == anio_t)]
      con_j[t] <-
        cuota_cubierta_usd    * F_t +
        cuota_descubierta_usd * trm_path[t]
    }
  }
  total_sin_sim[j] <- sum(sin_j)
  total_con_sim[j] <- sum(con_j)
}

ahorro_sim <- total_sin_sim - total_con_sim

prob_ahorro  <- mean(ahorro_sim > 0)
ahorro_medio <- mean(ahorro_sim)
ahorro_p5    <- quantile(ahorro_sim, 0.05)
ahorro_p95   <- quantile(ahorro_sim, 0.95)

kable(data.frame(
  Prob_ahorro  = prob_ahorro,
  Ahorro_medio = ahorro_medio,
  Ahorro_P5    = ahorro_p5,
  Ahorro_P95   = ahorro_p95
), digits = 2,
caption = "Distribucion del ahorro por cobertura (simulaciones)")
Distribucion del ahorro por cobertura (simulaciones)
Prob_ahorro Ahorro_medio Ahorro_P5 Ahorro_P95
5% 0.28 -27886025 -105987845 78552244