Is the Rotation From Tech to Industrials Backed by Earnings? Relative EPS Growth Analysis in Python
July 10, 2026
What's the question?
A rotation trade occurs when capital flows from one sector to another. In mid-2026, market commentary has focused on a shift away from technology toward industrials and financials. The Technology Select Sector ETF (XLK) gained only 2.5% over the most recent month, while the Financial Select Sector ETF (XLF) rose 5.9% and the Industrial Select Sector ETF (XLI) gained 3.1%.
The question is whether this rotation reflects a genuine shift in earnings fundamentals. If industrials and financials are accelerating on revenue and operating income while technology is decelerating, the rotation has a fundamental basis. If technology still leads on earnings growth, the rotation is more likely a positioning or valuation trade, not an earnings-driven reallocation.
The approach
The analysis compares median revenue growth to year-to-date price performance across three sectors: technology, industrials, and financials. Five representative large-cap stocks are selected from each sector.
- Pull five years of annual fundamentals for all 15 stocks, focusing on revenue and operating income
- Compute year-over-year revenue growth for the most recent fiscal year relative to the prior year
- Group by sector and compute the median revenue growth rate, which is resistant to outliers
- Pull year-to-date daily prices for three sector ETFs (XLK, XLI, XLF) and compute cumulative returns
- Compare whether the sector with the strongest earnings growth also has the strongest price performance
Technology is represented by AAPL, MSFT, NVDA, META, and GOOG. Industrials by CAT, HON, GE, RTX, and DE. Financials by JPM, GS, BAC, MS, and BLK. Operating income is included where available; most financial institutions do not report a traditional operating income line item, so revenue growth serves as the primary comparison metric.
Code
import xfinlink as xfl
import pandas as pd
xfl.set_api_key("YOUR_API_KEY") # free at https://xfinlink.com/signup
tech = ["AAPL", "MSFT", "NVDA", "META", "GOOG"]
industrials = ["CAT", "HON", "GE", "RTX", "DE"]
financials = ["JPM", "GS", "BAC", "MS", "BLK"]
all_stocks = tech + industrials + financials
sectors = {t: "Tech" for t in tech}
sectors.update({t: "Industrials" for t in industrials})
sectors.update({t: "Financials" for t in financials})
fund = xfl.fundamentals(all_stocks, period_type="annual", period="5y",
fields=["revenue", "operating_income"])
results = []
for ticker in all_stocks:
t = fund[fund["ticker"] == ticker].sort_values("period_end")
latest, prior = t.iloc[-1], t.iloc[-2]
rev_growth = (latest["revenue"] - prior["revenue"]) / abs(prior["revenue"]) * 100
results.append({"ticker": ticker, "sector": sectors[ticker],
"rev_growth_pct": round(rev_growth, 1)})
df_growth = pd.DataFrame(results)
sector_rev = df_growth.groupby("sector")["rev_growth_pct"].median()
etfs = ["XLK", "XLI", "XLF"]
prices = xfl.prices(etfs, period="ytd", fields=["close"])
for etf in etfs:
sub = prices[prices["ticker"] == etf].sort_values("date")
ytd = (sub.iloc[-1]["close"] / sub.iloc[0]["close"] - 1) * 100
print(f"{etf} YTD: {ytd:+.1f}%")
print()
for sec in ["Tech", "Industrials", "Financials"]:
print(f"{sec:12s} Median rev growth: {sector_rev[sec]:+.1f}%")
Full script with formatting and visualisation: tech-industrials-rotation-earnings-python.py
Output
Individual stock revenue growth (latest fiscal year vs prior):
AAPL (Tech ) Rev: +6.4% OI: +8.0%
MSFT (Tech ) Rev: +14.9% OI: +17.4%
NVDA (Tech ) Rev: +65.5% OI: +60.1%
META (Tech ) Rev: +22.2% OI: +20.0%
GOOG (Tech ) Rev: +15.1% OI: +14.8%
CAT (Industrials ) Rev: +4.3% OI: -14.7%
HON (Industrials ) Rev: +7.8% OI: +6.0%
GE (Industrials ) Rev: +30.6% OI: N/A
RTX (Industrials ) Rev: +9.7% OI: +42.2%
DE (Industrials ) Rev: -11.7% OI: N/A
JPM (Financials ) Rev: +2.8% OI: N/A
GS (Financials ) Rev: +8.9% OI: N/A
BAC (Financials ) Rev: +6.8% OI: N/A
MS (Financials ) Rev: +14.4% OI: N/A
BLK (Financials ) Rev: +18.7% OI: -7.0%
Sector median revenue growth:
Tech +15.1%
Industrials +7.8%
Financials +8.9%
Sector ETF price performance:
XLK (Tech ) YTD: +28.4% 1-month: +2.5%
XLI (Industrials ) YTD: +14.6% 1-month: +3.1%
XLF (Financials ) YTD: +1.1% 1-month: +5.9%
What this tells us
Year-to-date, price performance aligns with earnings fundamentals. Technology has the highest median revenue growth at +15.1% and the highest ETF return at +28.4%. Industrials follow with +7.8% revenue growth and +14.6% price return. Financials post +8.9% revenue growth but only +1.1% YTD price gain — the weakest performer despite having stronger revenue growth than industrials.
The dispersion within sectors is also informative. Technology revenue growth ranges from +6.4% (AAPL) to +65.5% (NVDA), with all five companies positive. Industrials are more mixed: GE grew revenue 30.6% (partly reflecting its post-spinoff composition), but Deere contracted 11.7% due to the agricultural cycle downturn. Caterpillar, often cited as a cyclical bellwether, grew just 4.3%.
The recent one-month window tells a different story. Financials led with +5.9%, industrials gained +3.1%, and technology trailed at +2.5%. This is the rotation that has drawn market attention. But this one-month price shift has no corresponding earnings acceleration to support it. The most recent annual revenue data shows technology still growing at nearly double the median rate of the other two sectors.
Operating income data reinforces the picture for technology, where median operating income growth is +17.4%. Most financial institutions do not report traditional operating income, and industrial operating income is mixed (RTX +42.2%, CAT -14.7%).
So what?
The data suggests the recent rotation is a valuation or positioning trade, not an earnings-driven reallocation. Technology still leads on the fundamental metric that matters most for forward returns: revenue growth. The market has priced this correctly on a year-to-date basis.
Short-term rotations into cyclicals often occur when investors de-risk concentrated technology positions or anticipate macro tailwinds like rate cuts. These can persist for weeks or months. But sustained sector leadership historically requires sustained earnings superiority, and the current data does not show industrials or financials catching up on that front.
For portfolio construction, the takeaway is straightforward: rotating into industrials or financials should be supported by a forward-looking earnings thesis, not simply a contrarian bet against technology's recent dominance. The backward-looking earnings data does not yet validate the rotation narrative.
Built with xfinlink — free financial data API for Python. pip install xfinlink
pip install xfinlink