• John Hawver

Earnings Season, Visualized


Earnings season is here. I thought it would be interesting to take one of my csv reports and make the information easier to visually digest. The plot is below, the code at the end of the post, and I’ve added this as a new pdf report for the site, so it will update weekly like the others.





For long-term investors, earnings season can largely be ignored (see my earlier post on market noise). If earnings are going to dramatically disappoint, generally that information is telegraphed by the company well ahead of their earnings date. Occasionally there are surprises. However, in the long-term, these tend to wash out, especially if you’re invested in ETF’s.


Traders, on the other hand, live for earnings. It provides much sought after volatility. Options traders can get long or short around the earnings dates and HFT firms can trade the events. Interestingly, the volatility models for earnings dates vary quite a bit from firm to firm. Some model it with a single distribution, others use bi-modal distributions. That uncertainty provides opportunity. Unless you’re a professional options trader I wouldn’t recommend getting involved.


Finally, earnings themselves can be modeled predictively. Not unlike trying to predict stock returns using statistical methods, earnings can be modeled with a few factors using constrained regressions, and even to some extent using time series models.


Not a long post, and no great insight. But I hope you enjoy the plot, gives a better look at the calendar ahead.


Good luck.


John




***** Code to Replicate *****


library(ggplot2)


# Get the Data

earnings_data <- read.csv('~/Dropbox/Trident/Reports/MarkFiveReports/MarkFive_SP500_Upcoming_Earnings.csv', stringsAsFactors = F)


# Setup for loop

uni_dates <- unique(earnings_data$Earnings.Date)

earn_count <- rep(NA, length(uni_dates))

tot_mkt_cap <- rep(NA, length(uni_dates))


# loop thru and group and collect data (this can be done with 'aggregate', but is not as read-able)

idx = 1

for (dt in uni_dates) {

temp <- subset(earnings_data, earnings_data$Earnings.Date == dt)

tot_mkt_cap[idx] <- sum(temp$MarketCap, na.rm = T)

earn_count[idx] <- nrow(temp); idx = idx + 1

}


# Construct data.frame

ec_df <- data.frame(date = unique(earnings_data$Earnings.Date), count = earn_count, mktcap = tot_mkt_cap)

ec_df$date <- as.character(ec_df$date)

ec_df <- na.omit(ec_df)

ec_df$time <- unlist(strsplit(ec_df$date, " "))[c(F, F, T)]

ec_df$dt <- as.Date(unlist(strsplit(ec_df$date, " "))[c(T, F, F)], format = '%m/%d/%Y')


# plot

p <- ggplot(ec_df, aes(dt, mktcap))

p + geom_bar(stat = "identity", aes(fill = time)) +

labs(x = 'Dates', y = 'Market Cap', title = paste0('Earnings Season ', year(today()))) +

theme(axis.text.x = element_text(angle = 90, hjust = 1))

©2020 by Mud Muscle and Markets - Disclaimer