danielkv danielkv - 1 month ago 8
R Question

How to estimate static yield curve with 'termstrc' package in R?

I am trying to estimate the static yield curve for Brazil using

termstrc
package in R. I am using the function
estim_nss.couponbonds
and putting 0% coupon-rates and $0 cash-flows, except for the last one which is $1000 (the face-value at maturity) -- as far as I know this is the function to do this, because the
estim_nss.zeroyields
only calculates the dynamic curve. The problem is that I receive the following error message:

"Error in (pos_cf[i] + 1):pos_cf[i + 1] : NA/NaN argument In addition: Warning message: In max(n_of_cf) : no non-missing arguments to max; returning -Inf "

I've tried to trace the problem using
trace(estim_nss.couponbons, edit=T)
but I cannot find where
pos_cf[i]+1
is calculated. Based on the name I figured it could come from the
postpro_bond
function and used
trace(postpro_bond, edit=T)
, but I couldn't find the calculation again. I believe "cf" comes from cashflow, so there could be some problem in the calculation of the cashflows somehow. I used
create_cashflows_matrix
to test this theory, but it works well, so I am not sure the problem is in the cashflows.

The code is:

#Creating the 'couponbond' class
ISIN <- as.character(c('ltn_2017','ltn_2018', 'ltn_2019', 'ltn_2021','ltn_2023')) #Bond's identification

MATURITYDATE <- as.Date(c(42736, 43101, 43466, 44197, 44927), origin='1899-12-30') #Dates are in system's format

ISSUEDATE <- as.Date(c(41288,41666,42395, 42073, 42395), origin='1899-12-30') #Dates are in system's format

COUPONRATE <- rep(0,5) #Coupon rates are 0 because these are zero-coupon bonds

PRICE <- c(969.32, 867.77, 782.48, 628.43, 501.95) #Prices seen 'TODAY'

ACCRUED <- rep(0.1,5) #There is no accrued interest in the brazilian bond's market

#Creating the cashflows sublist
CFISIN <- as.character(c('ltn_2017','ltn_2018', 'ltn_2019', 'ltn_2021', 'ltn_2023')) #Bond's identification

CF <- c(1000,1000,1000,1000,1000)# The face-values

DATE <- as.Date(c(42736, 43101, 43466, 44197, 44927), origin='1899-12-30') #Dates are in system's format

CASHFLOWS <- list(CFISIN,CF,DATE)
names(CASHFLOWS) <- c("ISIN","CF","DATE")

TODAY <- as.Date(42646, origin='1899-12-30')

brasil <- list(ISIN,MATURITYDATE,ISSUEDATE,
COUPONRATE,PRICE,ACCRUED,CASHFLOWS,TODAY)

names(brasil) <- c("ISIN","MATURITYDATE","ISSUEDATE","COUPONRATE",
"PRICE","ACCRUED","CASHFLOWS","TODAY")

mybonds <- list(brasil)

class(mybonds) <- "couponbonds"

#Estimating the zero-yield curve
ns_res <-estim_nss.couponbonds(mybonds, 'brasil' ,method = "ns")

#Testing the hypothesis that the error comes from the cashflow matrix
cf_p <- create_cashflows_matrix(mybonds[[1]], include_price = T)
m_p <- create_maturities_matrix(mybonds[[1]], include_price = T)
b <- bond_yields(cf_p,m_p)


Note that I am aware of this question which reports the same problem. However, it is for the dynamic curve. Besides that, there is no useful answer.

Answer

Your code has two problems. (1) doesn't name the 1st list (this is the direct reason of the error. But if modifiy it, another error happens). (2) In the cashflows sublist, at least one level of ISIN needs more than 1 data.

  # ... 
CFISIN <- as.character(c('ltn_2017','ltn_2018', 'ltn_2019', 
                         'ltn_2021', 'ltn_2023',  'ltn_2023'))   # added a 6th element
CF <- c(1000,1000,1000,1000,1000,  1000)                         # added a 6th
DATE <- as.Date(c(42736,43101,43466,44197,44927,  44928), origin='1899-12-30') # added a 6th

CASHFLOWS <- list(CFISIN,CF,DATE)
names(CASHFLOWS) <- c("ISIN","CF","DATE")
TODAY <- as.Date(42646, origin='1899-12-30')
brasil <- list(ISIN,MATURITYDATE,ISSUEDATE,
               COUPONRATE,PRICE,ACCRUED,CASHFLOWS,TODAY)
names(brasil) <- c("ISIN","MATURITYDATE","ISSUEDATE","COUPONRATE",
                   "PRICE","ACCRUED","CASHFLOWS","TODAY")

mybonds <- list(brasil = brasil)                      # named the list

class(mybonds) <- "couponbonds"
ns_res <-estim_nss.couponbonds(mybonds, 'brasil', method = "ns")
Note: the error came from these lines
bonddata <- bonddata[group]    # prepro_bond()'s 1st line (the direct reason).

# cf <- lapply(bonddata, create_cashflows_matrix)   # the additional error
create_cashflows_matrix(mybonds[[1]], include_price = F)  # don't run