Bond Timer for S&P500

It is late and I am tired, but I wanted to quickly explore an idea, where I use the ratio of the S&P500 divided by the US 10yr Treasury note yield as the trigger for when to get in and out of the S&P500. I have lots of things to check to see if this spurious or not, but none the less this is the code I came up with.

But before we look at the code you can see some nice out performance of the index. I haven’t factored in transaction costs or spread. Will check and amend if this is likely to be material.



Some visuals of the indicators


Finally the code:  [Post script: On the 25th of December I improved on the findings originally posted here. I don’t like to delete my workings as I like to have a source of reference for the progression of my thinking.]

start<- "1962-01-02"
#get the data (S&P500 and US 10yr Treasury)
spy<- Quandl("YAHOO/INDEX_GSPC", authcode="kvYEqCqKCTyL4anWz5Zv", type="xts")
bond<- Quandl("FRED/DGS10", authcode="kvYEqCqKCTyL4anWz5Zv", type="xts")
data<- merge(spy[,6],bond[,1])
data<- data["1962::"]
# This is the magic signal or is it? It is the Nominal Price of the S&P500 / bond yield. 
# The fact that it is nominal worries me. 
ratio<- data[,1]/data[,2]
ratio<- na.omit(ratio)
# moving averages of the ratio
ratio_short<- rollmean(ratio, k=20, align= "right")
ratio_long<- rollmean(ratio, k=100, align= "right")
# I like visual references ignore the red errors in the output console I am too lazy to fix up the axis.
plot(data[,1], main="Mike's Bond Timer")
plot(ratio_long, col ='red')
plot(ratio_short, col ='green')
plot(ratio, col ='blue')
#our baseline, unfiltered results
ret <- ROC(data[,1])
#our comparision, filtered result. The idea being to trade the ratio while it is above the long term m.average
sig_long <- Lag(ifelse(ratio > ratio_long, 1, 0))
sig_short <- Lag(ifelse(ratio > ratio_short, 1, 0))
sig_long <- ret * sig_long
sig_short <- ret * sig_short
btimer<- cbind(sig_long, sig_short, ret)
colnames(btimer) = c('BT Long', 'BT Short','Buy&Hold')
table.AnnualizedReturns(btimer, Rf= 0.02/252)
charts.PerformanceSummary(btimer, Rf = 0.02, main="Bond Timer",geometric=FALSE)

Created by Pretty R at


One thought on “Bond Timer for S&P500

  1. Pingback: Bond Timer for S&P500 (Part 2) | Sefirot Capital

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s