• John Hawver

News Trading, Feel the Noize

Updated: Apr 13, 2019

In my last post, I mentioned news and event-based trading. I’d like to share what I know about the subject and explain why long-term investors shouldn’t care.

News/Event trading started becoming prevalent in the early 2000s, largely as an outgrowth of statistical arbitrage trading. Defined events, like earnings or economic releases, drove the strategy. It works like this: News/event data is collected and “parsed” into multiple factors. This parsing was where the original vig was; if you parsed your data better you got more information out of it. The parsed factors, which are 1’s and 0’s indicating if the news was positive or negative, or if earnings were good or bad, etc, are then regressed against forward returns for the applicable asset. This process “fits” the model.

Today things have changed somewhat. Multiple news services offer parsed feeds and historical data that include twitter feeds, earnings events, and economic releases. It’s not cheap. In practice, this data is transmitted, via microwave towers from the news origination source (Washington DC for economic numbers) to co-location facilities in NJ and Chicago (CME, technically Aurora, IL) where it is acted upon. This takes at most a few milliseconds and in some cases only a few microseconds (1 millionth of a second). So, when Crossing WallStreet (a great blog) posts a chart on the “immediate” news reaction, this is how it actually happens.

If you’d like to dive deeper into the details, Kaggle hosted a competition sponsored by TwoSigma on this very subject and you can read how it was solved here.

I hope that was informative. But, if you’re a serious long-term investor, please delete that from your memory bank. While interesting, it won’t help you invest more intelligently, nor can anyone manually compete with event/news traders.

There are two primary reasons to avoid the noise from Wall Street:

First, trading and investing are commonly referred to as transference of risk. I like to think about it slightly differently; trading and investing are really information transfer. If each party in the transaction is rational, they believe their information is superior to their counter-party. To be a successful investor, your information has to be informed. Noise is not information.

“Wall Street” (the financial industry and media) operates on a very short time horizon. And at short time horizons, there really isn’t that much true relevant long-term information. But Wall Street needs its profits, and traders itch to make more money, so all players concerned tend to overweight the importance of recent information (recency bias) and act upon it unnecessarily.

The second reason to avoid the noise is that statistically, it is in your favor to do so. The longer your time frame to invest, the higher the probability that your investment in the market will rise. Ignoring the noise simply works. The chart below shows this and I’ve included the code to replicate it at the end of the post.

Since 1980, if you invested with a horizon of four years (1000 market days), your probability of a positive return was around 86%; greater than 12 years and the probability was 100%. Of course, when you start investing does impact the below results, as shown in the chart, but that impact diminishes with time. And if you started investing in 2010, you’ve had a nice smooth ride, for now.

To summarize:

1. Understand news/event trading, then forget it.

2. Noise is not information.

3. Time is your friend.

Hope that helped. Good luck.


***** R Code to replicate *****

# packages


# helper functions

fLead <- function(vec, leadN) { c(vec[(leadN + 1):(length(vec)) ], rep(NA, leadN)) }

fSmplRtns <- function(lead_val, past_val) { (lead_val / past_val) - 1 }

# Get and clean Data

idx <- getSymbols("WILL5000INDFC", src = 'FRED', auto.assign = F)

idx <- na.omit(idx)

# define start years

start_years <- c('1980', '1990', '2000', '2010')

plot_cols <- c('darkgreen', 'blue', 'red', 'orange'); names(plot_cols) <- start_years

test <- idx['2000::']

# loop thru each start year

for (styr in start_years) {

# Setup

idx <- idx[paste0(styr, '::')]

horizons <- seq(1, min(15*252, nrow(idx)-10), 10)

# loop thru and create columns of forward returns

app = FALSE

for (hrz in horizons) {

hrz_data <- fLead(coredata(idx), hrz)

temp_rtns <- fSmplRtns(hrz_data, coredata(idx))

lead_rtns <- if (app) cbind(lead_rtns, temp_rtns) else cbind(idx, temp_rtns); app = TRUE


colnames(lead_rtns) <- c('idx', horizons)

# get probability of a positive return

num <- colSums(lead_rtns[, as.character(horizons)] > 0, na.rm = T)

den <- colSums(lead_rtns[, as.character(horizons)] / lead_rtns[, as.character(horizons)], na.rm = T)

probPositive <- num / den

# plot it out

if (styr == start_years[1]) {

plot(as.numeric(names(probPositive)), as.vector(probPositive),

main = 'Probability of a Positive Equity Index Return',

xlab = 'Investment Horizon (working days)', ylab = 'Probability', col = 'darkgreen', type="b"); grid()

legend(3000, .7, legend = start_years, col = plot_cols, lty = 1:4, cex = 0.9)

} else {

points(as.numeric(names(probPositive)), as.vector(probPositive), col = plot_cols[styr], type="b")



# Daily probability that your portfolio is up or down.

spy <- fGetSymTSData('spy')

spy_rtns <- na.omit(CalculateReturns(spy$SPY.Adjusted))

prob_up <- sum(spy_rtns>=0) / length(spy_rtns); prob_dn <- 1-prob_up

hist(spy_rtns, 50, col = 'blue', xlab = 'SPY Daily Returns (1993 to Present)', main = 'Probability up 55%, down 45%')