Bond Valuation and Analysis (Part 1)
Last Updated on July 20, 2023 by Editorial Team
Author(s): Mishtert T
Originally published on Towards AI.
A Baby Step into World of Applied Finance
How to calculate Present Value, Future Value, Time Value of Money β an R Example
Bonds are units of corporate debt issued by companies and securitized as tradeable assets. A fixed-income instrument that traditionally paid a fixed interest rate (coupon) to debtholders (Variable or floating interest rates are also now quite common) β Investopedia
Characteristics of Bond
β Issuer
: The entity that borrows the money
β Principal
: The amount borrowed(par value or face value)
β Coupon Rate:
The amount of interest issuer agrees to pay (Annually, semi-annually, or quarterly U+007C Fixed or floating rate)
β Maturity Date:
Date when the principal amount is returned to the investor (Some bonds do not mature)
β Embedded Options
:
- Example β callable bond ( Issuer can buyback bond earlier than maturity at a pre-agreed price)
- A more complex analysis required.
In this article, weβll look at:
β Annual coupons
β Fixed-rate
β Fixed maturity
β No embedded options
Price vs. Value
β Sometimes, the terms βpriceβ and βvalueβ interchangeably, but there are distinctions:
- Price: Amount paid to acquire an asset
- Value: How much the asset is worth
β For actively traded assets, the price may be considered the best estimate of value
Time Value of Money (TVM)
β $1 today is worth more than $1 tomorrow
β Suppose you won $1,000 in a game, what would you choose?
- Receive the $1,000 today?
- Receive the $1,000 one year from now?
Future Value
β The future value is the value of an invested price at some point in the future
β Future value (fv)
of one and two years from now can be calculated as:
fv1 <- pv * (1+r)
fv2 <- pv * (1+r) * (1+r)
*** r is interest rate
*** pv is present value
Present Value
β Reverse logic of future values
β The value of $1 in the future is worth less today
β So you will be willing to take less than $1 today instead of waiting to receive $1 one or two years from now
β This can be calculated as follows:
pv <- fv1 / (1 + r)
pv <- fv2 / ((1 + r) * (1 + r))
***fv1 is future value calculated for one year from above
***fv2 is future value calculated for two years from above
TVM Applied To Bonds
β We can apply this Time Value of Money concept to bonds
β Example:
- $100 par value, 5% coupon rate (= $5), 5 years to maturity
- Price = $100 today
Should you buy this bond?
To determine the value of the bond, we can show the cash inflow and cash outflow over time graphically.
Letβs assume today is the year βzeroβ
in which youβll pay $100 to purchase the bond shown as CF Out in below table,
Youβll receive $5 year one
through year four
. In year 5 youβll get the last coupon payment + $100 principal payment. After that, the bond matures and is no longer outstanding.
To know if itβs worth giving up $100 today, youβd need to know the present value(pv)
of the coupons and principal payments is greater than $100.
To do this, you should take the $5 in year one and calculate itβs present value and do the same for the $5 in year one
through year year four
In year five,
youβll calculate the value of the $105.
Comparing Cash Flows
The sum of the present value of those present value is equal to the value of the bond
#Using the above example i.e Bond with 5 year to maturity and has a yield of 6%, which acts as the discount rate.
# Create vector of cash flowscf <- c(5,5,5,5,105) #Create vector with cash flowcf <- data.frame(cf)# Convert to data framecf$t <- as.numeric(rownames(cf)) # Add column tcf$pv_factor <- 1 / (1 + 0.06)^cf$t # Calculate pv_factorcf$pv <- cf$cf * cf$pv_factor # Calculate pvsum(cf$pv)# Calculate the bond price95.78764
If sum of the present value exceed $100, you buy the bond.
Bond Valuation
For this section, weβll consider a simple bond:
β Fixed Annual Coupon Rate
β Fixed Maturity Date
β No Embedded Options
Value of an Asset
As a matter of economics, the value of any asset is equal to the present value of expected future cash flows.
These cash flows are discounted at the appropriate risk-adjusted discount rate and this is reflected mathematically as below.
Bonds are no different, the first step in calculating the bond value is to layout the cash flows weβre discounting.
Prior to maturity, the bond investor receives coupon payments and at maturity, the bond investor receives the last coupon payment and the par value.
We can modify the above formula to account for how these cash flows are separated from a mechanical point of view.
How do we run this analysis in βRβ
Creating a Cash Flow Vector
In βRβ, we can create a cash flow vector (cf)
by laying out the cash flows as-is.
cf <- c(c1,c2,c3,c4,c5....)
***last cash flow equals the last coupon rate + principal
Creating a Data Frame
To perform bond valuation, we need to add additional variables to the cash flow vector. To be able to do this, we need to convert our cash flow vector to a data frame.
cf <- data.frame(cf)
Creating Time Index
Because each cash flow occurs at a particular time, we need to add a time index variable. Weβll label this variable βtβ
The time index is used as the number of periods, in our example βyearsβ, that we will discount each of the bond cash flows.
cf$t <- c(1, 2, 3, 4, 5, . . . )
Calculate the Present Value(PV) Factor
Next, we will have to calculate pv
factor to discount each bond cash flow.
The discount rate for bonds is called bond yield
cf$pv_factor <- 1 / (1 + y)^cf$t
***y is discount rate
For example, if we have a discount rate of 10%. The pv
factor for cash flows received 2 years from now is
pv_factor <- 1 / (1 + .10)^2
pv_factor
[1] 0.8264463
PV of Cash Flows
The penultimate step is to calculate the present value of each of the bondsβ cash flow by multiplying each cash flow by the appropriate pv
factor
cf$pv <- cf$cf * cf$pv_factor
Finally, we sum the PV of the cash flows to arrive at the bondβs value.
Creating a Function
Letβs now create a simple function to perform the valuation of many bonds instead of one like we learned above.
Input Generalizations
β p
for par value
β r
for coupon rate
β ttm
for time to maturity
β y
for yield
cf <- c(rep(p * r, ttm - 1), p * (1 + r))
βrep(x, y) β repeats y times the value of x
- x =
p * r
= coupon payment - y =
ttm β 1
= bondβs time to maturity minus one year
βp * (1 + r)
= principal + final coupon payment
cf <- data.frame(cf) #Convert to data framecf$t <- as.numeric(rownames(cf))#create time index
- rownames() of
βcfβ
vector is equal to 1, 2, 3, 4, until theβttmβ
of bond - as.numeric() needed to ensure values are read as numbers
cf$pv_factor #Calculate PV Factor
cf$pv <- cf$cf * cf$pv_factor #Calculate PV of each cash flow
sum(cf$pv) #Sum PV to arrive at bondβs value
Now wrapping everything together
bond_price <- function(p, r, ttm, y){
cf <- c(rep(p * r, ttm - 1), p * (1 + r))
cf <- data.frame(cf)
cf$t <- as.numeric(rownames(cf))
cf$pv_factor <- 1 / (1 + y)^cf$t
cf$pv <- cf$cf * cf$pv_factor
sum(cf$pv)
}
Check if the
bond_price
function gives us a price of $95.79 for the value of a bond with a $100 par value, 5% coupon rate, 5 years to maturity, and 6% yield to maturity.
Join thousands of data leaders on the AI newsletter. Join over 80,000 subscribers and keep up to date with the latest developments in AI. From research to projects and ideas. If you are building an AI startup, an AI-related product, or a service, we invite you to consider becoming aΒ sponsor.
Published via Towards AI