R Markdown

# Define parameters
r0 <- 0.05  # initial short rate
n <- 10     # number of tenors
T <- 1      # time horizon
dt <- 0.1   # time step
m <- 1000   # number of simulations

# Generate correlated random numbers
set.seed(123)
corr_matrix <- matrix(c(1, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5,
                        0.5, 1, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5,
                        0.5, 0.5, 1, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5,
                        0.5, 0.5, 0.5, 1, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5,
                        0.5, 0.5, 0.5, 0.5, 1, 0.5, 0.5, 0.5, 0.5, 0.5,
                        0.5, 0.5, 0.5, 0.5, 0.5, 1, 0.5, 0.5, 0.5, 0.5,
                        0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 1, 0.5, 0.5, 0.5,
                        0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 1, 0.5, 0.5,
                        0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 1, 0.5,
                        0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 1),
                      ncol=n, byrow=T)
e <- matrix(rnorm(n*m), ncol=n) %*% chol(corr_matrix)

# Define the LMM function
LIBOR_Market_Model <- function(r0, n, T, dt, e) {
  r <- matrix(NA, nrow=m, ncol=n+1)
  r[,1] <- r0
  for (i in 1:n) {
    r[,i+1] <- r[,i] + 0.1 * (0.05 - r[,i]) * dt + 0.1 * e[,i] * sqrt(dt)
  }
  return(r)
}

# Run the model
r_LMM <- LIBOR_Market_Model(r0, n, T, dt, e)

# Define parameters
r0 <- 0.05  # initial short rate
theta <- 0.05  # long-term rate
k <- 0.1   # speed of reversion
sigma <- 0.01  # volatility
T <- 1      # time horizon
dt <- 0.1   # time step
m <- 1000   # number of simulations

# Define the Hull-White Model function
Hull_White_Model <- function(r0, theta, k, sigma, T, dt, m) {
  r <- matrix(NA, nrow=m, ncol=11)
  r[,1] <- r0
  for (i in 1:10) {
    t <- i * dt
    A <- (1 - exp(-k*(T-t))) / (k*(T-t))
    B <- (sigma^2 / (2*k^2)) * (1 - exp(-2*k*(T-t))) / (2*k*(T-t))
    r[,i+1] <- theta + (r[,i]-theta) * exp(-k*(T-t)) + A * (r0-theta) + B * rnorm(m)
  }
  return(r)
}

# Run the model
r_Hull_white <- Hull_White_Model(r0, theta, k, sigma, T, dt, m)

# Define inputs
WAC <- 0.05  # weighted average coupon rate
WAM <- 360  # weighted average maturity
PSA <- 100  # PSA prepayment benchmark
r <- 0.03  # discount rate
n <- 360  # number of monthly payments
P0 <- 1000000  # initial pool balance

# Calculate monthly interest rate
r_monthly <- r / 12

# Define function to calculate CPR based on PSA benchmark
calculate_CPR <- function(month) {
  if (month <= 30) {
    CPR <- PSA / 100 / 12
  } else if (month <= 60) {
    CPR <- 2 * PSA / 100 / 12
  } else if (month <= 120) {
    CPR <- 3 * PSA / 100 / 12
  } else if (month <= 240) {
    CPR <- 6 * PSA / 100 / 12
  } else if (month <= 360) {
    CPR <- 9 * PSA / 100 / 12
  } else {
    CPR <- 0
  }
  return(CPR)
}

# Define function to calculate monthly cash flow
calculate_cashflow <- function(month, balance, WAC, CPR) {
  interest_payment <- balance * r_monthly
  principal_payment <- balance * (WAC / 12 - r_monthly) / (1 - (1 + r_monthly)^(-n + month))
  prepayment <- balance * CPR
  cashflow <- interest_payment + principal_payment + prepayment
  return(cashflow)
}

# Calculate monthly cash flows and present value of cash flows
cashflows <- numeric(n)
discount_factors <- numeric(n)
for (month in 1:n) {
  CPR <- calculate_CPR(month)
  cashflows[month] <- calculate_cashflow(month, P0, WAC, CPR)
  discount_factors[month] <- (1 + r_monthly)^(-month)
}
PV <- sum(cashflows * discount_factors)

# Print the present value of the MBS
cat("Present Value of MBS:", round(PV, 2))
## Present Value of MBS: Inf

Note that the echo = FALSE parameter was added to the code chunk to prevent printing of the R code that generated the plot.