Iteration

This manual serves two main purposes: to implement financial risk models and to establish routines for process automation.

VaR model

In this first section, I will address constructing a VaR and CVaR model.

Create dates without holidays

# Define a calendar with no holidays
cal <- create.calendar("MyCalendar", weekdays = c("saturday", "sunday"))

# Create a sequence of working days
start_date   <- as.Date("2023-09-28")
end_date     <- as.Date("2024-10-02")
working_days <- seq(start_date, end_date, by = "day")

# Filter only business days
working_days <- working_days[is.bizday(working_days, cal)]

Convert to an xts object

indice_I <- xts(indice[, -1], order.by = indice$Fecha)

return_a <-  CalculateReturns(indice_I, method="log")

Graph

hc <- highchart() %>%
      hc_title(text = "Retorno") %>%
      hc_xAxis(type = "datetime", title = "Fecha") %>%
      hc_yAxis(title = "Retornos") %>%
      hc_add_series(data = return_a, type = "line", name = "Retorno", color = "#0B3040") %>%
      hc_tooltip(formatter = JS("function() {
        return '<b>Date:</b> ' + Highcharts.dateFormat('%Y-%m-%d', this.x) + 
               '<br><b>Retorno:</b> ' + Highcharts.numberFormat(this.y, 6);
      }"))

hc

Results

VaR

  • sapply: The sapply function iterates through each element in a vector, applying another function to each element in the vector and returning the results.
calculate_VaR <- function(return_a, confidence_level = 0.95) {
  sapply(c("gaussian", "historical", "modified"), function(method) {
    VaR(return_a, p = confidence_level, method = method)
  })
}

VaR_results <- calculate_VaR(return_a)

Transform to tables the results with thew following code

tabla <- as.data.frame(print(VaR_results))
##     gaussian   historical     modified 
## -0.001348161 -0.001247548 -0.001296809
tabla_A <-  rownames_to_column(tabla, var = "Modelos")%>% 
            as_tibble()%>%
            rename(Resultados=2)%>%
            mutate("Porcentajes[%]"=round(Resultados*100,2),
                   Portafolio = 210000000,
                   VaR=Portafolio*`Porcentajes[%]`,
                   VaR_Mensual=Portafolio*`Porcentajes[%]`*20)
Modelos Resultados Porcentajes[%] Portafolio VaR VaR_Mensual
gaussian -0.0013482 -0.13 2.1e+08 -27300000 -5.46e+08
historical -0.0012475 -0.12 2.1e+08 -25200000 -5.04e+08
modified -0.0012968 -0.13 2.1e+08 -27300000 -5.46e+08

CVaR

calculate_CVaR <- function(return_a, confidence_level = 0.95) {
  sapply(c("gaussian", "historical", "modified"), function(method) {
    ETL(return_a, p = confidence_level, method = method)
  })
}

CVaR_results <- calculate_CVaR(return_a)

Iteration of function

In this section, I will present the main custom formulas for iteration.

Formula 1

Lista_Prueba_A <- Lista_Prueba %>%
  map(function(df) {
    # Calculate 'a' and 'ain' for each data frame
    a   <- length(df$Saldos) / nun
    ain <- length(df$Saldos) - (trunc(a) * nun) + 1
    
    # Subset the data frame from 'ain' to the end
    df <- df[ain:nrow(df), ]
    
    # Add the 'BoM' column using the calculated 'a' and 'nun'
    df <- df %>%
          mutate(BoM = rep(seq(1:trunc(a)), each = nun, length.out = nrow(df)))
    
    return(df)  # Return the modified data frame
  })

Formula 2

  • Lista_Prueba_BoM: It is a list
Lista_Prueba_VaRBoM <- Lista_Prueba_BoM %>%
                       map(function(df) {
                                         quantile(df$SUMBoM, p, na.rm = TRUE)})

Formula 3

calculate_TABoM <- function(df) {
  # Calculate VaRBoM using quantile
  VaRBoM <- quantile(df$SUMBoM, p, na.rm = TRUE)
  
  # Create TABoM data frame with the desired metrics
  TABoM <- data.frame(
    NB = nrow(df),  # Count of rows
    MedB = median(df$SUMBoM, na.rm = TRUE),  # Median of SUMBoM
    VoltB = sd(df$SUMBoM, na.rm = TRUE),  # Standard deviation (Volatility) of SUMBoM
    VaRB = VaRBoM[[2]],  # 99% VaR
    CVaRB = mean(df$SUMBoM[df$SUMBoM <= VaRBoM[[2]]], na.rm = TRUE)  # Conditional VaR (99%)
  )
  
  return(TABoM)  # Return the result
}

Lista_TABoM <-  Lista_Prueba_BoM %>%
                map(~ calculate_TABoM(.x))

Formula 4

distributions <- c("logis", "unif", "norm", "exp", "gamma", "lnorm")

# Fit distributions for each data frame in the list
fitted_models <- lapply(Lista_Prueba_BoM_AA, function(data_frame) {
  # Check if the data frame contains the 'TSUMBomb' column
  if ("TSUMBoM" %in% colnames(data_frame)) {
    lapply(distributions, function(dist) {
      fitdist(data = data_frame$TSUMBoM, distr = dist, method = "mme")
    })
  } else {
    warning("Column 'TSUMBoM' not found in one of the data frames.")
    return(NULL)  # Return NULL if the column is not found
  }
})

Formula 5

emv0  <- lapply(fitted_models, function(model_list) {
  if (!is.null(model_list[[5]])) {
    model_list[[5]][["estimate"]]  # Extract estimates from the fifth model
  } else {
    return(NA)  # Return NA if the model is NULL
  }
})

ygen0 <- lapply(emv0, function(x) rgamma(n = 50000, 
                                         shape = x[1], rate = x[2]))

Formula 6

p=0.01 # 99%

results <- list()

for (i in seq_along(Xgen0)) {
  result <- matrix(nrow = 6, ncol = 5)
  for (j in 0:5) {
    result[j + 1, 1] <- p
    result[j + 1, 2] <- round(median(Xgen0[[i]]$TSUMBoM, na.rm = TRUE), digits = 2)
    result[j + 1, 3] <- round(sd(Xgen0[[i]]$TSUMBoM, na.rm = TRUE), digits = 2)
    result[j + 1, 4] <- round(quantile(Xgen0[[i]]$TSUMBoM, p, na.rm = TRUE), digits = 2)
    result[j + 1 ,5] <- round(mean(Xgen0[[i]]$TSUMBoM[Xgen0[[i]]$TSUMBoM<=result[j+1,4]]), 
                              digits = 2)
    p <- 2.5 * j / 100
  }
  results[[i]] <- result
}

TABoMSIM <-  lapply(results, data.frame)   %>%
             map(~dplyr::filter(.x,X1>0))
                
TABoMSIM_A <- lapply(TABoMSIM, function(df) {
              colnames(df) <- c("Prob(%)","Mediana","Volatilidad","VaR","CVaR")
              return(df)})