Do Yahoo Finance S&P 500 adjusted prices take into account dividend yields? The answer depends on whether you are working with the index or the ETF. In the case of the SPY, then the answer is yes. By looking into close-to-close returns, this vignette illustrates the consistency with the famous data reported by Prof. Damodaran. However, this does not seem to be the case for the S&P 500 index.

The Case for the SPY

We begin with downloading data from Yahoo Finance for the SPY ETF:

library(quantmod)
library(lubridate)
library(rvest)


getSymbols("SPY",from = "1990-01-01")
'indexClass<-' is deprecated.
Use 'tclass<-' instead.
See help("Deprecated") and help("xts-deprecated").
[1] "SPY"
P <- SPY[,6]
R <- na.omit(P/lag(P)) - 1
R <- R["1994-01-01/2020-12-31",]
R_y <- apply.yearly(R,function(x) prod(x + 1) - 1 )
plot(R_y)

Now, let’s scrap the table from Prof. Damodaran’s website:

theurl <- "http://pages.stern.nyu.edu/~adamodar/New_Home_Page/datafile/histretSP.html"
file <- read_html(theurl)
tables <- html_nodes(file, "table")

# try extract each into a data.frame
tables.list <- numeric()
for (i in 1:length(tables)) { 
  tables.list[i] <- list(try(html_table(tables[i], fill = TRUE),silent = T))
}

Table <- tables.list[[1]][[1]]
head(Table)

We note that the above tables needs some adjustment. In this case, we care about columns 1 and 2:

snp <- Table$X2
snp <- na.omit(as.numeric(gsub("%","",snp)))
NAs introduced by coercion
y <- na.omit(as.numeric(Table$X1))
NAs introduced by coercion
snp <- snp[y >= min(year(R_y))]
y <- y[y >= min(year(R_y)) ]
snp <- data.frame(y,snp)
tail(snp)

Finally, let’s merge altogether:


R_y <- data.frame(y = year(R_y),SPY = as.numeric(R_y)*100)
ds <- merge(snp,R_y)

plot(snp~y, data = ds, ylab = "",
     xlab = "year", 
     main = "Annual Returns on S&P 500 including Dividends",
     pch = 20)
points(SPY~y, data = ds, col = 2,lwd = 2)
legend("bottomleft",c("Prof. Damodaran","Yahoo SPY"), pch = c(20,1), col = 1:2)

We observe that both data are consistent over the full sample period between 1994 and 2020.

The Case for the Index

Let’s repeat the above, however, for the case of the S&P 500 index:


getSymbols("^GSPC",from = "1990-01-01")
'indexClass<-' is deprecated.
Use 'tclass<-' instead.
See help("Deprecated") and help("xts-deprecated").
[1] "^GSPC"
SPY <- GSPC
P <- SPY[,6]
R <- na.omit(P/lag(P)) - 1
R <- R["1994-01-01/2020-12-31",]
R_y <- apply.yearly(R,function(x) prod(x + 1) - 1 )

R_y <- data.frame(y = year(R_y),SPY = as.numeric(R_y)*100)
ds <- merge(snp,R_y)

plot(snp~y, data = ds, ylab = "",
     xlab = "year", 
     main = "Annual Returns on S&P 500 including Dividends",
     pch = 20)
points(SPY~y, data = ds, col = 2,lwd = 2)
legend("bottomleft",c("Prof. Damodaran","Yahoo S&P 500 Index"), pch = c(20,1), col = 1:2)

We note the discrepancy between the two.

Takeaway

While the Yahoo Finance data takes into account adjustment in terms of stock splits and dividend, it is important to pay attention to whether this is the case in when it comes to working with the adjusted prices. We observe that the adjusted prices for the SPY ETF do take into considerations dividend yields.

LS0tCnRpdGxlOiAiWWFob28gRmluYW5jZSBhbmQgRGl2aWRlbmQgWWllbGRzIgphdXRob3I6ICJNYWplZWQgU2ltYWFuIgpkYXRlOiAiQXByaWwgMjgsIDIwMjEiCm91dHB1dDoKICBodG1sX25vdGVib29rOiBkZWZhdWx0CiAgaHRtbF9kb2N1bWVudDoKICAgIGRmX3ByaW50OiBwYWdlZAogIHBkZl9kb2N1bWVudDogZGVmYXVsdAotLS0KCkRvIFlhaG9vIEZpbmFuY2UgU1wmUCA1MDAgYWRqdXN0ZWQgcHJpY2VzIHRha2UgaW50byBhY2NvdW50IGRpdmlkZW5kIHlpZWxkcz8gVGhlIGFuc3dlciBkZXBlbmRzIG9uIHdoZXRoZXIgeW91IGFyZSB3b3JraW5nIHdpdGggdGhlIGluZGV4IG9yIHRoZSBFVEYuIEluIHRoZSBjYXNlIG9mIHRoZSAqKlNQWSoqLCB0aGVuIHRoZSBhbnN3ZXIgaXMgKip5ZXMqKi4gQnkgbG9va2luZyBpbnRvIGNsb3NlLXRvLWNsb3NlIHJldHVybnMsIHRoaXMgdmlnbmV0dGUgaWxsdXN0cmF0ZXMgdGhlIGNvbnNpc3RlbmN5IHdpdGggdGhlIGZhbW91cyBkYXRhIHJlcG9ydGVkIGJ5IFtQcm9mLiBEYW1vZGFyYW5dKGh0dHBzOi8vdC5jby9WMHpNZ0FlUnhYP2FtcD0xKS4gSG93ZXZlciwgdGhpcyBkb2VzIG5vdCBzZWVtIHRvIGJlIHRoZSBjYXNlIGZvciB0aGUgU1wmUCA1MDAgaW5kZXguCgojIFRoZSBDYXNlIGZvciB0aGUgU1BZCldlIGJlZ2luIHdpdGggZG93bmxvYWRpbmcgZGF0YSBmcm9tIFlhaG9vIEZpbmFuY2UgZm9yIHRoZSBTUFkgRVRGOgpgYGB7cn0KbGlicmFyeShxdWFudG1vZCkKbGlicmFyeShsdWJyaWRhdGUpCmxpYnJhcnkocnZlc3QpCgoKZ2V0U3ltYm9scygiU1BZIixmcm9tID0gIjE5OTAtMDEtMDEiKQpQIDwtIFNQWVssNl0KUiA8LSBuYS5vbWl0KFAvbGFnKFApKSAtIDEKUiA8LSBSWyIxOTk0LTAxLTAxLzIwMjAtMTItMzEiLF0KUl95IDwtIGFwcGx5LnllYXJseShSLGZ1bmN0aW9uKHgpIHByb2QoeCArIDEpIC0gMSApCnBsb3QoUl95KQoKYGBgCgoKTm93LCBsZXQncyBzY3JhcCB0aGUgdGFibGUgZnJvbSBQcm9mLiBEYW1vZGFyYW4ncyB3ZWJzaXRlOiAKYGBge3J9CnRoZXVybCA8LSAiaHR0cDovL3BhZ2VzLnN0ZXJuLm55dS5lZHUvfmFkYW1vZGFyL05ld19Ib21lX1BhZ2UvZGF0YWZpbGUvaGlzdHJldFNQLmh0bWwiCmZpbGUgPC0gcmVhZF9odG1sKHRoZXVybCkKdGFibGVzIDwtIGh0bWxfbm9kZXMoZmlsZSwgInRhYmxlIikKCiMgdHJ5IGV4dHJhY3QgZWFjaCBpbnRvIGEgZGF0YS5mcmFtZQp0YWJsZXMubGlzdCA8LSBudW1lcmljKCkKZm9yIChpIGluIDE6bGVuZ3RoKHRhYmxlcykpIHsgCiAgdGFibGVzLmxpc3RbaV0gPC0gbGlzdCh0cnkoaHRtbF90YWJsZSh0YWJsZXNbaV0sIGZpbGwgPSBUUlVFKSxzaWxlbnQgPSBUKSkKfQoKVGFibGUgPC0gdGFibGVzLmxpc3RbWzFdXVtbMV1dCmhlYWQoVGFibGUpCmBgYAoKV2Ugbm90ZSB0aGF0IHRoZSBhYm92ZSB0YWJsZXMgbmVlZHMgc29tZSBhZGp1c3RtZW50LiBJbiB0aGlzIGNhc2UsIHdlIGNhcmUgYWJvdXQgY29sdW1ucyAxIGFuZCAyOgpgYGB7cn0Kc25wIDwtIFRhYmxlJFgyCnNucCA8LSBuYS5vbWl0KGFzLm51bWVyaWMoZ3N1YigiJSIsIiIsc25wKSkpCnkgPC0gbmEub21pdChhcy5udW1lcmljKFRhYmxlJFgxKSkKc25wIDwtIHNucFt5ID49IG1pbih5ZWFyKFJfeSkpXQp5IDwtIHlbeSA+PSBtaW4oeWVhcihSX3kpKSBdCnNucCA8LSBkYXRhLmZyYW1lKHksc25wKQp0YWlsKHNucCkKYGBgCgpGaW5hbGx5LCBsZXQncyBtZXJnZSBhbHRvZ2V0aGVyOgpgYGB7cn0KClJfeSA8LSBkYXRhLmZyYW1lKHkgPSB5ZWFyKFJfeSksU1BZID0gYXMubnVtZXJpYyhSX3kpKjEwMCkKZHMgPC0gbWVyZ2Uoc25wLFJfeSkKCnBsb3Qoc25wfnksIGRhdGEgPSBkcywgeWxhYiA9ICIiLAogICAgIHhsYWIgPSAieWVhciIsIAogICAgIG1haW4gPSAiQW5udWFsIFJldHVybnMgb24gUyZQIDUwMCBpbmNsdWRpbmcgRGl2aWRlbmRzIiwKICAgICBwY2ggPSAyMCkKcG9pbnRzKFNQWX55LCBkYXRhID0gZHMsIGNvbCA9IDIsbHdkID0gMikKbGVnZW5kKCJib3R0b21sZWZ0IixjKCJQcm9mLiBEYW1vZGFyYW4iLCJZYWhvbyBTUFkiKSwgcGNoID0gYygyMCwxKSwgY29sID0gMToyKQoKYGBgCldlIG9ic2VydmUgdGhhdCBib3RoIGRhdGEgYXJlIGNvbnNpc3RlbnQgb3ZlciB0aGUgZnVsbCBzYW1wbGUgcGVyaW9kIGJldHdlZW4gMTk5NCBhbmQgMjAyMC4KCiMgVGhlIENhc2UgZm9yIHRoZSBJbmRleApMZXQncyByZXBlYXQgdGhlIGFib3ZlLCBob3dldmVyLCBmb3IgdGhlIGNhc2Ugb2YgdGhlIFNcJlAgNTAwIGluZGV4OgpgYGB7cn0KZ2V0U3ltYm9scygiXkdTUEMiLGZyb20gPSAiMTk5MC0wMS0wMSIpClNQWSA8LSBHU1BDClAgPC0gU1BZWyw2XQpSIDwtIG5hLm9taXQoUC9sYWcoUCkpIC0gMQpSIDwtIFJbIjE5OTQtMDEtMDEvMjAyMC0xMi0zMSIsXQpSX3kgPC0gYXBwbHkueWVhcmx5KFIsZnVuY3Rpb24oeCkgcHJvZCh4ICsgMSkgLSAxICkKClJfeSA8LSBkYXRhLmZyYW1lKHkgPSB5ZWFyKFJfeSksU1BZID0gYXMubnVtZXJpYyhSX3kpKjEwMCkKZHMgPC0gbWVyZ2Uoc25wLFJfeSkKCnBsb3Qoc25wfnksIGRhdGEgPSBkcywgeWxhYiA9ICIiLAogICAgIHhsYWIgPSAieWVhciIsIAogICAgIG1haW4gPSAiQW5udWFsIFJldHVybnMgb24gUyZQIDUwMCBpbmNsdWRpbmcgRGl2aWRlbmRzIiwKICAgICBwY2ggPSAyMCkKcG9pbnRzKFNQWX55LCBkYXRhID0gZHMsIGNvbCA9IDIsbHdkID0gMikKbGVnZW5kKCJib3R0b21sZWZ0IixjKCJQcm9mLiBEYW1vZGFyYW4iLCJZYWhvbyBTJlAgNTAwIEluZGV4IiksIHBjaCA9IGMoMjAsMSksIGNvbCA9IDE6MikKCmBgYApXZSBub3RlIHRoZSBkaXNjcmVwYW5jeSBiZXR3ZWVuIHRoZSB0d28uCgojIFRha2Vhd2F5CldoaWxlIHRoZSBZYWhvbyBGaW5hbmNlIGRhdGEgdGFrZXMgaW50byBhY2NvdW50IGFkanVzdG1lbnQgaW4gdGVybXMgb2Ygc3RvY2sgc3BsaXRzIGFuZCBkaXZpZGVuZCwgaXQgaXMgaW1wb3J0YW50IHRvIHBheSBhdHRlbnRpb24gdG8gd2hldGhlciB0aGlzIGlzIHRoZSBjYXNlIGluIHdoZW4gaXQgY29tZXMgdG8gd29ya2luZyB3aXRoIHRoZSBhZGp1c3RlZCBwcmljZXMuIFdlIG9ic2VydmUgdGhhdCB0aGUgYWRqdXN0ZWQgcHJpY2VzIGZvciB0aGUgU1BZIEVURiBkbyB0YWtlIGludG8gY29uc2lkZXJhdGlvbnMgZGl2aWRlbmQgeWllbGRzLiAKCgoKCgoK