I am attempting to calculate the NPV, clean and dirty price, accrued interest, yield, duration, and convexity for each of the bonds in a portfolio loaded into R as a data frame from a csv file. I have bootstrapped a discount curve using the DiscountCurve function in the RQuantLib package. Then, I created a bond function to iterate through the portfolio of bonds and calculate the various metrics. The function code is below. The problem is that I receive an error when running the bond function:
Error in value[[3L]](cond) :
Error creating FixedRateBond for row 1 : Error in FixedRateWithRebuiltCurve(bond, rates, schedule, calc, c(discountCurve$table$date), : Not compatible with requested type: [type=list; target=double].
Here is the bond function code:
price_bond_portfolio <- function(bond_data, discountCurve) {
# Create a placeholder for results
bond_metrics <- data.frame(matrix(ncol = 7, nrow = nrow(bond_data)))
colnames(bond_metrics) <- c("clean_price", "dirty_price", "NPV", "duration", "convexity", "yield", "accrued")
for (i in 1:nrow(bond_data)) {
# Extract bond details with error handling
bond_details <- tryCatch({
bond_data[i, ]
}, error = function(e) {
stop(paste("Error extracting bond details for row", i, ": ", e))
})
bond = list(settlementDays = bond_details[["settlementDays"]],
issueDate = as.Date(bond_details[["issueDate"]], "%Y-%m-%d"),
faceAmount = bond_details[["faceAmount"]],
accrualDayCounter = bond_details[["accrualDayCounter"]],
paymentConvention = bond_details[["paymentConvention"]])
schedule = list(effectiveDate = tradeDate,
maturityDate = as.Date(bond_details[["maturityDate"]], "%Y-%m-%d"),
period = bond_details[["period"]],
calendar = bond_details[["calendar"]],
businessDayConvention = bond_details[["businessDayConvention"]],
terminationDateConvention = bond_details[["terminationDateConvention"]],
dateGeneration = bond_details[["dateGeneration"]],
endOfMonth = bond_details[["endOfMonth"]])
calc = list(dayCounter = bond_details[["dayCounter"]],
compounding = bond_details[["compounding"]],
freq = bond_details[["freq"]],
durationType = bond_details[["durationType"]])
rates = list(rates = bond_details[["rates"]])
# dc = DiscountCurve(params, tsQuotes, times)
# Create FixedRateBond object with the provided dates and discounts
FR_bond <- tryCatch({
FixedRateBond(bond, rates, schedule, calc, discountCurve)
}, error = function(e) {
stop(paste("Error creating FixedRateBond for row", i, ": ", e))
})
# Extract metrics and store in results
bond_metrics[i, "clean_price"] <- cleanPrice(FR_bond)
bond_metrics[i, "dirty_price"] <- dirtyPrice(FR_bond)
bond_metrics[i, "NPV"] <- NPV(FR_bond)
bond_metrics[i, "duration"] <- duration(FR_bond)
bond_metrics[i, "convexity"] <- convexity(FR_bond)
bond_metrics[i, "yield"] <- bondYield(FR_bond, dayCounter = "Thirty360")
bond_metrics[i, "accrued"] <- accruedAmount(FR_bond)
}
return(bond_metrics)
}
# Pass the curve_list to the price_bond_portfolio function
bond_metrics <- price_bond_portfolio(bond_data = bond_port, discountCurve= discountCurve)
I have tried various things such as creating a list outside of the function consisting of the dates and zero rates
curve = list(dates = discountCurve$table$dates, zerorates = discountCurve$table$zeroRates
but I still get the same error.
Any help would be appreciated.