[R-SIG-Finance] Excel Price function in R for Bonds
Amelia Marsh
amelia_marsh08 at yahoo.com
Sun Sep 27 20:22:34 CEST 2015
Dear Forum,
I am using trying to find price of bond in R. I have written the code in line with Excel PRICE formula. However, whenever the residual maturity is less than a year, my R output tallies with the Excel Price formula. However, moment my residual maturity exceeds 1 year, the R output differs from Excel Price function. I have tried to find out the reason for am not able to figure out.
Please guide me. Here is my code alongwith illustrative examples -
(I am copying this code from notepad++. Please forgive forgive for any inconvenience caused)
# MY code
add.months = function(date, n) {
nC <- seq(date, by=paste (n, "months"), length = 2)[2]
fD <- as.Date(strftime(as.Date(date), format='%Y-%m-01'))
C <- (seq(fD, by=paste (n+1, "months"), length = 2)[2])-1
if(nC>C) return(C)
return(nC)
}
# ________________________________________________________________________
date.diff = function(end, start, basis=1) {
if (basis != 0 && basis != 4)
return(as.numeric(end - start))
e <- as.POSIXlt(end)
s <- as.POSIXlt(start)
d <- (360 * (e$year - s$year)) +
( 30 * (e$mon - s$mon )) +
(min(30, e$mday) - min(30, s$mday))
return (d)
}
# ________________________________________________________________________
excel.price = function(settlement, maturity, coupon, yield, redemption, frequency, basis=1)
{
cashflows <- 0
last.coupon <- maturity
while (last.coupon > settlement) {
last.coupon <- add.months(last.coupon, -12/frequency)
cashflows <- cashflows + 1
}
next.coupon <- add.months(last.coupon, 12/frequency)
valueA <- date.diff(settlement, last.coupon, basis)
valueE <- date.diff(next.coupon, last.coupon, basis)
valueDSC <- date.diff(next.coupon, settlement, basis)
if (cashflows == 0)
stop('number of coupons payable cannot be zero')else
if (cashflows == 1)
{
valueDSR = valueE - valueA
T1 = 100 * coupon / frequency + redemption
T2 = (yield/frequency * valueDSR/valueE) + 1
T3 = 100 * coupon / frequency * valueA / valueE
result = (T1 / T2) - T3
return(result = result)
}else
if (cashflows > 1)
{
expr1 <- 1 + (yield/frequency)
expr2 <- valueDSC / valueE
expr3 <- coupon / frequency
result <- redemption / (expr1 ^ (cashflows - 1 + expr2))
for (k in 1:cashflows) {
result <- result + ( 100 * expr3 / (expr1 ^ (k - 1 + expr2)) )
}
result <- result - ( 100*expr3 * valueA / valueE )
return(result = result)
}
}
# ________________________________________________________________________
(ep1 = excel.price(settlement = as.Date(c("09/15/24"), "%m/%y/%d"), maturity = as.Date(c("11/15/4"), "%m/%y/%d"), coupon = 0.065, yield = 0.05904166667, redemption = 100, frequency = 2, basis = 1))
(ep2 = excel.price(settlement = as.Date(c("09/15/24"), "%m/%y/%d"), maturity = as.Date(c("7/16/22"), "%m/%y/%d"), coupon = 0.0725, yield = 0.0969747125, redemption = 100, frequency = 2, basis = 1))
(ep3 = excel.price(settlement = as.Date(c("09/15/24"), "%m/%y/%d"), maturity = as.Date(c("11/16/30"), "%m/%y/%d"), coupon = 0.08, yield = 0.0969747125, redemption = 100, frequency = 2, basis = 1))
# .......................................................................................................................................
# OUTPUT
ep1 = 100.0494
Excel output = 100.0494
ep2 = 98.0815
Excel output = 98.08149
ep3 = 98.12432
Excel output = 98.122795
While ep1 and ep2 match exactly with Excel Price function values, ep3 which has maturity exceeding one year doesnt tally with Excel Price function.
Kindly advise
With regards
Amelia
More information about the R-SIG-Finance
mailing list