Title: | Nonparametric Estimation of the Yield Curve Evolution |
---|---|
Description: | Nonparametric estimation of discount functions and yield curves from transaction data of coupon paying bonds. Koo, B., La Vecchia, D., & Linton, O. B. (2021) <doi:10.1016/j.jeconom.2020.04.014> describe an application of this package using the Center for Research in Security Prices (CRSP) Bond Data and document its implementation. |
Authors: | Bonsoo Koo [aut], Nathaniel Tomasetti [ctb], Kai-Yang Goh [ctb], Yangzhuoran Fin Yang [aut, cre] |
Maintainer: | Yangzhuoran Fin Yang <[email protected]> |
License: | GPL-3 |
Version: | 0.2.1.9000 |
Built: | 2024-11-15 05:37:49 UTC |
Source: | https://github.com/bonsook/ycevo |
Nonparametric estimation of discount functions and yield curves.
Maintainer: Yangzhuoran Fin Yang [email protected] (ORCID)
Authors:
Bonsoo Koo [email protected]
Other contributors:
Nathaniel Tomasetti [contributor]
Kai-Yang Goh [contributor]
Koo, B., La Vecchia, D., & Linton, O. (2021). Estimation of a nonparametric model for bond prices from cross-section and time series information. Journal of Econometrics, 220(2), 562-588.
Useful links:
Augment data with predicted discount functions and yield curves
## S3 method for class 'ycevo' augment(x, newdata = NULL, loess = TRUE, ...)
## S3 method for class 'ycevo' augment(x, newdata = NULL, loess = TRUE, ...)
x |
A ycevo object |
newdata |
A data frame containing time-to-maturity in years |
loess |
Logical. If TRUE, the returned discount functions and yield curves are loess smoothed. |
... |
Additional arguments required for generic consistency. Currently not used. Warning: A misspelled argument will not raise an error. The misspelled argument will be either disregarded, or the default value will be applied if one exists. |
If newdata
is not provided, returns the discount function and yield curve
at the specified estimation points in ycevo()
.
If newdata
is provided, the discount functions at the time-to-maturities
specified in newdata
are generated from loess smoothing (see
stats::loess()
), and interpolated to produce the discount function values at the
quotation date specified in newdata
, before being converted to the yield curves.
newdata
augmented with .discount
and .yield
for the discount
function and the yield curve respectively.
# Simulating bond data bonds <- ycevo_data(n = 10) # Estimation can take up to 30 seconds res <- ycevo(bonds, x = lubridate::ymd("2023-03-01")) # Augmentation augment(res)
# Simulating bond data bonds <- ycevo_data(n = 10) # Estimation can take up to 30 seconds res <- ycevo(bonds, x = lubridate::ymd("2023-03-01")) # Augmentation augment(res)
Plots the estimated discount functions and yield curves from a ycevo()
object.
## S3 method for class 'ycevo' autoplot( object, est = c("both", "discount", "yield"), against = c("tau", "x", "both"), loess = TRUE, ... )
## S3 method for class 'ycevo' autoplot( object, est = c("both", "discount", "yield"), against = c("tau", "x", "both"), loess = TRUE, ... )
object |
A ycevo object |
est |
String. Indicates which estimated values to plot: discount function, yield curve, or both. Default is both. |
against |
String. Indicates which variable to plot against, i.e. what is on the x axis.
Time-to-maturity |
loess |
Logical. If TRUE, the returned discount functions and yield curves are loess smoothed. |
... |
Additional arguments required for generic consistency. Currently not used. Warning: A misspelled argument will not raise an error. The misspelled argument will be either disregarded, or the default value will be applied if one exists. |
A ggplot2::ggplot()
object if only one dimension is specified in
against
. A plotly::plot_ly()
object if against
is set to both.
# Simulating bond data bonds <- ycevo_data(n = 10) # Estimation can take up to 30 seconds res <- ycevo(bonds, x = lubridate::ymd("2023-03-01")) # Plot autoplot(res)
# Simulating bond data bonds <- ycevo_data(n = 10) # Estimation can take up to 30 seconds res <- ycevo(bonds, x = lubridate::ymd("2023-03-01")) # Plot autoplot(res)
Generate a yield curve using the extended version of Nelson & Siegel model
(Nelson, C. R., & Siegel, A. F., 1987). This has been used in the simulation
setting (Equation (30)) of Koo, B., La Vecchia, D., & Linton, O. (2021). See
Details
and References
.
generate_yield( n_qdate = 12, periods = 36, b0 = 0, b1 = 0.05, b2 = 2, t1 = 0.75, t2 = 125, linear = -0.55, quadratic = 0.55, cubic = -0.55 ) get_yield_at( time, maturity, b0 = 0, b1 = 0.05, b2 = 2, t1 = 0.75, t2 = 125, linear = -0.55, quadratic = 0.55, cubic = -0.55 ) get_yield_at_vec( time, maturity, b0 = 0, b1 = 0.05, b2 = 2, t1 = 0.75, t2 = 125, linear = -0.55, quadratic = 0.55, cubic = -0.55 )
generate_yield( n_qdate = 12, periods = 36, b0 = 0, b1 = 0.05, b2 = 2, t1 = 0.75, t2 = 125, linear = -0.55, quadratic = 0.55, cubic = -0.55 ) get_yield_at( time, maturity, b0 = 0, b1 = 0.05, b2 = 2, t1 = 0.75, t2 = 125, linear = -0.55, quadratic = 0.55, cubic = -0.55 ) get_yield_at_vec( time, maturity, b0 = 0, b1 = 0.05, b2 = 2, t1 = 0.75, t2 = 125, linear = -0.55, quadratic = 0.55, cubic = -0.55 )
n_qdate |
Integer. Number of quotation dates to use in the data. Defaults to 12. |
periods |
Integer. Maximum number of time-to-maturity periods in 10 years that the yield curve is estimated for each quotation date. Defaults to 36 |
b0 |
Level term in yield curve equation, Defaults is 0. See
|
b1 |
Slope term in yield curve equation, Defaults is 0.05. See
|
b2 |
Curvature term in yield curve equation, Defaults is 2. See
|
t1 |
Scaling parameter in yield curve equation, Defaults is 0.75. See
|
t2 |
Scaling parameter in yield curve equation, Defaults is 125. See
|
linear |
Linear term in yield curve evolution, Defaults is -0.55. See
|
quadratic |
Quadratic term in yield curve evolution. Defaults is 0.55.
See |
cubic |
Cubic term in yield curve evolution. Defaults is -0.55. See
|
time |
Numeric value. |
maturity |
Numeric value. Maturity in years. |
The initial curve at time zero is generated from the following equation
where is the time to maturity, usually measured in years. This
defines the yield curve for the quotation date = 0. The yield curve for
quotation dates
time
is obtained by multiplying this curve
by the cubic equation,
so the yield curve slowly changes over different quotation dates.
generate_yield()
Numeric matrix. Each column contains the yield curve values at a point in time (a quotation date).
Each row contains the yield curve values for a time-to-maturity.
For example, the number in the second column third row is the yield at the second quotation date,
for the third time-to-maturity ranking from shortest to longest.
See Details
for the equation to generate a yield curve.
See Examples
for a example with the code to visually inspect the yield curves.
get_yield_at()
Numeric vector.
get_yield_at_vec()
Numeric vector.
get_yield_at()
: Return the yield at specific points in time of
specific maturities.
get_yield_at_vec()
: Deprecated. Vectorised version of
get_yield_at()
. Use get_yield_at()
instead.
Nelson, C. R., & Siegel, A. F. (1987). Parsimonious Modeling of Yield Curves. The Journal of Business, 60(4), 473-489.
Koo, B., La Vecchia, D., & Linton, O. (2021). Estimation of a nonparametric model for bond prices from cross-section and time series information. Journal of Econometrics, 220(2), 562-588.
out <- generate_yield() # plots library(ggplot2) out <- data.frame(out) colnames(out) <- 1:12 out <- dplyr::mutate(out, time = 1:36) out <- tidyr::pivot_longer(out, -time, names_to = "qdate", values_to = "yield") ggplot(out) + geom_line(aes(x=time, y=yield, color = qdate))
out <- generate_yield() # plots library(ggplot2) out <- data.frame(out) colnames(out) <- 1:12 out <- dplyr::mutate(out, time = 1:36) out <- tidyr::pivot_longer(out, -time, names_to = "qdate", values_to = "yield") ggplot(out) + geom_line(aes(x=time, y=yield, color = qdate))
vis_kernel()
visualises kernel weights assigned to the intervals
surrounding specific grid points using the Epanechnikov
kernel function and given bandwidths.
vis_kernel(data, x = NULL, hx = NULL, tau = NULL, ht = NULL, ...)
vis_kernel(data, x = NULL, hx = NULL, tau = NULL, ht = NULL, ...)
data |
Bond data. If |
x |
Time grids at which the discount curve is evaluated. Should be
specified using the same class of object as the quotation date ( |
hx |
Numeric vector. Bandwidth parameters corresponding to each time
point |
tau |
Numeric vector. Time-to-maturities in years where
discount function and yield curve will be estimated for each of time points |
ht |
Numeric vector. Bandwidth parameters corresponding to each value of
time-to-maturities |
... |
Specification of an additional covariate, taking the form of |
If x
and hx
are provided, the kernel weights assigned to the intervals
surrounding each of time points x
will be plotted.
If tau
and ht
are provided, the kernel weights assigned to the intervals
surrounding each of time-to-maturities tau
will be plotted.
If the grid and bandwidth of a covariate are provided in ...
, the
kernel weights of that covariate will be plotted.
The kernel weights can only be plotted in one dimension (time, time-to-maturity, or covariate) at a time.
A ggplot2::ggplot()
object.
bonds <- ycevo_data() vis_kernel(bonds, x = lubridate::ymd("2023-06-01"), hx = 0.2)
bonds <- ycevo_data() vis_kernel(bonds, x = lubridate::ymd("2023-06-01"), hx = 0.2)
Nonparametric estimation of discount functions and yield curves at given dates, time-to-maturities, and one additional covariate, usually interest rate.
ycevo( data, x, span_x = 60, hx = NULL, tau = NULL, ht = NULL, tau_p = tau, htp = NULL, cols = NULL, ... ) estimate_yield( data, xgrid, hx, tau, ht, tau_p = tau, htp = ht, rgrid = NULL, hr = NULL, interest = NULL, cfp_slist = NULL )
ycevo( data, x, span_x = 60, hx = NULL, tau = NULL, ht = NULL, tau_p = tau, htp = NULL, cols = NULL, ... ) estimate_yield( data, xgrid, hx, tau, ht, tau_p = tau, htp = ht, rgrid = NULL, hr = NULL, interest = NULL, cfp_slist = NULL )
data |
Data frame; bond data to estimate discount curve from. See
|
x |
Time grids at which the discount curve is evaluated. Should be
specified using the same class of object as the quotation date ( |
span_x |
Half of the window size, or the distance from the centre |
hx |
Numeric vector. Bandwidth parameters corresponding to each time
point |
tau |
Numeric vector. Time-to-maturities in years where
discount function and yield curve will be estimated for each of time points |
ht |
Numeric vector. Bandwidth parameters corresponding to each value of
time-to-maturities |
tau_p |
Numeric vector. Auxiliary time-to-maturities in
years. See |
htp |
Numeric vector. Bandwidth parameters corresponding to each of
auxiliary time-to-maturities |
cols |
< |
... |
Specification of an additional covariate, taking the form of |
xgrid |
Numeric vector. Values between 0 and 1. Time grids over the entire time horizon (percentile) of the data at which the discount function is evaluated. |
rgrid |
(Optional) Numeric vector. Interest rate grids in percentage at which the discount function is evaluated, e.g. 4.03 means at interest rate of 4.03%. |
hr |
(Optional) Numeric vector. Bandwidth parameter in percentage determining the size of the window in the kernel function that corresponds to each interest rate grid ('rgrid'). |
interest |
(Optional) Numeric vector. Daily short term interest rates. The length is the same as the number of quotation dates included in the data, i.e. one interest rate per day. |
cfp_slist |
(Internal) Experienced users only. A list of matrices, generated by the internal function 'get_cfp_slist'. |
Suppose that a bond has a price
at time
with a
set of cash payments, say
with a set of
corresponding discount values
. In the bond
pricing literature, the market price of a bond should reflect the
discounted value of cash payments. Thus, we want to minimise
For the estimation of , solving the first order condition yields
and
There are challenges: depends on all the relevant discount
values for the cash payments of the bond. Our model contains random errors
and our interest lies in expected value of
where the expected
value of errors is zero.
is an infinite-dimensional function not
a discrete finite-dimensional vector. Generally, cash payments are made
biannually, not dense at all. Moreover, cash payment schedules vary over
different bonds.
Let be the discount function at given covariates
(dates
x
and interest rates rgrid
), and given
time-to-maturities (
tau
). is the yield
curve at given covariates
(dates
x
and interest rates
rgrid
), and given time-to-maturities (
tau
).
We pursue the minimum of the following smoothed sample least squares
objective function for any smooth function :
where a bond has a price
at time
with a set of cash
payments
with a set of corresponding discount
values
,
is the kernel
function with a bandwidth parameter
, the first kernel function is
the kernel in space with bonds whose maturities
are close to
the sequence
, the second kernel function is the kernel in
time and in interest rates with
, which are close to the sequence
. This means that bonds with similar cash flows, and traded in
contiguous days, where the short term interest rates in the market are
similar, are combined for the estimation of the discount function at a
point in space, in time, and in "interest rates".
The estimator for the discount function over time to maturity and time is
This function provides a data frame of the estimated yield and discount rate at each combination of the provided grids. The estimated yield is transformed from the estimated discount rate.
An alternative specification of bandwidth hx
is span_x
, which provides
kernel coverage invariant to the length of data
. span_x
takes an
absolute measure of time depending on the unit of x
. The default value is
60. If the data is daily on trading days, i.e., the interval between every
two consecutive qdate
is one trading day, then the window of the kernel
function allows the estimation at each point x
to contain information
from 60 trading days prior to and after the time point x
.
For more information on the estimation method, please refer to
References
.
A tibble::tibble()
object of class ycevo
with the following
columns.
The time points that user-specified as x
. The name of this
column will be consistent with the name of the time index column in the
data
input, if the user choose to provide a data frame with the time
index column named differently from qdate
with the cols
argument.
A nested columns of estimation results containing a
tibble::tibble()
for each qdate
. Each tibble
contains three columns:
tau
for the time-to-maturity specified by the user in the tau
argument,
.disount
for the estimated discount function at this time and this
time-to-maturity, and .yield
for the estimated yield curve.
estimate_yield()
: Experienced users only. Yield estimation with interest rate
and manually selected bandwidth parameters.
Only length one x and length one hx are supported at a time.
Returns a data frame of the yield and discount rate at each combination of
the provided grids.
Estimated discount rate
Same as input 'xgrid'
Same as input 'tau'
Estimated yield
Koo, B., La Vecchia, D., & Linton, O. (2021). Estimation of a nonparametric model for bond prices from cross-section and time series information. Journal of Econometrics, 220(2), 562-588.
augment.ycevo()
, autoplot.ycevo()
# Simulating bond data bonds <- ycevo_data(n = 10) # Estimation can take up to 30 seconds ycevo(bonds, x = lubridate::ymd("2023-03-01"))
# Simulating bond data bonds <- ycevo_data(n = 10) # Estimation can take up to 30 seconds ycevo(bonds, x = lubridate::ymd("2023-03-01"))
Simulates bond transaction data at each weekday throughout the year 2023, following the extended version of Nelson & Siegel model (Nelson, C. R., & Siegel, A. F., 1987).
ycevo_data( n = 40, b0 = 0, b1 = 0.05, b2 = 2, t1 = 0.75, t2 = 125, linear = -0.55, quadratic = 0.55, cubic = -0.55 )
ycevo_data( n = 40, b0 = 0, b1 = 0.05, b2 = 2, t1 = 0.75, t2 = 125, linear = -0.55, quadratic = 0.55, cubic = -0.55 )
n |
Integer. Number of bonds of each maturity to simulation |
b0 |
Level term in yield curve equation, Defaults is 0. See
|
b1 |
Slope term in yield curve equation, Defaults is 0.05. See
|
b2 |
Curvature term in yield curve equation, Defaults is 2. See
|
t1 |
Scaling parameter in yield curve equation, Defaults is 0.75. See
|
t2 |
Scaling parameter in yield curve equation, Defaults is 125. See
|
linear |
Linear term in yield curve evolution, Defaults is -0.55. See
|
quadratic |
Quadratic term in yield curve evolution. Defaults is 0.55.
See |
cubic |
Cubic term in yield curve evolution. Defaults is -0.55. See
|
n
bonds for each of the following maturities are simulated: 20, 10, 5,
3, 2 and 0.8 years. The face value of all bonds is 100. Bonds with 0.8 years
of maturity are similar to the US Treasury bills with no coupon. Bonds with
maturity between 2 and 10 years correspond to the US Treasury notes. Their
coupon rates are simulated from an Epanechnikov distribution with mean 4, and
the distance from the mean to the boundary is 2.65. Bonds with maturity of 20
years corresponds to the US Treasury bonds. Their coupon rates are simulated
from an Epanechnikov distribution with mean 7.5, and the distance from the
mean to the boundary is 2.65. Coupons are payable every 6 months.
We artificially "observe" quotation data of bonds on every weekday through out 2023, starting with 2 Jan 2023. To ensure an adequate number of transactions are observed for the estimation of the yield curve, the earliest bond is issued prior to the beginning of 2023, determined by the length of maturity of that type of bond, such that the last payment can still be observed at the beginning of 2023. For example, the first bond with 20 years of maturity is issued at the beginning of 2003. The last bond within this type is issued at the end of 2023. The rest of the bonds have issue dates evenly distributed between the first and the last bonds.
The initial yield at the beginning of 2023 is generated from the following equation
where is the time to maturity in years. The yield curve at
quotation time
is obtained by multiplying this curve by the cubic
equation,
so the yield curve slowly changes over different
quotation dates. The time is a value between 0 and 1, the proportion
of time that has passed by a quotation date, identifying the progression
through 2023. For example, the time
corresponding to 31 Mar 2023 is
0.25.
The discount function is then derived from the yield curve,
to discount all the future cash flows of a bond and calculate the price of that bond at the quotation date.
A tibble::tibble()
object with 5 variables
The quotation date of a bond in a Date()
class.
The unique identifier of a bond.
The price of a bond.
The remaining time until the given cash flow in days.
The payment amount of the cash flow. For a non-coupon-paying bond, the only cash flow occurs on the maturity date with a payment of 100, i.e., the face value of the bond. For a coupon-paying bond, the stream of cash flows includes the coupon payable on the interest payment date before maturity and the face value 100 plus the coupon payment for the last cash flow on the maturity date.
Nelson, C. R., & Siegel, A. F. (1987). Parsimonious Modeling of Yield Curves. The Journal of Business, 60(4), 473-489.
Koo, B., La Vecchia, D., & Linton, O. (2021). Estimation of a nonparametric model for bond prices from cross-section and time series information. Journal of Econometrics, 220(2), 562-588.
ycevo_data()
ycevo_data()