Skip to content

Instantly share code, notes, and snippets.

@ivannp
Last active November 28, 2017 20:14
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save ivannp/f989a2d25f4efbbbb9d547767fdd15c0 to your computer and use it in GitHub Desktop.
Save ivannp/f989a2d25f4efbbbb9d547767fdd15c0 to your computer and use it in GitHub Desktop.
POTUS Rallies since Election Day
require(quantmod)
require(ggplot2)
require(ggthemes)
# The starting index in the elections dates and president's arrays
# start.index = 7
start.index = 6
# sp = getSymbols("^GSPC", from="1900-01-01", auto.assign=F)
sp = as.xts(read.csv.zoo('dji.csv', format='%Y%m%d', header=F, sep=",")[,1:4])
colnames(sp) = c("open","high","low","close")
index(sp) = as.Date(index(sp))
ydji = getSymbols("^DJI", from="1900-01-01", auto.assign=F)
ii = match(first(index(ydji)), index(sp))
sp = rbind(Cl(sp[1:(ii-1)]), Cl(ydji))
colnames(sp) = c("close")
sp = sp["1950/"]
# TODO Remove. Temp hack to add closing date prior to EOD.
# aa = xts(23328.36, order.by=as.Date("2017-10-20"))
# colnames(aa) = "close"
# sp = rbind(sp, aa)
election.dates = c("1932-11-08", "1936-11-03",
"1940-11-05", "1944-11-07", "1948-11-02",
"1952-11-04", "1956-11-06",
"1960-11-08", "1964-11-03", "1968-11-05",
"1972-11-07", "1976-11-02",
"1980-11-04", "1984-11-06", "1988-11-08",
"1992-11-03", "1996-11-05",
"2000-11-07", "2004-11-02", "2008-11-04",
"2012-11-06", "2016-11-08")
presidents = c("Roosevelt", "Roosevelt 2nd",
"Roosevelt 3rd", "Roosevelt/Truman", "Truman",
"Eisenhower", "Eisenhower 2nd",
"Kennedy/Johnson", "Johnson", "Nixon",
"Nixon/Ford", "Carter",
"Reagen", "Reagen 2nd", "H.W. Bush",
"Clinton", "Clinton 2nd",
"W. Bush", "W. Bush 2nd", "Obama",
"Obama 2nd", "Trump")
election.dates = election.dates[start.index:NROW(election.dates)]
presidents = presidents[start.index:NROW(presidents)]
potus.date = election.dates[NROW(election.dates)]
potus.start = findInterval(as.Date(potus.date), index(sp))
cat("\n")
cat("Marked start date: ", as.character(head(index(sp), 1)), "\n")
cat("Marked last date: ", as.character(tail(index(sp), 1)), "\n")
# potus.rets = ROC(Cl(sp)[potus.start:NROW(sp)], n=1, type="discrete", na.pad=FALSE)
days.elected = NROW(sp) - potus.start
cat("POTUS days since election: ", days.elected, "\n")
rets = ROC(Cl(sp), n=days.elected, type="discrete", na.pad=FALSE)
r = na.trim(rets)
rets.mean = mean(r)
cat("The average return over ", days.elected, " day is ", round(100*rets.mean, 2), "%\n", sep="")
current.ret = as.numeric(last(rets))
cat(round(100*ecdf(x=as.numeric(na.trim(rets)))(current.ret), 0), "% of the time, the returns over ", days.elected, " days have been lower\n", sep="")
cat("This is ", round((current.ret - rets.mean)/sd(r), 2), " standard deviations from the mean\n")
ret = as.numeric(tail(r, 1))
q = qnorm(ret, rets.mean, sd(r), lower.tail=F)
# cat("The current return of ", round(100*ret, 2), "% is in the ", round(q, 4), " quantile\n", sep="")
cat("\n")
r = na.trim(lag.xts(rets, k=-days.elected))
s = r
# last.date = last(index(daily.rets[paste0(ed, "/", sep="")])[1:days.elected])
r = r[findInterval(as.Date(election.dates), index(r))]
last.dates = index(sp)[findInterval(as.Date(election.dates), index(sp)) + days.elected]
df = data.frame(Date=index(r), LastDate=last.dates, Return=round(100*as.numeric(r[,1]),2), President=presidents, row.names=NULL)
# Compute inflation
cpi = getSymbols("CPIAUCNS", src="FRED", since="1900-01-01", auto.assign = F)
inflation = c()
for(i in 1:NROW(last.dates)) {
start.date = index(sp)[findInterval(as.Date(election.dates[i]), index(sp))]
a = cpi[paste0(start.date, "/", last.dates[i])]
inflation[i] = round(100*(as.numeric(last(a))/as.numeric(first(a)) - 1), 2)
}
df = cbind(df, data.frame(Inflation=inflation))
top5 = head(sort.int(df[,'Return'], decreasing=T, index.return=T)$ix, 5)
print(df)
# Add all presidents, day by day
daily.rets = ROC(Cl(sp), n=1, type="discrete", na.pad=FALSE)
df = NULL
for(i in 1:NROW(election.dates)) {
ed = election.dates[i]
start.id = findInterval(as.Date(ed), index(daily.rets))
#r = c(0, head(daily.rets[paste0(ed, "/", sep="")], days.elected))
r = c(0, daily.rets[(start.id+1):(start.id + days.elected)])
r = (cumprod(1+r) - 1)*100
df = if(is.null(df)) data.frame(r) else cbind(df, data.frame(r))
}
colnames(df) = c(presidents)
rownames(df) = NULL
df = cbind(data.frame(Day=0:days.elected), df[,top5])
print(tail(df))
df = df[,2:NCOL(df)]
write.csv(df, 'rallies.csv', quote=F, row.names=F)
# Rename the columns
# colnames(df) = gsub(" ", "_", colnames(df), fixed=T)
# colnames(df) = paste0("col", 1:NCOL(df))
if(F) {
# Plot
gg = ggplot(df)
gg = gg + xlab("Days")
gg = gg + ylab("Advance (%)")
line.names = colnames(df)
col.names = colnames(df)
for(ii in 1:NROW(line.names)) {
color.str = paste("\"", line.names[ii], "\"", sep="")
gg = gg + geom_line(aes_string(x=1:NROW(df), y=col.names[ii], color=color.str))
}
# if(!missing(x.scale)) {
# gg = gg + scale_x_continuous(breaks=x.scale)
# }
#gg = gg + theme_solarized(base_size=16, base_family="verdana", light=TRUE)
#gg = gg + theme_wsj(base_size=16, base_family="verdana")
#gg = gg + theme_economist(base_size=16, base_family="verdana")
gg = gg + theme_igray(base_size=16, base_family="verdana")
gg = gg + theme(panel.background=element_rect(colour="grey60"))
gg = gg + theme(plot.title=element_blank())
gg = gg + theme(plot.background=element_rect(fill="white"))
#gg = gg + theme(axis.ticks=element_line(colour="grey90"))
#gg = gg + theme(axis.line=element_line(colour="grey60"))
#gg = gg + theme(legend.title=element_blank())
#gg = gg + theme(legend.background=element_rect(fill="white", colour="#dddddd", size=0.4))
}
@MarioHoH
Copy link

Where can I get the dataset?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment