Sunday, April 17, 2011

Historical Sources of Bond Returns-Comparison of Daily to Monthly

Thanks so much for the comment on my last post Historical Bond Price and Total Returns from 10y Yield Series

“I know this might sound antithetical to a bond guy, but won't the monthly series get you close enough? “

which proved me wrong and allowed me to get nine additional years of history.  The question caused me to go one step further in proving my statement “…but monthly yields from Shiller and Fed are averages of the daily yields and not month-end values.  Applying this method to these month averages does not work.”  This monthly averaging has caused many problems in the past for me, but in this case, it does not matter.  We can see the difference in monthly averaging (GS10) and month-end daily values (DGS10) in this chart.

From TimelyPortfolio

However, if we look at the price and total return series from both, the differences are insignificant.

From TimelyPortfolio

Now that I have cleared that up, I can continue Bond Market as a Casino Game with data back to 1953.

R code:

#do everything twice to compare monthly average to daily


getSymbols("DGS10",src="FRED") #load daily US Treasury 10y from Fed Fred
getSymbols("GS10",src="FRED") # load monthly average US 10y from Fed Fred

#Fed monthly series of yields is the monthly average of daily yields
#Shiller series also is monthly average
#to calculate returns monthly average does not work
#so we get daily, take monthend with to.monthly
#and unfortunately the series does not go back as far
#set index to yyyy-mm-dd format rather than to.monthly mmm yyy for better merging later
DGS10pricereturn<-DGS10  #set this up to hold price returns

colnames(DGS10pricereturn)<-"PriceReturn-daily to monthly DGS10"
#I know I need to vectorize this but not qualified enough yet
#Please feel free to comment to show me how to do this
for (i in 1:(NROW(DGS10)-1)) {
    maturityDate= advance("UnitedStates/GovernmentBond", Sys.Date(), 10, 3),

colnames(GS10pricereturn)<-"PriceReturn-monthly avg GS10"
#I know I need to vectorize this but not qualified enough yet
#Please feel free to comment to show me how to do this
for (i in 1:(NROW(GS10)-1)) {
    maturityDate= advance("UnitedStates/GovernmentBond", Sys.Date(), 10, 3),

#total return will be the price return + yield/12 for one month
colnames(DGS10totalreturn)<-"Total Return-daily to monthly DGS10"
#total return will be the price return + yield/12 for one month
colnames(GS10totalreturn)<-"TotalReturn-monthly avg GS10"

chartSeries(DGS10,TA="addTA(GS10,on=1);addTA((DGS10-GS10)/100)",name="Comparison of DGS10 and GS10",theme="white")
mtext("Source: Federal Reserve FRED",side=1,adj=0)

charts.PerformanceSummary(merge(DGS10pricereturn,DGS10totalreturn,GS10pricereturn,GS10totalreturn),ylog=TRUE,colorset=c("cadetblue","darkolivegreen3","goldenrod","gray70"),main="Simulated Returns from US10y Yield")
mtext("Source: Federal Reserve FRED",side=1,adj=0)


  1. Thanks for posting this. If I recall correctly, GFD uses (or used) similar assumptions to generate some of their long series. At any rate, it should be a reasonable proxy for many uses.

    Don't worry too much about vectorizing here, for a few reasons. First, I think that FixedRateBondPriceByYield isn't vectorized, so that will require you to loop somehow (whether using apply or a for loop). Second, this code isn't likely to get used often, so readable code is preferable (what does it do, again? Oh, right...). As such, it's unlikely to be much of a bottleneck for anyone.

  2. How would you go about converting 3 month T Bills yields to total returns? I experimented with the following code, but I'm obviously missing something because total returns are negative. I appreciate your help and your very informative blog. Michael

    #load 3-Month Treasury Bill from FRED
    TB3M = getSymbols("TB3MS",src="FRED",auto.assign = FALSE)

    TB3M_pricereturn = TB3M;
    TB3M_pricereturn[1] = 0;

    for (i in 1:(NROW(TB3M)-1)) {
    maturityDate= advance("UnitedStates/GovernmentBond", Sys.Date(), 3, 2))[1]/100-1

    #interest return will be yield/12 for one month
    TB3M_interestreturn = lag(TB3M,k=1)/12/100

    #total return will be the price return + interest return
    TB3M_totalreturn = TB3M_pricereturn + TB3M_interestreturn