################ This code uses cubic splines to interpolate the makam yields with time-varying maturities ###############
################ motivation: we need yields for specific maturities, to match the yields with the FX swap data ###############


library(readxl)
library(expm)
library(numDeriv)
library(tidyverse)

graphics.off()  # clear all graphs
rm(list = ls()) # remove all files from your workspace

### change data and working directory
### data directory
data.file.dir <- "C:/Users/Markus.Hertrich/OneDrive - htwsaar.de/Dokumente/Forschung/projects/Daniel Nathan FXI/makam.xlsx"
### working directory
data.file.dir1 <- "C:/Users/Markus.Hertrich/OneDrive - htwsaar.de/Dokumente/Forschung/projects/Daniel Nathan FXI"
setwd( data.file.dir1 )


### transform data to zoo series
### makam yield to maturity
data <- openxlsx::read.xlsx( data.file.dir, sheet = "yield sorted", startRow = 1, detectDates = TRUE, colNames = TRUE )
### remove first column, as it exists twice
data <- data[,-c(1,3, 5)]
memoDates <- data[,"DATE"]
### Convert to panel data frame
pdata <- pdata.frame( data, index = c("ID", "DATE"))


### Ensure 'value' is numeric
pdata$YIELD <- as.numeric(pdata$YIELD)
pdata$DURATION <- as.numeric(pdata$DURATION)
pdata$PRICE <- as.numeric(pdata$PRICE)
pdata_sorted <- pdata[order(pdata$DATE),]
df_day <- pdata_sorted

# Set your standard maturities
  # DURATION is measured in years: therefore, we have to divide by 12
      target_maturities <- c( 1/12, 3/12, 6/12, 1 )

# Interpolation function per date
interpolate_yields <- function(df_day, target_maturities) {
  spline(x = df_day$DURATION, y = df_day$YIELD, xout = target_maturities, method = "natural")$y
}

# Interpolate for all dates
df_interp <- df_day %>%
  group_by(DATE) %>%
  summarise(across(c(DURATION, YIELD), list), .groups = "drop") %>%
  mutate(
    # Extract the unique DURATION values for each date
    time_varying_maturities = map(DURATION, ~ sort(unique(.x))),
    # Combine the fixed maturities with the time-varying maturities
    combined_maturities = map(time_varying_maturities, ~ c(1/12, 3/12, 6/12, 1, .x)),
    # Perform the interpolation for the combined maturities
    yields_interp = pmap(list(DURATION, YIELD, combined_maturities), 
                         ~ spline(x = ..1, y = ..2, xout = ..3, method = "natural")$y)
  ) %>%
  select(DATE, yields_interp) %>%
  unnest_wider(yields_interp, names_sep = "_")  # Creates columns like yields_interp_1, _2, _3, ...

# Final yield matrix
yield_matrix <- as.matrix(df_interp[,-1])
maturities <- c(1/12, 3/12, 6/12, 1 )  # Fixed maturities
colnames(yield_matrix) <- c("1m", "3m", "6m", "1y", paste0("m", 1:12))  # Assuming up to 12 time-varying maturities

# Create zoo object with dates as the index
yield_matrix <- zoo(yield_matrix, order.by = df_interp$DATE)

# Write to Excel
  # Convert zoo object to a data.frame including the dates as a separate column
      df_yield_matrix <- data.frame( Date = index(yield_matrix), coredata(yield_matrix) )
openxlsx::write.xlsx( df_yield_matrix, file = "interpolate.xlsx" )
