3 FI & FX
3.1 Fixed Income
3.1.1 Bond Calculator in R
3.1.1.1 Calculate Forward Rates
Calculate Forward Rates
Create a table with bond (or import real ones) and calculate forward rates.
library(dplyr)
#Calculate Forward rate
#Create a table with plain vanilla bonds
df <- tribble(
~bond, ~maturity, ~yield,
1, 1.5, 1.65,
2, 3, 1.55,
3, 5, 1.8,
4, 10, 1.9
)
#Create table with all bonds in columns for short vs long bond
df <- df %>%
mutate(dummy = 1L) %>%
inner_join(., ., by = "dummy", suffix=c("_short", "_long")) %>%
select(-dummy) %>%
filter(bond_short < bond_long)
#Create column with maturity for length between bonds (not neccesary for below calculation)
df <- mutate(df, maturity_between_bonds = (maturity_long - maturity_short))
day_count <- 360
#Create function for calculating frw rate
calculate_forward_rate <- function(maturity_short, yield_short, maturity_long, yield_long, day_count){
short_bond <- (1+yield_short/100)^(maturity_short/day_count)
long_bond <- (1+yield_long/100)^(maturity_long/day_count)
days_between <- (maturity_long - maturity_short)
forward_rate <- ((long_bond/short_bond)^(360/days_between)-1)*100
return(round(forward_rate, digits=2))
}
#run function
df <- df %>%
mutate(forward_rate = calculate_forward_rate(
maturity_short,
yield_short,
maturity_long,
yield_long,
day_count))
#Create a yield_diff. How much more/less the yield must be when its time to buy the subsequent bond
df <- df %>%
mutate(yield_diff = if_else(bond_short == bond_long, NA_real_, forward_rate - yield_short))
3.1.1.2 Bond Converter
Calculate Bond Price
Maturity <- "2023-04-30"
Handle <- 100
x32 <- 25
x64 <- 24
cpn <- 2.25
ttm <- as.numeric(as.Date(Maturity) - as.Date(Sys.Date())) / 365
FV <- 100
calculate_price <- function(Handle, x32, x64){
bond_price <- Handle + ((x32+(x64/64))/32)
return(format(round(bond_price,10), nsmall=10))
}
bond_price <- as.numeric(calculate_price(Handle, x32, x64))
Convert from Discount to Yield
discount <- 1.69
maturity_date <- as.Date("2021-05-06")
settlement_date <- Sys.Date() +1
day_count <- 360
calculate_ytm_from_discount <- function(discount, maturity_date, settlement_date, day_count){
days <- as.numeric(maturity_date-settlement_date)
discount <- discount / 100
yield_ <- (discount / (1-(discount * (days/day_count))))
return(format(round(yield_*100,10),nsmall=10))
}
calculate_ytm_from_discount(discount, maturity_date, settlement_date, day_count)
Convert from Yield to Discount
yield <- 1.719967
maturity_date <- as.Date("2021-05-06")
settlement_date <- Sys.Date()+1
day_count <- 360
yield <- yield / 100
calculate_disc_from_yield <- function(yield, maturity_date, settlement_date, day_count){
days <- as.numeric(maturity_date-settlement_date)
discount <- (yield / (1+(yield /(day_count/days))))
return(format(round(discount*100,10),nsmall=10))
}
calculate_disc_from_yield(yield, maturity_date, settlement_date, day_count)