VibeTradingVibeTrading
Back to Blog
Also available in中文
StrategiesJuly 21, 202614 min read

AI Momentum Strategy: Build a Rank-Based Python Bot

A step-by-step guide to building an AI momentum strategy in Python. Rank assets by momentum, manage risk, and backtest your approach.

#ai trading#momentum#python#ranking#backtesting#strategy
Risk Disclaimer: This content is for educational purposes only. Trading involves significant risk of loss. Past performance does not guarantee future results. Always do your own research before using any trading tool or strategy.

Momentum is one of the oldest and most robust ideas in investing. Assets that have risen recently tend to keep rising, at least for a while. With Python and a few libraries, you can build a momentum strategy that ranks assets and rebalances periodically.

This tutorial walks you through building a simple AI-enhanced momentum strategy from data collection to backtest.

What You Will Build

By the end of this guide, you will have:

  • A Python script that fetches price data
  • A momentum scoring function
  • A rank-based portfolio rebalancer
  • A backtest with basic risk metrics

The Core Idea

Traditional momentum ranks assets by past returns. AI-enhanced momentum adds additional signals such as:

  • Risk-adjusted momentum
  • Volume-confirmed momentum
  • Cross-asset momentum
  • Regime detection

For this tutorial, we keep it simple but extensible.

Step 1: Fetch Data

Use yfinance or Alpaca to download historical prices for a universe of assets.

import yfinance as yf
import pandas as pd
 
tickers = ["AAPL", "MSFT", "AMZN", "GOOGL", "META", "NVDA", "TSLA"]
data = yf.download(tickers, start="2020-01-01", end="2024-01-01")["Adj Close"]

Step 2: Calculate Momentum Scores

Compute returns over multiple lookback windows and combine them.

def compute_momentum_scores(prices):
    returns_1m = prices.pct_change(21)
    returns_3m = prices.pct_change(63)
    returns_6m = prices.pct_change(126)
    returns_12m = prices.pct_change(252)
 
    # Combine signals
    score = 0.4 * returns_12m + 0.3 * returns_6m + 0.2 * returns_3m + 0.1 * returns_1m
    return score
 
momentum_scores = compute_momentum_scores(data)

Step 3: Rank and Select

Each month, rank assets by momentum score and select the top N.

def select_top_assets(scores, n=3):
    latest_scores = scores.iloc[-1]
    ranked = latest_scores.sort_values(ascending=False)
    return ranked.head(n).index.tolist()
 
top_assets = select_top_assets(momentum_scores, n=3)

Step 4: Add a Volatility Filter

Avoid assets with extreme volatility. Use an AI-style risk filter.

def volatility_filter(prices, max_vol=0.03):
    daily_returns = prices.pct_change()
    volatility = daily_returns.rolling(63).std().iloc[-1]
    return volatility[volatility < max_vol].index.tolist()
 
allowed = volatility_filter(data)
top_assets = [a for a in top_assets if a in allowed]

Step 5: Backtest the Strategy

A simple monthly rebalancing backtest:

import numpy as np
 
portfolio_value = 1.0
portfolio_values = [portfolio_value]
rebalance_dates = data.resample("ME").last().index
 
for i in range(1, len(rebalance_dates)):
    start_date = rebalance_dates[i-1]
    end_date = rebalance_dates[i]
 
    period_data = data.loc[start_date:end_date]
    period_returns = period_data.pct_change().iloc[-1]
 
    scores = momentum_scores.loc[start_date]
    top_assets = scores.rank(ascending=False) <= 3
    selected = scores[top_assets].index.tolist()
 
    if len(selected) == 0:
        portfolio_values.append(portfolio_value)
        continue
 
    equal_weight_return = period_returns[selected].mean()
    portfolio_value *= (1 + equal_weight_return)
    portfolio_values.append(portfolio_value)

Step 6: Evaluate Performance

returns_series = pd.Series(portfolio_values).pct_change().dropna()
sharpe = returns_series.mean() / returns_series.std() * np.sqrt(12)
max_dd = (pd.Series(portfolio_values) / pd.Series(portfolio_values).cummax() - 1).min()
 
print(f"Sharpe: {sharpe:.2f}")
print(f"Max Drawdown: {max_dd:.2%}")

AI Enhancements to Add

Once the basics work, consider adding:

  • Machine learning ranking: Train a model to predict next-month returns from momentum, volatility, and sentiment features.
  • Regime detection: Use clustering to identify trending vs ranging periods.
  • Dynamic sizing: Increase exposure when momentum is strong and reduce during drawdowns.
  • Sector neutrality: Avoid concentrating in one sector.

Common Pitfalls

  • Look-ahead bias: Never use future data to compute signals at a given date.
  • Survivorship bias: Use point-in-time universe data.
  • Transaction costs: Rebalancing monthly can erode returns on small accounts.
  • Overconcentration: Holding only 2-3 assets increases risk.

Worked Example: Monthly Rebalance Walkthrough

Assume a $10,000 account and a universe of 20 large-cap tech stocks. At the end of January, the momentum scores rank NVDA, META, and MSFT in the top three. Each has an average daily volatility below 3%. The strategy allocates one-third of capital, roughly $3,333, to each.

At the end of February, NVDA has fallen out of the top three and AVGO has replaced it. The strategy sells NVDA and buys AVGO, rebalancing back to equal weights. Over a full year, this process repeats twelve times. The backtest measures total return, Sharpe ratio, maximum drawdown, and turnover.

Turnover matters. If every rebalance costs 0.1% in slippage and commission, twelve rebalances per year on a fully invested portfolio can drag returns by more than 1% annually. Momentum strategies must earn enough excess return to cover this cost.

When Momentum Works Best

Momentum tends to work when:

  • Markets are trending, even with normal corrections.
  • The universe contains assets with heterogeneous performance.
  • You diversify across sectors or asset classes.
  • You use a sufficiently long lookback, typically three months or more.

It struggles when:

  • Markets chop back and forth without sustained trends.
  • Everyone is crowded into the same few winners.
  • Transaction costs are high relative to expected moves.

Position Sizing Rules

A simple but effective rule is volatility parity: size positions inversely to recent volatility. Higher volatility assets get smaller allocations. This prevents a single volatile name from dominating portfolio risk and often improves the Sharpe ratio in backtests.

Bottom Line

Momentum is a simple, powerful concept that is easy to implement in Python. AI enhancements can improve ranking and risk management, but the foundation is the same: buy assets that are trending, cut losers, and rebalance with discipline.

Start with a simple version, validate it honestly, and add complexity only when the core idea works.


Related reading: AI Trend Following vs Mean Reversion | AI Multi-Factor Ranking | How to Backtest Without Overfitting