*
*  BONDS.PRG
*  Manual Example 7.4
*
compute nbonds=20
all nbonds
open data bonds.xls
data(format=xls,org=cols)
*
*  The data set consists of US Treasury bonds, which have
*  semi-annual coupons, but with the coupon stated in annual terms.
*  The maturity series also provides annual information. The coupon
*  is divided by two and the maturity multiplied by 2 to give values
*  for the actual coupon period.
*
set coupon   = coupon / 2
set maturity = maturity * 2
*
nonlin a0 a1 a2
compute a0=.030,a1=a2=0.0
compute cusp=2.0
*
function BondPV bond
type real BondPV
type integer bond
*
local real mdate cdate
*
compute mdate=maturity(bond)
compute BondPV=100.0 * $
    exp(-mdate*(a0+mdate*a1+%max(mdate-cusp,0.0)*a2))
*
*        Walk backwards through the coupons.
*
compute cdate=mdate
while (cdate > 0.0) {
   compute BondPV=BondPV + coupon(bond) * $
     exp(-cdate*(a0+cdate*a1+%max(cdate-cusp,0.0)*a2))
   compute cdate=cdate-1
}
*
*  Adjust for simple interest payable by the purchaser
*  for the initial coupon. cdate will be -(fraction of period).
*
compute BondPV=BondPV+coupon(bond)*cdate
end
*
frml BondPrice value = BondPV(t)
*
nlls(robusterrors,frml=BondPrice) value
*
*   Graph the estimated yield curve from maturities of 0->10 periods (5 years).
*   After the present value function is evaluated, the maturity is switched to
*   years and the annual yield computed.
*
set testm 1 50  = .20*t
set pvalue 1 50 = $
   exp(-testm*(a0+testm*a1+%max(testm-cusp,0.0)*a2))
set testm 1 50  = testm/2
set yield 1 50  = -log(pvalue)/testm
scatter(style=line,window='Yield Curve')
# testm yield


