280 likes | 417 Views
Fixed Income. Downloads. Today’s work is in: matlab_lec09.m Functions we need today: ycurve.m Datasets we need today: data_bonds.m. Bonds. A bond is a security that pays a predefined amount at predefined future dates
E N D
Downloads • Today’s work is in: matlab_lec09.m • Functions we need today: ycurve.m • Datasets we need today: data_bonds.m
Bonds • A bond is a security that pays a predefined amount at predefined future dates • They care called fixed income securities because the payments are (usually) fixed • Note that unlike stocks, bonds are (usually) free of cash flow risk • Bonds still carry discount rate risk
Price • As with any security, the price of a bond is the discounted present value of all future cash flows • Suppose a bond pays $3 on Jan 1st 2009, $3 on Jan 1st 2010, and $103 on Jan 1st 2011 • Suppose today is Jan 1st 2008 and you expect the discount rate to be 2% in 2008, 3% in 2009, and 4% in 2010 • The bond’s price is
Yield • Note that in the above example the discount rate was not constant! • We can try to find a constant discount rate that would make the bond’s actual price equal to the discounted value of cash flows. This discount rate is called the Yield • Note that the yield is not the “true” discount rate • For the above bond, the yield is
Institutional Details • In the U.S. most bonds have coupons which are paid every 6 months • Coupon payments are quoted as an annual percent of the principle • ie if coupon is 3% bond pays $1.5 twice per year • At the time the bond matures, the owner receives the principal and one last coupon payment • A bond that matures on Jan 1st 2010 and has a 4% coupon rate has payments of: $102 on Jan 1st 2010, $2 on July 1st 2009, $2 on Jan 1st 2009 …
Institutional Details • If I buy a bond with 2 months left until the coupon payment, I will receive the full coupon payment I am entitled to all future payments • The price is the present value of all future payments, this is called the “dirty” price and is the true out of pocket cost to buyer • This is the only number we should care about or know • Banks do not quote the dirty price but rather “clean” price • ClnP = DrtP – AccrInt • Accrued Interest = Coupon*(6-MonthUntilCoupon) • Buyer pays DrtP=ClnP+AccrInt • Just after coupon is paid, AccrInt=0 so ClnP=DrtP • To avoid unnecessary complications we will only look at bonds close to after coupon paid so that ClnP≈DrtP
ConstructingDataset • This data set is being constructed on Oct 3, 2008 • Data comes from Bloomberg screen on trading floor • Could also get data from WSJ: http://online.wsj.com/mdc/public/page/mdc_bonds.html?mod=mdc_topnav_2_3000 • We will construct the vector maturity: >>maturity(1)=2009+4/12; • We will construct the vector price: >>price(1)=100+33.5/36 %prices quoted as fraction of 36 %we are given bid and ask, take midpoint • We will construct the vector coupon: >>coupon(1)=3+1/8;
Load Data >>data_bonds; >>N=length(maturity); %number of bonds >>calendar=[2008+(9/12):(1/12):2030]'; >>T=length(calendar); >>startdate=2008+(10/12)+((3/31)/12);
Construct CF >>CF=zeros(T,N); %make matrix of cashflows >>for i=1:N; [a Tmat]=min(abs(maturity(i)-calendar)); CF(Tmat,i)=100+coupon(i)*.5; for t=1:Tmat-1; if mod(t,6)==0 & calendar(Tmat-t)>startdate; CF(Tmat-t,i)=coupon(i)*.5; end; end; end;
Construct CF >> CF(1:20,1:6) ans = 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 101.5625 102.2500 1.6875 1.8125 2.0000 1.0625 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 101.6875 101.8125 2.0000 1.0625 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 102.0000 101.0625
Calculating Yield >> for i=1:N; prerrbest=100000000; for j=1:1000; y=0+.2*(j-1)/(1000-1); py=sum(CF(:,i)./((1+y).^(calendar-startdate))); prerr=abs(price(i)-py); if prerr<prerrbest; prerrbest=prerr; yieldbest(i)=y; end; end; end; >> plot(maturity,yieldbest,'.'); >> xlabel('Maturity'); ylabel('Yield');
Calculating Yield • Note that yield increases with maturity, this is typical • However, this is not what is known as the yield curve (though it is related)
The Yield Curve • A zero-coupon bond is a bond that has no coupon payments and only pays the principal at maturity • For such a bond yT=rT where r is the rate of return and T is time until maturity • Note that any other bond can be constructed with a portfolio of “zeros” so if we know the prices (or yields) of “zeros” of every maturity we can price any other bond • The Yield curve is the yield on zero coupon bonds of every maturity • Also called Term Structure of Interest Rates • Note that we have already broken up all of our bonds into “zeros” within the matrix CF • Now we just need a yield for each point in time which will make each bond price (almost) agree with the price of the cash flows
Constructingthe Yield Curve • We will not solve for a yield for every date but rather at a few different dates and then interpolate between them %motnhs in which we will solve for yield >>yieldgriddate=[6 12 18 24 30 36 42 48 60 72 96 120 180 T]'; %actual dates of those months >>yielddate=calendar(yieldgriddate); %initial guess (these are yields of bonds at various maturities taken from printout) >>y0=[1.0123 1.0157 1.0150 1.0158 1.0175 1.0204 1.0228 1.0238 1.027 1.028 1.033 1.037 1.042 1.042]';
ycurve.m function x=ycurve(yieldgrid,yielddate,calendar,startdate,CF,price,N,T); %first interpolate to get yield for every date in dataset for t=1:T; [a b]=min(abs(yielddate-calendar(t))+10000*(yielddate>=calendar(t))); if b==length(yielddate); b=b-1; end; mult=(calendar(t)-yielddate(b))/(yielddate(b+1)-yielddate(b)); yield(t,1)=yieldgrid(b)+mult*(yieldgrid(b+1)-yieldgrid(b)); end; %next calculate the discounted present value of CF and compare to price for i=1:N; err(i)=price(i)-sum(CF(:,i)./(yield.^(calendar([1:T]')-startdate))); end; x=mean(abs(err));
Constructingthe Yield Curve • ycurve.m takes in any yield curve and return the pricing error from that curve, we want to make that error as small as possible • fminsearch.m can minimize errors, its inputs are a function, and a set of initial values; it will then search over values to find the minimum of the function • Sometimes you have to apply fminsearch.m more than once to get to “better” minimum
Constructingthe Yield Curve >>y1=fminsearch(@ycurve,y0,[],yielddate,calendar,startdate,CF,price,N,T); >>y2=fminsearch(@ycurve,y1,[],yielddate,calendar,startdate,CF,price,N,T); >>y3=fminsearch(@ycurve,y2,[],yielddate,calendar,startdate,CF,price,N,T); %check minimum values: >> disp([ycurve(y0,yielddate,calendar,startdate,CF,price,N,T) ... ycurve(y1,yielddate,calendar,startdate,CF,price,N,T) ... ycurve(y2,yielddate,calendar,startdate,CF,price,N,T) ... ycurve(y3,yielddate,calendar,startdate,CF,price,N,T)]); 3.1012 0.5914 0.5521 0.5518 %plot the yield curve >>plot(yielddate,y3,'LineWidth',3); • The yield curve is upward sloping, this is typical • This suggests expectations of higher interest rates in the future and/or more risk at longer maturities • Sometimes (rarely) yield curves are downward sloping • This is called “inverted” and often precedes recessions • Suggests expectations of lower interest rates and/or less risk at longer maturities