We report strong evidence that changes of momentum, i.e. "acceleration", defined as the first difference of successive returns, provide better performance and higher explanatory power than momentum. The corresponding Γ-factor explains the momentum-sorted portfolios entirely but not the reverse. Thus, momentum can be considered an imperfect proxy for acceleration, and its success can be attributed to its correlation to the predominant Γ-factor. Γ-strategies based on the "acceleration" effect are on average profitable and beat momentum-based strategies in two out of three cases, for a large panel of parameterizations. The "acceleration" effect and the Γ-factor profit from transient non-sustainable accelerating (upward or downward) log-prices associated with positive feedback mechanisms.
Keywords: Asset pricing, momentum, positive feedbacks, acceleration, investment strategies
- Focus on: Stocks listed on NYSE, AMEX, and NASDAQ
- Compute acceleration metric: Momentum over 6 months minus momentum from the previous 6 months (from 6 months ago)
- Categorize stocks into ten groups with equal distribution in each group
- Adopt a long position in stocks with high acceleration, and a short position in those with low acceleration
- Acceleration effect materializes after 6 months, strongest returns at 12 months.
- Ideal approach: Initiate stock purchases 6 months post-portfolio creation and maintain for an additional 6 months
- To integrate the acceleration and momentum effects:
- Determine acceleration by assessing: (Momentum from month T-7 to T-12) subtracted from (momentum from month T-13 to T-18)
- Organize stocks into ten groups based on their acceleration rate
- At month's end (T), adopt a long position on the highest momentum stocks (from month T-1 to T-6) of the top acceleration group
- Similarly, adopt a short position on the lowest momentum stocks (from month T-1 to T-6) of the lowest acceleration group
- Hold long/short portfolio for six months.
import backtrader as bt import pandas as pd import numpy as np class AccelerationMomentum(bt.Strategy): def __init__(self): self.stock_data = dict() def prenext(self): self.next() def next(self): # Every 6 months, reevaluate the portfolio if len(self) % 126 == 0: self.rebalance_portfolio() def rebalance_portfolio(self): stocks_accel =  for d in self.datas: # Calculate 6-month momentum momentum_6m = d.close / d.close[-126] # Calculate 6-month momentum six months prior momentum_6m_prior = d.close[-126] / d.close[-252] # Calculate acceleration ratio acceleration_ratio = momentum_6m - momentum_6m_prior stocks_accel.append((d, acceleration_ratio)) # Sort stocks by acceleration ratio and divide into deciles sorted_stocks = sorted(stocks_accel, key=lambda x: x, reverse=True) deciles = np.array_split(sorted_stocks, 10) # Get top and bottom deciles top_decile = deciles bottom_decile = deciles[-1] # Sort top decile by momentum (T-1 to T-6) top_decile_momentum = sorted(top_decile, key=lambda x: x.close / x.close[-6], reverse=True) # Sort bottom decile by momentum (T-1 to T-6) bottom_decile_momentum = sorted(bottom_decile, key=lambda x: x.close / x.close[-6]) # Go long on top decile stocks for stock in top_decile_momentum: self.order_target_percent(stock, target=1.0 / len(top_decile_momentum)) # Go short on bottom decile stocks for stock in bottom_decile_momentum: self.order_target_percent(stock, target=-1.0 / len(bottom_decile_momentum)) if __name__ == '__main__': cerebro = bt.Cerebro() # Add all stocks in the investment universe # (Replace 'stock_data' with actual stock data) for stock in stock_data: data = bt.feeds.PandasData(dataname=stock_data[stock]) cerebro.adddata(data) cerebro.addstrategy(AccelerationMomentum) cerebro.broker.setcash(100000.0) cerebro.run()
Note: This code is a starting point and should be adapted according to your specific data source and requirements. The ‘stock_data’ variable should be replaced with actual stock data from NYSE, AMEX, and NASDAQ. Additionally, ensure that your stock data has the required history for the calculations.