What are the Best & Worst Times of Day to Buy the Stock Market?

I awoke this morning to find the S&P 500 futures down about 11 points. My immediate thought was “oh goodie, there’s some candy for the old early morning BTFD’ers to enjoy” [translation, “I’ll bet the market goes up from here”]. This instinct was based on many such mornings of observing and interacting with the stock market. But how good is this intuition, and more importantly are there times of day where prices have a tendancy to outperform / underperform?

To answer these questions, let’s go back to a non-parametric machine learning model known as the Kernel Density Estimator (KDE). Not long ago I wrote an article showing how to simulate correlated random walks using the KDE, and today we’re going to use it for two tasks

  1. To learn the shape of the distribution of price returns for the S&P 500 futures contract over each hour of the day and
  2. To simulate a large number of price returns for each hour (i.e. far more than could have occurred in nature)

In other words, we start by “binning” or sorting all the actual hourly returns for the S&P 500 futures in 2017 into the time of day they occurred e.g. midnight, 1am, 2am, 3am, and so forth…

Then, for each hourly “bin” or “bucket” I trained a KDE model to estimate the shape of the price return distribution. In other words, the KDE learns whether the price return distribution is skewed to one side or has a mean that heavily favors one side vs the other. We can also learn about how “scattered” the distribution is around its mean. I can accomplish this task easily with SliceMatrix-IO‘s Python SDK:

from slicematrixIO import SliceMatrix
sm = SliceMatrix(api_key)

#assuming diffs is a pandas dataframe with my S&P 500 price return data...

times = ["00:00", "01:00", "02:00", "03:00", "04:00", "05:00",
"06:00", "07:00", "08:00", "09:00", "10:00", "11:00",
"12:00", "13:00", "14:00", "15:00", "16:00", "17:00",
"18:00", "19:00", "20:00", "21:00", "22:00", "23:00"]

distributions = []
simulations = []

for time in times:
    print time
    segment = diffs.between_time(time, time)
    kde = sm.KernelDensityEstimator(dataset = segment)

Now we can plot the distributions of each hour’s price returns:


As you can see, there is a pronounced skew higher in price returns around 7am to 8am New York time (confirming my earlier intuition… pats self on the back)

However, whats truly interesting is the negative skew from 9am to 10am. It would seem if the market is going to have a “falling out of bed” moment in 2017, its most likely to happen then. A quick glance at the same chart for the front month VIX future confirms this pattern:


As for the answer to the headline, the most benign times to be long the market appear to be that 7am to 8am stretch as well as the afternoon in general. Likewise, if you want to be short volatility then the afternoon is the best time.

The worst times to be long equities appears to be right on the open as well as right after the futures reopen for Asian trading. Likewise, the best time to be betting on rising volatility is right after the equity open.

Interested in Machine Learning Applications for Trading?


Create complex machine learning systems in just a few lines of code

This example is powered by SliceMatrix-IO, the next generation in machine intelligence Platform as a Service (PaaS). SliceMatrix delivers an end-to-end machine intelligence solutions to end-users so that they can seamlessly develop machine intelligent applications and systems. Get started building for free, get your api key here

Categories: Python, Quant Tools, Volatility

Tagged as: , , ,

1 reply »

Leave a Reply

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

WordPress.com Logo

You are commenting using your WordPress.com 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 )

Google+ photo

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

Connecting to %s