Momentum trading refers to a general class of strategies which extrapolate from existing trends. They assume that stocks which are going up will continue to go up and stocks which are going down will continue going down, and buy and sell accordingly. This is in direct contrast to mean-reversion strategies, which rely on trends reversing direction.

Exported image

Momentum in a Stock
In this post, let’s explore why momentum based signals exist in financial markets and differences between momentum and mean-reversion behaviors.

# Load pricing data for an assetstart = '2014-01-01'end = '2015-01-01'data = dl.load_data_nologs('nasdaq', ['AAPL'], start, end)prices = data['ADJ CLOSE']dates = prices.index
# Plot the price of the asset over timeplt.figure(figsize=(15,7))plt.plot(prices['AAPL'])
# Find the line of best fit to illustrate the trendX = np.arange(len(dates))x = sm.add_constant(X) # Add a column of ones so that line can have a y-interceptmodel = regression.linear_model.OLS(prices['AAPL'], x).fit()a = model.params[0] # Get coefficients of lineb = model.params[1]prices['Y_hat'] = X * b + aplt.plot(prices['Y_hat'], 'r', alpha=0.9);plt.ylabel('Price')plt.legend(['AAPL', 'Trendline']);plt.show()
The hypothesis here is that the motion of the stock is based on some upwards trend, captured by the linear model, plus some random noise.

Momentum and Auto-Correlation
Many things in finance are autocorrelated. An intuitive explanation for this is that prices are determined by traders, which take into account past prices when determining new ones.

Some forms of autocorrelation will not exhibit momentum behavior. For instance, a very simple autocorrelation relation could be as follows.
In [5]:
def generate_autocorrelated_values(N): X = np.zeros(N) for i in range(N-1): X[i+1] = X[i] + np.random.normal(0, 1) return X
plt.figure(figsize=(15,7))for i in range(10): X = generate_autocorrelated_values(100) plt.plot(X)plt.xlabel('tt')plt.ylabel('XtX_t');plt.show()
These series will not exhibit momentum behavior, as the amount they go up and down each timestep is purely random. However, if the series' returns are autocorrelated, then we will see momentum behavior. We can simulate this as follows.
In [6]:
def generate_autocorrelated_values(N): X = np.zeros(N) for i in range(1, N-1): # Do the past returns 'look good' to investors past_returns = X[i] - X[i-1] # Investors hypothesize that future returns will be equal to past returns and buy at that price X[i+1] = X[i] + past_returns + np.random.normal(0, 1) return X
plt.figure(figsize=(15,7))for i in range(10): X = generate_autocorrelated_values(10) plt.plot(X)plt.xlabel('tt')plt.ylabel('XtX_t');plt.show()
It's now clear to see that if investors incorporate information about past returns into the future price, we will see momentum behavior. Obviously in real data this will be far more noisy and difficult to observe.

Testing for Autocorrelation
We can test for autocorrelation in a few ways. One is by checking for a unit root. If the series has a unit root, we should be worried that there is autocorrelation present.
In [25]:
from statsmodels.tsa.stattools import adfuller
X1 = generate_autocorrelated_values(100)X2 = np.random.normal(0, 1, 100)
# Compute the p-value of the Dickey-Fuller statistic to test the null hypothesis that yw has a unit rootprint 'X1'_, pvalue, _, _, , _ = adfuller(X1)if pvalue > 0.05: print 'We cannot reject the null hypothesis that the series has a unit root.'else: print 'We reject the null hypothesis that the series has a unit root.'print 'X2', pvalue, _, _, _, _ = adfuller(X2)if pvalue > 0.05: print 'We cannot reject the null hypothesis that the series has a unit root.'else: print 'We reject the null hypothesis that the series has a unit root.'
Time Frame is Important
Momentum behavior and mean reversion behavior can both occur in the same asset. Take for example AAPL again. We can see a trend upwards, but there is also movement around that trend. One approach could be to buy an hold AAPL and attempt to make money on the longer timeframe. Another approach would be to buy AAPL whenever it went under the trendline and sell it whenever it was beneath. This strategy would work on shorter timeframes.
In [7]:
# Load pricing data for an assetstart = '2016-03-01'end = '2017-01-01'data = dl.load_data_nologs('nasdaq', ['AAPL'], start, end)prices = data['ADJ CLOSE']dates = prices.index
# Plot the price of the asset over timeplt.figure(figsize=(15,7))plt.plot(prices['AAPL'])
# Find the line of best fit to illustrate the trendX = np.arange(len(dates))x = sm.add_constant(X) # Add a column of ones so that line can have a y-interceptmodel = regression.linear_model.OLS(prices['AAPL'], x).fit()a = model.params[0] # Get coefficients of lineb = model.params[1]prices['Y_hat'] = X * b + aplt.plot(prices['Y_hat'], 'r', alpha=0.9);plt.ylabel('Price')plt.legend(['AAPL', 'Trendline']);plt.show()
To see how a mean reversion signal might look, let's look at the difference between the asset and the prediction. Sure enough, looks like some good opportunity for mean reversion as the price difference crosses the zero line many times.
In [8]:
plt.figure(figsize=(15,7))plt.plot((prices['AAPL'] - prices['Y_hat']).values)plt.hlines(np.mean(prices['AAPL'] - prices['Y_hat']), 0, len(dates), colors='r')plt.hlines(np.std(prices['AAPL'] - prices['Y_hat']), 0, len(dates), colors='r', linestyles='dashed')plt.hlines(-np.std(prices['AAPL'] - prices['Y_hat']), 0, len(dates), colors='r', linestyles='dashed')plt.xlabel('Time')plt.ylabel('Dollar Difference')plt.show()
Time Frame is Important for Predictive Capacity
Each momentum measure will be predictive over different time horizons. Some over years and some over days. This will also be true of different asset classes. Some asset classes have momentum over years and some over days. It is important, when constructing a momentum model, to keep in mind what time frame makes sense. That time frame should be roughly the time frame on which you rebalance/exit the trade. It should also be the time frame you use when measuring predictive capacity of your model.

IMPORTANT: Model Selection
It is important not to fall prey to statistical biases by throwing a lot of models at a dataset and seeing which fit. To understand why this is true, see The Dangers of Overfitting. In short, if you throw a lot of models at a dataset, one will likely happen to look good based on random chance. This model will not have predictive power on any new data, just the data you've already seen.
A better approach is to let your model creation be driven by underlying things you know to be true about your data. For instance, here is a good development path:

  1. Hypothesize that based on investor psychology, certain stocks should exhibit momentum behavior.
  2. Construct a mathemtical model that follows this hypothesis.
  3. Test your hypothesis by seeing if that model fits your data well.
  4. Test your model out of sample on new data you've never seen before.

Trading on Momentum
Measuring Momentum
To trade on momentum, we must first be able to measure it. For information on how to measure momentum, please see the Measuring Momentum notebook. Various ways to quantify momentum will be discussed there. We will discuss what you might do once you have developed a measure of momentum here.

Entry and Exit Signals
One way to use momentum is to have cutoffs and enter a position when momentum is significantly high, and leave it when momentum is significantly low. The can be done for shorting stocks as well if momentum is in the negative direction. Good examples of this would be moving average crossover strategies, as discussed in the Measuing Momentum.

Ranking Stocks for Long-Short Baskets
Another approach is to use momentum as a factor for ranking stocks. The general approach and its benefits are descrbed in the Long-Short Equity and Ranking Universes by Factors. In short, you make a bet that stocks with higher momentum will outperform those with lower momentum. This tends to be more market neutral and robust. Momentum could also be used as one of many factors in a ranking scheme.
Cross-Sectional Momentum
Cross sectional momentum is when rather than looking at absolute momentum, you look at momentum of every stock relative to every other stock. This has the advantage of providing a relative scale, rather than a somewhat meaningless absolute measure of momentum.

Built with LogoFlowershow