I Ranked 151 US Large-Caps With a 15-Line Model — Here's the Code and the Top 10
⚠️ Disclaimer: This is research and educational content built from public market data. It is not personalized investment advice and is not a recommendation to buy or sell any security. Past performance does not predict future results. Do your own research.
What I built
A single Python script that:
- Downloads ~2 years of split/dividend-adjusted daily closes for 151 US large-caps via
yfinance - Computes 12-month momentum, annualized volatility, and a quality score per ticker
- Z-scores every factor cross-sectionally (mean 0, std 1 across the universe)
- Combines them into a single composite score: 0.5 × Momentum + 0.5 × Quality
- Prints the full ranked table and writes a dated CSV
No look-ahead bias. No survivorship bias (the universe is fixed). No black box.
The 15-Line Model (complete, runnable)
import yfinance as yf, pandas as pd, numpy as np, warnings
warnings.filterwarnings("ignore")
TICKERS = ["AAPL","MSFT","NVDA","GOOGL","AMZN","META","TSLA","AVGO","AMD","NFLX",
"ORCL","CRM","ADBE","CSCO","QCOM","TXN","MU","INTC","IBM","NOW","INTU",
"PLTR","SNOW","DDOG","NET","CRWD","PANW","ZS","FTNT","ANET","SMCI","ARM",
"MRVL","LRCX","AMAT","KLAC","ASML","ON","MPWR","MCHP","TER","ADSK","CDNS",
"SNPS","GFS","MRNA","LLY","NVO","UNH","JNJ","PFE","MRK","ABBV","BMY","TMO",
"DHR","ISRG","VRTX","REGN","AMGN","GILD","BSX","CVS","CI","HUM","ABT","SYK",
"ALGN","MDT","BABA","JD","PDD","SE","BIDU","UBER","ABNB","DASH","COIN","HOOD",
"PYPL","V","MA","AXP","BLK","SCHW","C","BAC","WFC","JPM","GS","MS","SPGI",
"ICE","CME","MCO","AIG","MET","PRU","TRV","ALL","CB","PGR","SPOT","T","VZ",
"TMUS","CMCSA","DIS","WMT","COST","HD","MCD","NKE","SBUX","TGT","UPS","CAT",
"DE","GE","BA","HON","UNP","CSX","NSC","LIN","APD","ECL","SHW","EMR","ETN",
"PH","ROK","WM","RSG","COP","XOM","CVX","SLB","OXY","EOG","DVN","PSX","VLO",
"MPC","PBR","BP","SHEL","TTE","RIO","FCX","NEM"]
close = yf.download(TICKERS, period="2y", interval="1d", auto_adjust=True, progress=False)["Close"].dropna(axis=1, how="any")
rets = close.pct_change().dropna()
mom12 = close.iloc[-1] / close.iloc[-252] - 1
vol = rets.iloc[-252:].std() * np.sqrt(252)
qual = -vol.rank(pct=True)
df = pd.DataFrame({"mom12": mom12, "vol": vol, "qual": qual})
df["score"] = 0.5 * df["mom12"].rank(pct=True) + 0.5 * df["qual"]
df = df.sort_values("score", ascending=False)
print(df.head(20).round(4))
df.to_csv("launchtower_factor_ranking.csv")
How to run it:
pip install yfinance pandas numpy
python launchtower_factor_screen.py
That's it. One file. No API keys. No cloud. No subscription.
The Top 10 (as of 2026-09-15)
| Rank | Ticker | 12M Momentum | Ann. Vol | Quality | Composite |
|---|---|---|---|---|---|
| 1 | APD | +6.3% | 46.8% | +11.06 | +6.07 |
| 2 | PBR | +35.3% | 28.8% | +2.54 | +2.80 |
| 3 | AVGO | +30.9% | 39.2% | +2.80 | +2.35 |
| 4 | NVDA | +45.9% | 34.8% | −0.06 | +1.96 |
| 5 | TRV | −11.5% | 46.0% | +2.06 | +1.86 |
| 6 | DE | +33.5% | 27.7% | +1.45 | +1.79 |
| 7 | UBER | +62.5% | 35.8% | +2.03 | +1.78 |
| 8 | COST | +20.9% | 22.6% | +1.18 | +1.72 |
| 9 | MA | +25.5% | 23.7% | +1.02 | +1.71 |
| 10 | ROK | +76.5% | 30.6% | +0.94 | +1.57 |
Scores are cross-sectional percentiles (0–1 scale) combined 50/50. Higher is better. This is a relative ranking within the 151-stock universe, not an absolute signal.
A few observations
- APD (Air Products) tops the list on quality — low realized volatility relative to its peers despite a weak 3-month print.
- PBR (Petrobras) and ROK (Rockwell) are the momentum leaders — both up 35%+ over 12 months.
- NVDA ranks 4th despite a negative quality score — its 12M momentum (+45.9%) carries it.
- COST and MA are the "boring" winners: moderate momentum, low volatility, solid quality.
What's in the Full Pack
The free table above is the top 10. The full 151-stock dataset includes:
- All 151 tickers with
momentum_12m,momentum_3m,volatility,quality_score, andcomposite_score - The complete Python script (the 15-line model above, plus the full 151-ticker universe)
- A dated CSV you can drop straight into Excel, pandas, or your own backtest
- Methodology notes: how each factor is computed, the z-scoring approach, and known limitations
👉 Get the Full 151-Stock Factor Pack — $9
Delivered instantly by email after purchase. No account required.
Why a 15-line model?
Most factor screens I've seen are either:
- Too simple — a single momentum sort that ignores risk
- Too complex — 40+ factors, black-box weighting, no reproducibility
This sits in the middle. Two factors (momentum + quality), equal weight, fully transparent. You can read every line. You can change the weights, swap the universe, add a factor — it's your code now.
Known limitations (honest ones):
- The universe is fixed at 151 large-caps. Small-caps and international names are excluded.
-
yfinancedata is delayed and occasionally has gaps. For production use, swap in a paid data source. - Equal weighting (0.5/0.5) is a starting point, not an optimized one.
- This is a ranking, not a signal. A stock ranked #1 today can be ranked #80 next month.
What I'm NOT doing
- I'm not telling you what to buy or sell.
- I'm not promising returns.
- I'm not hiding the code behind a paywall — the full script is in this article.
What I am doing: giving you a clean, reproducible starting point and the full dataset so you can do your own analysis faster.
LaunchTower is an independent market-data desk. All data is from public sources. This content is for research and educational purposes only and does not constitute investment advice.
Top comments (0)