# Clear environment and set working directory
rm(list = ls())
setwd(dirname(rstudioapi::getActiveDocumentContext()$path))

# Load necessary package
listofpackages <- c("ggplot2")
for (j in listofpackages) {
  if (sum(installed.packages()[, 1] == j) == 0) {
    install.packages(j)
  }
  library(j, character.only = TRUE)
}

# Function to calculate bond price given Y, C, and time to maturity
calculate_price <- function(Y, C) {
  T <- 10
  price <- sum(C[1:(T-1)] / (1 + Y)^(1:(T-1))) + C[T] / (1 + Y)^T
  return(price)
}

# Function to find the yield to maturity given P and C
find_yield_to_maturity <- function(P, C) {
  # Increase precision by setting a lower tolerance
  opt <- optimize(function(Y) abs(calculate_price(Y, C) - P), interval = c(0, 1), tol = 1e-12)
  return(opt$minimum)
}

# Input data: cash flows and a range of bond prices
C <- c(2, 2, 2, 2, 2, 2, 2, 2, 2, 102)
P<-80
Y_t_t10_BTP <- find_yield_to_maturity(P, C)
# Display results
cat("The yield to maturity Y_{t,t+10}^{BTP} is:", Y_t_t10_BTP, "\n")

price_range <- seq(80, 120, by = 1)  # Define a range of prices

# Calculate yield to maturity for each price
yield_data <- data.frame(
  Price = price_range,
  Yield = sapply(price_range, find_yield_to_maturity, C = C)
)

# Plot yield as a function of bond price
ggplot(yield_data, aes(x = Price, y = Yield)) +
  geom_line(color = "blue", size = 1) +
  geom_point(color = "red", size = 1.5) +
  labs(
    title = "Yield to Maturity vs Bond Price",
    x = "Bond Price",
    y = "Yield to Maturity"
  ) +
  theme_minimal() +
  theme(
    plot.title = element_text(hjust = 0.5, size = 14, face = "bold"),
    axis.title = element_text(size = 12),
    axis.text = element_text(size = 10)
  )
##########################
### INDEXED BONDS 
###########################


# Define the function to calculate the price of an indexed bond given a yield Y, coupons C, and inflation rates pi
calculate_indexed_price <- function(Y, C, pi) {
  T <- length(C)  # Maturity in periods
  price <- 0  # Initialize bond price
  
  # Calculate each term in the bond pricing formula
  for (t in 1:T) {
    # Inflation adjustment for coupon payment in the current period
    coupon_adjustment <- C[t] * (1 + pi[t])
    
    # Inflation adjustment for the principal at the end of the current period
    inflation_adjustment <- prod(1 + pi[1:t])
    previous_inflation_adjustment <- ifelse(t == 1, 1, prod(1 + pi[1:(t-1)]))
    
    # Calculate the term based on the inflation-adjusted coupon and principal
    term <- (coupon_adjustment + (inflation_adjustment - previous_inflation_adjustment)*100) / (1 + Y)^t
    price <- price + term
  }
  
  # Final principal repayment term
  price <- price + (100  / (1 + Y)^T)
  
  return(price)
}

# Define a function to find the yield to maturity Y for a given price P, C, and pi
find_indexed_yield_to_maturity <- function(P, C, pi) {
  opt <- optimize(function(Y) abs(calculate_indexed_price(Y, C, pi) - P), interval = c(0, 1))
  return(opt$minimum)
}

# Input data: sequence of ten cash flows C and corresponding inflation rates
C <- rep(5, 10)  # Example cash flows (e.g., 5 each period)
pi <- c(0.02, 0.02, 0.02, 0.02, 0.02, 0.02, 0.02, 0.02, 0.02, 0.02)  # Example inflation rates for each period
P <- 100  # Example bond price

# Calculate the bond price and yield to maturity
bond_price <- calculate_indexed_price(0.03, C, pi)  # Assume initial Y for price calculation
Y_t_t10_BTPi <- find_indexed_yield_to_maturity(P, C, pi)

# Display results
cat("The indexed bond price is:", bond_price, "\n")
cat("The yield to maturity Y_{t,t+10}^{BTPi} is:", Y_t_t10_BTPi, "\n")



# Input data: cash flows
C <- rep(5, 10)  # Example cash flows (e.g., 5 each period)

# Define different inflation scenarios
inflation_scenarios <- list(
  scenario1 = c(0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00),
  scenario2 = c(0.02, 0.02, 0.02, 0.02, 0.02, 0.02, 0.02, 0.02, 0.02, 0.02),  # Constant 2%
  scenario3 = c(0.03, 0.03, 0.03, 0.03, 0.03, 0.03, 0.03, 0.03, 0.03, 0.03),  # Mixed rates
  scenario4 = c(0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04),  # Higher inflation
  scenario5 = c(0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05)   # Moderate inflation
)

# Initialize results data frame
results <- data.frame(Average_Inflation = numeric(), Yield = numeric())

# Calculate yields for each inflation scenario
for (scenario in names(inflation_scenarios)) {
  pi <- inflation_scenarios[[scenario]]
  avg_inflation <- mean(pi)
  yield <- find_indexed_yield_to_maturity(100, C, pi)  # Price is assumed to be 100
  results <- rbind(results, data.frame(Average_Inflation = avg_inflation, Yield = yield))
}

# Plot the results using ggplot2
ggplot(results, aes(x = Average_Inflation, y = Yield)) +
  geom_line(color = "blue", size = 1.2) +
  geom_point(size = 3) +
  labs(title = "Yield to Maturity as a Function of Average Inflation",
       x = "Average Inflation (%)",
       y = "Yield to Maturity (%)") +
  theme_minimal() +
  theme(plot.title = element_text(hjust = 0.5, size = 16),
        axis.title.x = element_text(size = 14),
        axis.title.y = element_text(size = 14))