| AnnivDates {BondValuation} | R Documentation |
AnnivDates (time-invariant properties and temporal structure)
Description
AnnivDates returns a bond's time-invariant characteristics and temporal structure as a list of three or four named data frames.
Usage
AnnivDates(
Em = as.Date(NA),
Mat = as.Date(NA),
CpY = as.numeric(NA),
FIPD = as.Date(NA),
LIPD = as.Date(NA),
FIAD = as.Date(NA),
RV = as.numeric(NA),
Coup = as.numeric(NA),
DCC = as.numeric(NA),
EOM = as.numeric(NA),
DateOrigin = as.Date("1970-01-01"),
InputCheck = 1,
FindEOM = FALSE,
RegCF.equal = 0
)
Arguments
Em |
The bond's issue date. (required) |
Mat |
Maturity date, i.e. date on which the redemption value and the final interest are paid. (required) |
CpY |
Number of interest payments per year (non-negative integer; element of the set {0,1,2,3,4,6,12}. Default: 2. |
FIPD |
First interest payment date after |
LIPD |
Last interest payment date prior to |
FIAD |
Date on which the interest accrual starts (so-called "dated date"). |
RV |
The redemption value of the bond. Default: 100. |
Coup |
Nominal interest rate per year in percent. Default: |
DCC |
The day count convention the bond follows. Default: |
EOM |
Boolean indicating whether the bond follows the End-of-Month rule. Default: |
DateOrigin |
Determines the starting point for the daycount in "Date" objects. Default: "1970-01-01". |
InputCheck |
If 1, the input variables are checked for the correct format. Default: 1. |
FindEOM |
If |
RegCF.equal |
If 0, the amounts of regular cash flows are calculated according to the
stipulated |
Details
AnnivDates generates a list of the three data frames Warnings, Traits
and DateVectors. If the variable Coup is passed to the function,
the output contains additionally the data frame PaySched. AnnivDates is meant to analyze
large data frames. Therefore some features are implemented to evaluate the quality of the data. The
output of these features is stored in the data frame Warnings. Please see section Value
for a detailed description of the tests run and the meaning of the variables in Warnings. The
data frame Traits contains all time-invariant bond characteristics that were either provided by
the user or calculated by the function. The data frame DateVectors contains three vectors
of Date-Objects named RealDates, CoupDates and AnnivDates and three vectors of
numerics named RD_indexes, CD_indexes and AD_indexes. These vectors are
used in the other functions of this package according to the methodology presented in Djatschenko (2018).
The data frame PaySched matches CoupDates
to the actual amount of interest that the bond pays on the respective interest payment date. Section
Value provides further information on the output of the function AnnivDates. Below
information on the proper input format is provided. Subsequently follows information on the operating
principle of the function AnnivDates and on the assumptions that are met to
estimate the points in time needed to evaluate a bond.
The dates
Em,Mat,FIPD,LIPDandFIADcan be provided as"Date" with format
"%Y-%m-%d", or"numeric" with the appropriate
DateOrigin, ornumber of class "character" with the appropriate
DateOrigin, orstring of class "character" in the format
"yyyy-mm-dd".
CpY,RVandCoupcan be provided either as class "numeric" or as a number of class "character".The provided issue date (
Em) is instantly substituted by the first interest accrual date (FIAD) ifFIADis available and different fromEm.Before the determination of the bond's date characteristics begins, the code evaluates the provided calendar dates for plausibility. In this process implausible dates are dropped. The sort of corresponding implausibility is identified and stored in a warning flag. (See section Value for details.)
The remaining valid calendar dates are used to gauge whether the bond follows the End-of-Month-Rule. The resulting parameter est_EOM can take on the following values:
- -
-
Case 1: FIPDandLIPDare bothNA___________ ____________________________________ est_EOM = 1, if Matis the last day of a month.est_EOM = 0, else. ========== ================================ - -
-
Case 2: FIPDisNAandLIPDis a valid calendar date___________ ____________________________________ est_EOM = 1, if LIPDis the last day of a month.est_EOM = 0, else. ========== ================================ - -
-
Case 3: FIPDis a valid calendar date andLIPDisNA___________ ____________________________________ est_EOM = 1, if FIPDis the last day of a month.est_EOM = 0, else. ========== ================================ - -
-
Case 4: FIPDandLIPDare valid calendar dates___________ ____________________________________ est_EOM = 1, if LIPDis the last day of a month.est_EOM = 0, else. ========== ================================
If
EOMis initially missing orNAor not element of{0,1},EOMis setest_EOMwith a warning.If the initially provided value of
EOMdeviates fromest_EOM, the following two cases apply:________ _________________________________________ Case 1: If EOM = 0andest_EOM = 1:EOMis not overridden and remainsEOM = 0________ _________________________________________ Case 2: If EOM = 1andest_EOM = 0:EOMis overridden and setEOM = 0with a warning.Keeping EOM = 1in this case would conflict withthe provided Mat,FIPDorLIPD.________ _________________________________________ Note: Set the option FindEOM=TRUEto always useest_EOMfound by the code.======= ==================================== If
FIPDandLIPDare both available, the lengths of the first and final coupon periods are determinate and can be "regular", "long" or "short". To find the interest payment dates betweenFIPDandLIPDthe following assumptions are met:-
The interest payment dates between FIPD and LIPD are evenly distributed.
-
The value of EOM determines the location of all interest payment dates.
If assumption 1 is violated, the exact locatations of the interest payment dates between
FIPDandLIPDare ambiguous. The assumption is violated particularly, if-
FIPDandLIPDare in the same month of the same year but not on the same day, or the month difference between
FIPDandLIPDis not a multiple of the number of months implied byCpY, or-
FIPDandLIPDare not both last day in month, their day figures differ and the day figure difference betweenFIPDandLIPDis not due to different month lengths.
In each of the three cases,
FIPDandLIPDare dropped with the flagIPD_CpY_Corrupt = 1.-
If neither
FIPDnorLIPDare available the code evaluates the bond based only upon the required variablesEmandMat(andCpY, which is2by default). Since FIPD is not given, it is impossible to distinguish between a "short" and "long" odd first coupon period, without an assumption on the number of interest payment dates. Consequently the first coupon period is assumed to be either "regular" or "short". The locations ofFIPDandLIPDare estimated under the following assumptions:-
The final coupon period is "regular".
-
The interest payment dates between the estimated FIPD and Mat are evenly distributed.
-
The value of EOM determines the location of all interest payment dates.
-
If
LIPDis available butFIPDis not, the length of the final coupon payment period is determined byLIPDandMatand can be "regular", "long" or "short". The locations of the interest payment dates are estimated under the following assumptions:-
The first coupon period is either "regular" or "short".
-
The interest payment dates between the estimated FIPD and LIPD are evenly distributed.
-
The value of EOM determines the location of all interest payment dates.
-
If
FIPDis available butLIPDis not, the length of the first coupon payment period is determined byEmandFIPDand can be "regular", "long" or "short". The locations of the interest payment dates are estimated under the following assumptions:-
The final coupon period is either "regular" or "short".
-
The interest payment dates between FIPD and the estimated LIPD are evenly distributed.
-
The value of EOM determines the location of all interest payment dates.
-
Value
All dates are returned irrespective of whether they are on a business day or not.
- DateVectors (data frame)
-
- -
- RealDates
A vector of Date class objects with format "%Y-%m-%d" in ascending order, that contains the issue date, all actual coupon payment dates and the maturity date.
- RD_indexes
A vector of numerics capturing the temporal structure of the bond.
- CoupDates
A vector of Date class objects with format "%Y-%m-%d" in ascending order, that contains all actual coupon payment dates and the maturity date.
- CD_indexes
A vector of numerics capturing the temporal structure of the bond.
- AnnivDates
A vector of Date class objects with format "%Y-%m-%d" in ascending order, that contains all theoretical coupon anniversary dates. The first value of AnnivDates is the anniversary date immediately preceding the issue date, if the bond has an irregular first coupon period; otherwise it is the issue date. The final value of AnnivDates is the anniversary date immediately succeeding the maturity date, if the bond has an irregular final coupon period; otherwise it is the maturity date.
- AD_indexes
A vector of numerics capturing the temporal structure of the bond.
- -
- PaySched (data frame)
-
- -
- CoupDates
A vector of Date class objects with format "%Y-%m-%d" in ascending order, that contains all actual coupon payment dates and the maturity date.
- CoupPayments
A vector of class "numeric" objects, that contains the actual amounts of interest that the bond pays on the respective coupon payment dates. The unit of these payments is the same as that of
RVthat was passed to the function.RVis not included in the final interest payment.- NOTE:
PaySchedis created only if the variableCoupis provided.- -
- Traits (data frame)
-
- -
- DateOrigin
The starting point for the daycount in "Date" objects.
- CpY
Number of interest payments per year.
- FIAD
Date on which the interest accrual starts (so-called "dated date").
- Em
The bond's issue date that was used for calculations.
- Em_Orig
The bond's issue date that was entered.
- FIPD
The first interest payment date after
Emthat was used for calculations. If the enteredFIPDwas dropped during the calculation process, the value isNA.- FIPD_Orig
The first interest payment date after
Emthat was entered.- est_FIPD
The estimated first interest payment date after
Em.NA, if a validFIPDwas entered.- LIPD
The last interest payment date prior to
Matthat was used for calculations. If the enteredLIPDwas dropped during the calculation process, the value isNA.- LIPD_Orig
The last interest payment date prior to
Matthat was entered.- est_LIPD
The estimated last interest payment date prior to
Mat.NA, if a validLIPDwas entered.- Mat
The maturity date that was entered.
- Refer
Reference date that determines the day figures of all AnnivDates.
- FCPType
A character string indicating the type of the first coupon period. Values: "long", "regular", "short".
- FCPLength
Length of the first coupon period as a fraction of a regular coupon period.
- LCPType
A character string indicating the type of the last coupon period. Values: "long", "regular", "short".
- LCPLength
Length of the final coupon period as a fraction of a regular coupon period.
- Par
The redemption value of the bond.
- CouponInPercent.p.a
Nominal interest rate per year in percent.
- DayCountConvention
The day count convention the bond follows.
- EOM_Orig
The value of
EOMthat was entered.- est_EOM
The estimated value of
EOM.- EOM_used
The value of
EOMthat was used in the calculations.- -
- Warnings (data frame)
-
- -
A set of flags that indicate the occurrence of warnings during the execution. Below they are listed according to the hierarchical structure within the function AnnivDates.
- -
-
Em_FIAD_differ = 1 , if the provided issue date ( Em) was substituted by the firstinterest accrual date ( FIAD).This happens, if FIADis available and different fromEm.________________________________________________ Note: No warning is displayed. ___________________ ___ ________________________________________________ 0 , else. ================= === =========================================== - -
-
EmMatMissing = 1 , if either issue date ( Em) or maturity date (Mat) or bothare missing or NA.________________________________________________ Output: RealDates = NA, CoupDates= NA,AnnivDates = NA, FCPType= NA, LCPType= NA.___________________ ___ ________________________________________________ 0 , else. ================= === =========================================== - -
-
CpYOverride = 1 , if number of interest periods per year ( CpY) is missing orNA, or if the providedCpYis not element of {0,1,2,3,4,6,12}.________________________________________________ Note: CpYis set 2, and the execution continues.________________________________________________ Output: as if CpY= 2 was provided initially.___________________ ___ ________________________________________________ 0 , else. ================= === =========================================== - -
-
RV_set100percent = 1 , if the redemption value ( RV) is missing orNA.________________________________________________ Note: RVis set 100, and the execution continues.________________________________________________ Output: as if RV= 100 was provided initially.___________________ ___ ________________________________________________ 0 , else. ================= === =========================================== - -
-
NegLifeFlag = 1 , if the provided maturity date ( Mat) is before or on theprovided issue date ( Em).________________________________________________ Output: RealDates = NA, CoupDates= NA,AnnivDates = NA, FCPType= NA, LCPType= NA.___________________ ___ ________________________________________________ 0 , else. ================= === =========================================== - -
-
ZeroFlag = 1 , if number of interest payments per year ( CpY) is0.________________________________________________ Output: RealDates = (Em,Mat), CoupDates= Mat,AnnivDates = (Em,Mat), FCPType= NA, LCPType= NA.___________________ ___ ________________________________________________ 0 , else. ================= === =========================================== - -
-
Em_Mat_SameMY = 1 , if the issue date ( Em) and the maturity date (Mat) are in thesame month of the same year but not on the same day, while CpYis an element of {1,2,3,4,6,12}.________________________________________________ Output: RealDates = (Em,Mat), CoupDates= Mat,FCPType = short, LCPType= short.___________________ ___ ________________________________________________ 0 , else. ================= === =========================================== - -
-
ChronErrorFlag = 1 , if the provided dates are in a wrong chronological order. ________________________________________________ Note: The correct ascending chronological order is: issue date ( Em), first interest payment date (FIPD),last interest payment date ( LIPD), maturity date (Mat).FIPDandLIPDare setas.Date(NA).________________________________________________ Output: as if FIPDandLIPDwere not provided initially.___________________ ___ ________________________________________________ 0 , else. ================= === =========================================== - -
-
FIPD_LIPD_equal = 1 if Em<FIPD=LIPD<Mat.________________________________________________ Output: AnnivDates contains FIPDand has at least3elements.RealDates = (Em,FIPD,Mat), CoupDates= (FIPD,Mat).FCPType and LCPType can be "short", "regular" or "long". ___________________ ___ ________________________________________________ 0 , else. ================= === =========================================== - -
-
IPD_CpY_Corrupt = 1 , if the provided first interest payment date ( FIPD) and lastinterest payment date ( LIPD) are inconsistent with theprovided number of interest payments per year ( CpY).________________________________________________ Note: Inconsistency occurs if 1. FIPDandLIPDare in the same month of the same yearbut not on the same day, or 2. the number of months between FIPDandLIPDis not amultiple of the number of months implied by CpY, or3. FIPDandLIPDare not both last day in month, theirday figures differ and the day figure difference between FIPDandLIPDis not due to different month lengths.In each of the three cases keeping the provided values of FIPDandLIPDwould violate the assumption, that theanniversary dates between FIPDandLIPDare evenlydistributed. ________________________________________________ FIPDandLIPDare setas.Date(NA)and the execution continues. ________________________________________________ Output: as if FIPDandLIPDwere not provided initially.___________________ ___ ________________________________________________ 0 , else. ================= === =========================================== - -
-
EOM_Deviation = 1 , if the provided value of EOMdeviates from the value thatis inferred from the provided calendar dates. ________________________________________________ Note: The program analyses the valid values of Em,Mat,FIPDandLIPDto determine the appropriate value ofEOM.If the initially provided value of EOMdeviates from the valuedetermined by the program, there might be an inconsistency in the provided data. ___________________ ___ ________________________________________________ 0 , else. ================= === =========================================== - -
-
EOMOverride = 1 , if the provided value of EOMis overridden by a value thatis inferred from the provided calendar dates. ________________________________________________ Note: This happens automatically if EOMis initially missing orNAor not element of {0,1}and if the provided value ofEOMconflicts with the provided values of FIPD,LIPDorMat,e.g. if est_EOM = 0butEOM = 1.If EOM_Deviation = 1and the optionFindEOMis setTRUE,the initially provided value of EOMis also overridden by thevalue that is inferred from the provided calendar dates if est_EOM = 1butEOM = 0.________________________________________________ Output: as if the value of EOMthat is found by the program wasprovided initially. ___________________ ___ ________________________________________________ 0 , else. ================= === =========================================== - -
-
DCCOverride = 1 if DCCis missing or NA or not element of c(1:16).________________________________________________ Note: If the program cannot process the provided day count identifier DCC, it overrides it withDCC= 2.________________________________________________ Output: as if DCC= 2 was provided initially.___________________ ___ ________________________________________________ 0 , else. ================= === =========================================== - -
-
NoCoups = 1 , if there are no coupon payments between the provided issue date ( Em) and the maturity date (Mat), but theprovided ( CpY) is not zero.________________________________________________ Output: RealDates = (Em,Mat), CoupDates= (Mat),AnnivDates contains Matand has either2or3elements, FCPType = LCPType andcan be "short","regular"or"long".___________________ ___ ________________________________________________ 0 , else. ================= === ===========================================
References
Djatschenko, Wadim, The Nitty Gritty of Bond Valuation: A Generalized Methodology for Fixed Coupon Bond Analysis Allowing for Irregular Periods and Various Day Count Conventions (November 5, 2018). Available at SSRN: https://ssrn.com/abstract=3205167.
Examples
data(SomeBonds2016)
# Applying the function AnnivDates to the data frame SomeBonds2016.
system.time(
FullAnalysis<-apply(SomeBonds2016[,c('Issue.Date','Mat.Date','CpY.Input','FIPD.Input',
'LIPD.Input','FIAD.Input','RV.Input','Coup.Input','DCC.Input','EOM.Input')],1,function(y)
AnnivDates(y[1],y[2],y[3],y[4],y[5],y[6],y[7],y[8],y[9],y[10],RegCF.equal=1)),
gcFirst = TRUE)
# warnings are due to apply's conversion of the variables' classes in
# SomeBonds2016 to class "character"
# The output stored in FullAnalysis ist a nested list.
# Lets look at what is stored in FullAnalysis for a random bond:
randombond<-sample(c(1:nrow(SomeBonds2016)),1)
FullAnalysis[[randombond]]
# Extracting the data frame Warnings:
AllWarnings<-do.call(rbind,lapply(FullAnalysis, `[[`, 1))
summary(AllWarnings)
# binding the Warnings to the bonds
BondsWithWarnings<-cbind(SomeBonds2016,AllWarnings)
# Extracting the data frame Traits:
AllTraits<-do.call(rbind,lapply(FullAnalysis, `[[`, 2))
summary(AllTraits)
# binding the Traits to the bonds
BondsWithTraits<-cbind(SomeBonds2016,AllTraits)
# Extracting the data frame AnnivDates:
AnnivDates<-lapply(lapply(FullAnalysis, `[[`, 3), `[[`, 5)
AnnivDates<-lapply(AnnivDates, `length<-`, max(lengths(AnnivDates)))
AnnivDates<-as.data.frame(do.call(rbind, AnnivDates))
AnnivDates<-as.data.frame(lapply(AnnivDates, as.Date, as.Date(AllTraits$DateOrigin[1])))
# binding the AnnivDates to the bonds:
BondsWithAnnivDates<-cbind(SomeBonds2016,AnnivDates)
# Extracting the data frames PaySched for each bond and creating a panel:
CoupSched<-lapply(FullAnalysis, `[[`, 4)
CoupSchedPanel<-SomeBonds2016[rep(row.names(SomeBonds2016),sapply(CoupSched, nrow)),]
CoupSched<-as.data.frame(do.call(rbind, CoupSched))
CoupSchedPanel<-cbind(CoupSchedPanel,CoupSched)