Strategy - S&P500 (v7)

3 September 2025 - Written by ML

Highlights

  • This report is the first in a series on US market portfolio construction. The report is published in R and contains python script for producing results. Updated with consistent table formatting.

Aim

  • In first instance a python script looks up and extracts tickers that are components of the S&P500 (identified from wikipedia page that contains the list of constituent stocks). Each stock`s Global Industry Classification Standard (GICS) group is extracted at the same time.

  • Yahoo finance is then used to extract for each ticker financial data that include for instance share price, earnings, shares outstanding, return on eauity.

  • Various computations are then performed on each ticker and tables are output in CSV form.

  • Code has been created with a mixture of models including Claude, kimi.ai, deep seek, mistral.ai, chatgpt, and, cursor.

Script

###############################################################################
# Script Name: get_tickers_8.py
# pip install yfinance pandas requests beautifulsoup4 lxml
import yfinance as yf
import pandas as pd
import requests
from bs4 import BeautifulSoup
from io import StringIO
from datetime import datetime

# Convert exchange-style tickers (e.g., BRK.B) to Yahoo format (BRK-B)
def normalize_symbol_for_yahoo(symbol: str) -> str:
    if not isinstance(symbol, str):
        return symbol
    return symbol.replace('.', '-').strip()

def get_enhanced_earnings_data(symbol: str):
    """Enhanced function to get comprehensive earnings data."""
    try:
        tk = yf.Ticker(symbol)
        
        # Get price data
        price = None
        try:
            hist = tk.history(period="5d")
            if hist is not None and not hist.empty and 'Close' in hist:
                price = hist['Close'].dropna().iloc[-1]
        except Exception:
            pass

        if price is None:
            fast_info = getattr(tk, 'fast_info', {}) or {}
            price = fast_info.get('last_price')
        if price is None:
            info = getattr(tk, 'info', {}) or {}
            price = info.get('regularMarketPrice') or info.get('previousClose')

        # Get comprehensive earnings data
        info = getattr(tk, 'info', {}) or {}
        fast_info = getattr(tk, 'fast_info', {}) or {}
        
        # Basic earnings
        trailing_eps = info.get('trailingEps')
        if (trailing_eps is None or trailing_eps == 0) and price not in (None, 0):
            pe = fast_info.get('trailing_pe') or info.get('trailingPE')
            if pe not in (None, 0):
                try:
                    trailing_eps = float(price) / float(pe)
                except Exception:
                    trailing_eps = None
        
        # Enhanced earnings measures
        earnings_data = {
            'price': price,
            'trailing_eps': trailing_eps,
            'forward_eps': info.get('forwardEps'),
            'trailing_pe': info.get('trailingPE'),
            'forward_pe': info.get('forwardPE'),
            'earnings_growth': info.get('earningsAnnualGrowth'),
            'revenue_growth': info.get('revenueGrowth'),
            'profit_margins': info.get('profitMargins'),
            'roe': info.get('returnOnEquity'),
            'price_to_book': info.get('priceToBook'),
            'price_to_sales': info.get('priceToSalesTrailing12Months'),
            'debt_to_equity': info.get('debtToEquity'),
            'current_ratio': info.get('currentRatio'),
            'shares_outstanding': info.get('sharesOutstanding')
        }
        
        # Calculate additional derived metrics
        if earnings_data['trailing_eps'] and earnings_data['forward_eps']:
            try:
                earnings_data['eps_growth_rate'] = (
                    (earnings_data['forward_eps'] - earnings_data['trailing_eps']) / 
                    abs(earnings_data['trailing_eps']) * 100
                )
            except:
                earnings_data['eps_growth_rate'] = None
        
        if earnings_data['trailing_pe'] and earnings_data['forward_pe']:
            try:
                earnings_data['pe_ratio_spread'] = (
                    earnings_data['trailing_pe'] - earnings_data['forward_pe']
                )
            except:
                earnings_data['pe_ratio_spread'] = None
        
        return earnings_data
        
    except Exception as e:
        print(f"Error getting data for {symbol}: {e}")
        return {}

def analyze_earnings_quality(earnings_data):
    """Analyze the quality and consistency of earnings data."""
    quality_score = 0
    quality_notes = []
    
    # Check data completeness
    available_fields = sum(1 for v in earnings_data.values() if v is not None)
    total_fields = len(earnings_data)
    completeness = available_fields / total_fields
    
    if completeness >= 0.8:
        quality_score += 3
        quality_notes.append("High data completeness")
    elif completeness >= 0.6:
        quality_score += 2
        quality_notes.append("Moderate data completeness")
    else:
        quality_score += 1
        quality_notes.append("Low data completeness")
    
    # Check earnings consistency
    if earnings_data.get('trailing_eps') and earnings_data.get('forward_eps'):
        if earnings_data['forward_eps'] > earnings_data['trailing_eps']:
            quality_score += 2
            quality_notes.append("Forward EPS > Trailing EPS (growth expected)")
        else:
            quality_score += 1
            quality_notes.append("Forward EPS <= Trailing EPS")
    
    # Check P/E consistency
    if earnings_data.get('trailing_pe') and earnings_data.get('forward_pe'):
        if earnings_data['forward_pe'] < earnings_data['trailing_pe']:
            quality_score += 2
            quality_notes.append("Forward P/E < Trailing P/E (valuation improving)")
        else:
            quality_score += 1
            quality_notes.append("Forward P/E >= Trailing P/E")
    
    # Check growth metrics
    if earnings_data.get('earnings_growth'):
        if earnings_data['earnings_growth'] > 0:
            quality_score += 1
            quality_notes.append("Positive earnings growth")
        else:
            quality_score += 0
            quality_notes.append("Negative earnings growth")
    
    if earnings_data.get('revenue_growth'):
        if earnings_data['revenue_growth'] > 0:
            quality_score += 1
            quality_notes.append("Positive revenue growth")
        else:
            quality_score += 0
            quality_notes.append("Negative revenue growth")
    
    return {
        'quality_score': quality_score,
        'completeness': completeness,
        'notes': quality_notes
    }

print("Fetching S&P 500 constituents from Wikipedia...")
# 1) get the official S&P 500 list (symbol, company name, sector) ------------
url = "https://en.wikipedia.org/wiki/List_of_S%26P_500_companies"
headers = {"User-Agent": "Mozilla/5.0 (compatible; S&P500Fetcher/1.0)"}
resp = requests.get(url, headers=headers, timeout=30)
resp.raise_for_status()
sp500_tbl = pd.read_html(StringIO(resp.text))[0]          # first table on the page
sp500_tbl = sp500_tbl[['Symbol', 'Security', 'GICS Sector', 'GICS Sub-Industry', 'CIK']]
sp500_tbl['Yahoo_Symbol'] = sp500_tbl['Symbol'].apply(normalize_symbol_for_yahoo)
print(f"Loaded {len(sp500_tbl)} tickers.")

# 2) helper to fetch enhanced earnings data via yfinance ----
def get_enhanced_quote_data(symbol: str):
    try:
        earnings_data = get_enhanced_earnings_data(symbol)
        if not earnings_data:
            return None, None, None, None, None, None, None, None, None, None, None
        
        # Extract key metrics
        price = earnings_data.get('price')
        trailing_eps = earnings_data.get('trailing_eps')
        forward_eps = earnings_data.get('forward_eps')
        trailing_pe = earnings_data.get('trailing_pe')
        forward_pe = earnings_data.get('forward_pe')
        eps_growth_rate = earnings_data.get('eps_growth_rate')
        roe = earnings_data.get('roe')
        shares_outstanding = earnings_data.get('shares_outstanding')
        
        # Analyze data quality
        quality_analysis = analyze_earnings_quality(earnings_data)
        quality_score = quality_analysis['quality_score']
        data_completeness = quality_analysis['completeness']
        
        return (price, trailing_eps, forward_eps, trailing_pe, forward_pe, 
                eps_growth_rate, roe, shares_outstanding, quality_score, data_completeness)
    except Exception:
        return None, None, None, None, None, None, None, None, None, None, None

# 3) populate the dataframe with enhanced data ---------------------------------------------------
print("Fetching enhanced earnings data from Yahoo Finance...")
prices, trailing_eps_list, forward_eps_list, trailing_pe_list, forward_pe_list = [], [], [], [], []
eps_growth_list, roe_list, shares_list, quality_scores, completeness_scores = [], [], [], [], []

total = len(sp500_tbl)
for i, sym in enumerate(sp500_tbl['Yahoo_Symbol'], start=1):
    (price, trailing_eps, forward_eps, trailing_pe, forward_pe, 
     eps_growth_rate, roe, shares, quality_score, completeness) = get_enhanced_quote_data(sym)
    
    prices.append(price)
    trailing_eps_list.append(trailing_eps)
    forward_eps_list.append(forward_eps)
    trailing_pe_list.append(trailing_pe)
    forward_pe_list.append(forward_pe)
    eps_growth_list.append(eps_growth_rate)
    roe_list.append(roe)
    shares_list.append(shares)
    quality_scores.append(quality_score)
    completeness_scores.append(completeness)
    
    if i % 25 == 0 or i == total:
        print(f"Processed {i}/{total} tickers...")

sp500_tbl['Latest_Price'] = prices
sp500_tbl['Trailing_EPS'] = trailing_eps_list
sp500_tbl['Forward_EPS'] = forward_eps_list
sp500_tbl['Trailing_PE'] = trailing_pe_list
sp500_tbl['Forward_PE'] = forward_pe_list
sp500_tbl['EPS_Growth_Rate'] = eps_growth_list
sp500_tbl['Return_on_Equity'] = roe_list
sp500_tbl['Shares_Outstanding'] = shares_list
sp500_tbl['Data_Quality_Score'] = quality_scores
sp500_tbl['Data_Completeness'] = completeness_scores

# Calculate market capitalization
sp500_tbl['Market_Cap'] = sp500_tbl.apply(
    lambda row: row['Latest_Price'] * row['Shares_Outstanding'] 
    if pd.notna(row['Latest_Price']) and pd.notna(row['Shares_Outstanding']) 
    and row['Latest_Price'] > 0 and row['Shares_Outstanding'] > 0 
    else None, axis=1
)

# Calculate trailing earnings for each ticker (trailing EPS × shares outstanding)
sp500_tbl['Trailing_Earnings'] = sp500_tbl.apply(
    lambda row: row['Trailing_EPS'] * row['Shares_Outstanding'] 
    if pd.notna(row['Trailing_EPS']) and pd.notna(row['Shares_Outstanding']) 
    and row['Trailing_EPS'] is not None and row['Shares_Outstanding'] > 0 
    else None, axis=1
)

# Format market cap for better readability (in billions)
sp500_tbl['Market_Cap_Billions'] = sp500_tbl['Market_Cap'].apply(
    lambda x: round(x / 1e9, 2) if pd.notna(x) and x > 0 else None
)

# 4) inspect / save -----------------------------------------------------------
print(sp500_tbl.head())
print(f"\nMarket Cap Summary:")
print(f"Total companies with market cap data: {sp500_tbl['Market_Cap'].notna().sum()}")
print(f"Average market cap: ${sp500_tbl['Market_Cap'].mean() / 1e9:.2f}B")
print(f"Median market cap: ${sp500_tbl['Market_Cap'].median() / 1e9:.2f}B")

# Display enhanced earnings data summary
print(f"\nEnhanced Earnings Data Summary:")
print(f"Companies with trailing EPS: {sp500_tbl['Trailing_EPS'].notna().sum()}")
print(f"Companies with forward EPS: {sp500_tbl['Forward_EPS'].notna().sum()}")
print(f"Companies with trailing P/E: {sp500_tbl['Trailing_PE'].notna().sum()}")
print(f"Companies with forward P/E: {sp500_tbl['Forward_PE'].notna().sum()}")
print(f"Companies with ROE data: {sp500_tbl['Return_on_Equity'].notna().sum()}")
print(f"Companies with trailing earnings: {sp500_tbl['Trailing_Earnings'].notna().sum()}")
print(f"Average data quality score: {sp500_tbl['Data_Quality_Score'].mean():.1f}/10")
print(f"Average data completeness: {sp500_tbl['Data_Completeness'].mean():.1%}")

# 5) Create GICS Sector Summary Table -----------------------------------------
print("\nCreating GICS Sector Summary Table...")

# Group by GICS Sector and calculate summary statistics
sector_summary = sp500_tbl.groupby('GICS Sector').agg({
    'Symbol': 'count',  # Count of tickers
    'Market_Cap': 'sum',  # Sum of market capitalization
    'Trailing_Earnings': 'sum',  # Sum of trailing earnings
    'Data_Quality_Score': 'mean',  # Average data quality score
    'Data_Completeness': 'mean'  # Average data completeness
}).rename(columns={
    'Symbol': 'Ticker_Count',
    'Market_Cap': 'Total_Market_Cap',
    'Trailing_Earnings': 'Total_Sector_Earnings',
    'Data_Quality_Score': 'Avg_Data_Quality',
    'Data_Completeness': 'Avg_Data_Completeness'
})

# Convert market cap to billions for better readability
sector_summary['Total_Market_Cap_Billions'] = sector_summary['Total_Market_Cap'].apply(
    lambda x: round(x / 1e9, 2) if pd.notna(x) and x > 0 else 0
)

# Convert sector earnings to billions for better readability
sector_summary['Total_Sector_Earnings_Billions'] = sector_summary['Total_Sector_Earnings'].apply(
    lambda x: round(x / 1e9, 2) if pd.notna(x) and x > 0 else 0
)

# Calculate sector P/E ratio (sector market cap ÷ sector earnings)
sector_summary['Sector_PE_Ratio'] = sector_summary.apply(
    lambda row: round(row['Total_Market_Cap'] / row['Total_Sector_Earnings'], 2) 
    if pd.notna(row['Total_Market_Cap']) and pd.notna(row['Total_Sector_Earnings']) 
    and row['Total_Sector_Earnings'] > 0 else None, axis=1
)

# Calculate percentage share of total market cap
total_market_cap = sector_summary['Total_Market_Cap'].sum()
sector_summary['Market_Cap_Percentage'] = sector_summary['Total_Market_Cap'].apply(
    lambda x: round((x / total_market_cap * 100), 2) if pd.notna(x) and x > 0 and total_market_cap > 0 else 0
)

# Sort by market cap (descending)
sector_summary = sector_summary.sort_values('Total_Market_Cap', ascending=False)

# Display the summary table
print("\nGICS Sector Summary Table:")
print("=" * 140)
print(f"{'GICS Sector':<25} {'Ticker Count':<15} {'Market Cap ($B)':<20} {'Sector Earnings ($B)':<25} {'Sector P/E':<15} {'% of Total':<15}")
print("=" * 140)
for sector, row in sector_summary.iterrows():
    ticker_count = int(row['Ticker_Count'])
    market_cap_b = row['Total_Market_Cap_Billions']
    sector_earnings_b = row['Total_Sector_Earnings_Billions']
    sector_pe = f"{row['Sector_PE_Ratio']:.1f}" if pd.notna(row['Sector_PE_Ratio']) else "N/A"
    percentage = row['Market_Cap_Percentage']
    print(f"{sector:<25} {ticker_count:<15} ${market_cap_b:<19,.2f} ${sector_earnings_b:<24,.2f} {sector_pe:<15} {percentage:<14.2f}%")

# Calculate and display totals
total_tickers = sector_summary['Ticker_Count'].sum()
total_market_cap_b = total_market_cap / 1e9
total_sector_earnings = sector_summary['Total_Sector_Earnings'].sum()
total_sector_earnings_b = total_sector_earnings / 1e9
overall_pe = total_market_cap / total_sector_earnings if total_sector_earnings > 0 else None
overall_pe_str = f"{overall_pe:.1f}" if overall_pe is not None else "N/A"

print("=" * 140)
print(f"{'TOTAL':<25} {total_tickers:<15} ${total_market_cap_b:<19,.2f} ${total_sector_earnings_b:<24,.2f} {overall_pe_str:<15} {'100.00':<14}%")

# Save sector summary to CSV
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
sector_summary_path = f"gics_sector_summary_{timestamp}.csv"
sector_summary.to_csv(sector_summary_path)
print(f"\nSaved GICS sector summary to {sector_summary_path}")

# 6) Create GICS Sector Constituents Table (sorted by market cap) ------------
print("\nCreating GICS Sector Constituents Table...")

# Create a list to store all rows for the constituents table
constituents_data = []

# For each GICS sector, get all tickers sorted by market cap (descending)
for sector in sector_summary.index:
    # Get all tickers for this sector
    sector_tickers = sp500_tbl[sp500_tbl['GICS Sector'] == sector].copy()
    
    # Sort by market cap (descending) - largest to smallest
    sector_tickers_sorted = sector_tickers.sort_values('Market_Cap', ascending=False, na_position='last')
    
    # Add each ticker to the constituents data
    for _, row in sector_tickers_sorted.iterrows():
        constituents_data.append({
            'GICS_Sector': sector,
            'Ticker': row['Symbol'],
            'Company_Name': row['Security'],
            'Market_Cap': row['Market_Cap'],
            'Market_Cap_Billions': row['Market_Cap_Billions'],
            'Latest_Price': row['Latest_Price'],
            'Trailing_EPS': row['Trailing_EPS'],
            'Forward_EPS': row['Forward_EPS'],
            'Trailing_PE': row['Trailing_PE'],
            'Forward_PE': row['Forward_PE'],
            'Trailing_Earnings': row['Trailing_Earnings'],
            'EPS_Growth_Rate': row['EPS_Growth_Rate'],
            'Return_on_Equity': row['Return_on_Equity'],
            'Data_Quality_Score': row['Data_Quality_Score'],
            'Data_Completeness': row['Data_Completeness'],
            'GICS_Sub_Industry': row['GICS Sub-Industry']
        })

# Create the constituents dataframe
constituents_df = pd.DataFrame(constituents_data)

# Save the constituents table to CSV
constituents_path = f"gics_sector_constituents_{timestamp}.csv"
constituents_df.to_csv(constituents_path, index=False)
print(f"Saved GICS sector constituents table to {constituents_path}")

# Display a sample of the constituents table
print(f"\nSample of GICS Sector Constituents Table (first 20 rows):")
print("=" * 160)
print(f"{'GICS Sector':<20} {'Ticker':<8} {'Company':<25} {'Market Cap':<12} {'Trail EPS':<10} {'Fwd EPS':<10} {'Trail Earn':<12} {'ROE':<8} {'Quality':<8}")
print("=" * 160)
for _, row in constituents_df.head(20).iterrows():
    sector = row['GICS_Sector'][:19]  # Truncate if too long
    ticker = row['Ticker']
    company = row['Company_Name'][:24]  # Truncate if too long
    market_cap_b = f"${row['Market_Cap_Billions']:.1f}B" if pd.notna(row['Market_Cap_Billions']) else "N/A"
    trailing_eps = f"${row['Trailing_EPS']:.2f}" if pd.notna(row['Trailing_EPS']) else "N/A"
    forward_eps = f"${row['Forward_EPS']:.2f}" if pd.notna(row['Forward_EPS']) else "N/A"
    trailing_earnings = f"${row['Trailing_Earnings']/1e6:.1f}M" if pd.notna(row['Trailing_Earnings']) else "N/A"
    roe = f"{row['Return_on_Equity']:.1f}%" if pd.notna(row['Return_on_Equity']) else "N/A"
    quality = f"{row['Data_Quality_Score']:.0f}/10" if pd.notna(row['Data_Quality_Score']) else "N/A"
    print(f"{sector:<20} {ticker:<8} {company:<25} {market_cap_b:<12} {trailing_eps:<10} {forward_eps:<10} {trailing_earnings:<12} {roe:<8} {quality:<8}")

print(f"\nTotal rows in constituents table: {len(constituents_df)}")

output_path = f"sp500_latest_{timestamp}.csv"
sp500_tbl.to_csv(output_path, index=False)
print(f"\nSaved results to {output_path}")

Constituent highlights

  • S&P 500 constituents cover 503 companies with a combined market capitalization of $56.7 trillion.

  • Total Market Cap: $56.7 trillion

  • Average Company Size: $112.8 billion

  • Data Quality Score: 7.4/10

  • Data Completeness: 92.1%

Portfolio Weights: All tables now include portfolio weight columns showing each company’s and sector’s percentage allocation within the S&P 500 index.

Sector Overview

GICS Sector Summary
Market Capitalization and Key Metrics by Sector
GICS Sector Companies Total_Market_Cap_Billions Avg_Market_Cap_Billions Median_Market_Cap_Billions Avg Trailing P/E Avg Forward P/E Avg ROE Avg Data Quality Portfolio Weight (%) Total Market Cap Avg Market Cap Median Market Cap
Information Technology 68 18617.85 273.79191 56.965 54.4 30.9 0.367 7.7 32.8 18.6T 273.8B 57B
Financials 75 7653.66 102.04880 47.810 36.1 18.4 0.186 7.3 13.5 7.7T 102B 47.8B
Consumer Discretionary 51 6231.98 122.19569 36.570 32.4 23.5 0.305 7.5 11.0 6.2T 122.2B 36.6B
Communication Services 24 6049.05 252.04375 36.625 50.1 19.5 0.164 7.0 10.7 6T 252B 36.6B
Health Care 60 5105.90 85.09833 36.735 31.4 19.5 2.614 7.7 9.0 5.1T 85.1B 36.7B
Industrials 78 4676.03 59.94910 47.630 34.8 31.5 0.375 7.5 8.2 4.7T 59.9B 47.6B
Consumer Staples 37 3301.35 89.22568 27.480 22.9 19.1 0.379 7.3 5.8 3.3T 89.2B 27.5B
Energy 22 1673.36 76.06182 46.050 21.1 14.5 0.158 7.2 3.0 1.7T 76.1B 46B
Utilities 31 1288.17 41.55387 28.420 22.3 18.8 0.114 7.4 2.3 1.3T 41.6B 28.4B
Real Estate 31 1103.93 35.61065 26.530 202.9 55.7 0.030 7.0 1.9 1.1T 35.6B 26.5B
Materials 26 1043.57 40.13731 24.575 55.9 18.9 0.120 7.2 1.8 1T 40.1B 24.6B
TOTAL 503 56744.85 5158.62273 4676.030 51.3 24.6 0.438 7.3 100.0 56.7T 5158.6B 4676B
Data source: Yahoo Finance via yfinance API | Generated: September 2025

Sector Total Returns

Sector Total Returns Summary
Performance Metrics and Market Capitalization by Sector (S&P 500 TOTAL at bottom)
GICS Sector Companies Market Cap (T$) Price Return (%) Dividend Yield (%) Total Return (%) Avg Stock Return (%)
Communication Services 24 6.05 41.2 0.77 41.9 29.3
Information Technology 68 18.62 29.4 0.62 30.0 22.6
Consumer Discretionary 51 6.23 25.8 0.68 26.5 24.7
Financials 75 7.65 22.3 1.61 23.9 21.1
Industrials 78 4.68 19.4 1.69 21.1 19.6
Utilities 31 1.29 12.7 3.30 16.0 21.6
Energy 22 1.67 5.6 4.19 9.7 11.3
Consumer Staples 37 3.30 4.5 2.45 6.9 −1.0
Materials 26 1.04 3.6 2.10 5.7 3.6
Real Estate 31 1.10 −1.3 3.60 2.3 1.2
Health Care 60 5.11 −9.8 1.93 −7.8 −4.7
S&P 500 TOTAL 503 56.74 19.5 1.34 20.9 NA
Data source: Sector Performance Analysis | Generated: September 2025

Top 20 Companies by Market Cap

Top 20 S&P 500 Companies
Ranked by Market Capitalization
Ticker Company Name Sector Market_Cap_Billions Portfolio Weight (%) Price ($) Trailing P/E Forward P/E ROE Market Cap
NVDA Nvidia Information Technology 4154.09 7.3 170.62 48.5 41.4 1.094 4.2T
MSFT Microsoft Information Technology 3756.35 6.6 505.35 37.0 33.8 0.333 3.8T
AAPL Apple Inc. Information Technology 3538.99 6.2 238.47 36.2 28.7 1.498 3.5T
AMZN Amazon Consumer Discretionary 2410.16 4.2 225.99 34.4 36.7 0.248 2.4T
META Meta Platforms Communication Services 1598.63 2.8 737.05 26.7 29.1 0.406 1.6T
AVGO Broadcom Information Technology 1422.28 2.5 302.39 110.4 49.0 0.190 1.4T
GOOGL Alphabet Inc. (Class A) Communication Services 1341.75 2.4 230.66 24.6 25.7 0.348 1.3T
GOOG Alphabet Inc. (Class C) Communication Services 1254.87 2.2 231.10 24.7 25.8 0.348 1.3T
TSLA Tesla, Inc. Consumer Discretionary 1077.59 1.9 334.09 198.9 103.1 0.082 1.1T
JPM JPMorgan Chase Financials 823.58 1.5 299.51 15.4 17.9 0.162 823.6B
WMT Walmart Consumer Staples 792.82 1.4 99.44 37.5 36.6 0.234 792.8B
BRK.B Berkshire Hathaway Financials 691.33 1.2 501.49 17.2 25.0 0.099 691.3B
LLY Lilly (Eli) Health Care 661.43 1.2 737.83 48.3 32.6 0.863 661.4B
ORCL Oracle Corporation Information Technology 627.63 1.1 223.45 51.4 31.2 0.824 627.6B
V Visa Inc. Financials 596.02 1.1 350.87 34.2 27.7 0.518 596B
MA Mastercard Financials 532.33 0.9 593.28 39.9 36.2 1.769 532.3B
NFLX Netflix Communication Services 521.04 0.9 1,226.18 52.3 51.6 0.435 521B
XOM ExxonMobil Energy 477.10 0.8 111.91 15.9 14.2 0.118 477.1B
JNJ Johnson & Johnson Health Care 428.68 0.8 178.00 19.0 16.8 0.302 428.7B
COST Costco Consumer Staples 421.21 0.7 949.78 53.8 48.3 0.321 421.2B

Sector Deep Dives

Information Technology

Information Technology Sector - 68 companies, $18.6T market cap
Top 20 Companies by Market Cap
Ticker Company Name Sub-Industry Market_Cap_Billions Portfolio Weight (%) Price ($) Trailing P/E Forward P/E ROE Market Cap
NVDA Nvidia Semiconductors 4154.09 7.3 170.62 48.5 41.4 1.094 4.2T
MSFT Microsoft Systems Software 3756.35 6.6 505.35 37.0 33.8 0.333 3.8T
AAPL Apple Inc. Technology Hardware, Storage & Peripherals 3538.99 6.2 238.47 36.2 28.7 1.498 3.5T
AVGO Broadcom Semiconductors 1422.28 2.5 302.39 110.4 49.0 0.190 1.4T
ORCL Oracle Corporation Application Software 627.63 1.1 223.45 51.4 31.2 0.824 627.6B
PLTR Palantir Technologies Application Software 352.28 0.6 154.90 516.3 329.6 0.152 352.3B
CSCO Cisco Communications Equipment 267.97 0.5 67.67 25.9 17.4 0.226 268B
AMD Advanced Micro Devices Semiconductors 263.11 0.5 162.13 97.1 31.8 0.047 263.1B
CRM Salesforce Application Software 245.17 0.4 256.45 40.1 23.0 0.103 245.2B
IBM IBM IT Consulting & Other Services 227.38 0.4 244.10 39.3 23.0 0.227 227.4B
NOW ServiceNow Systems Software 190.79 0.3 919.38 115.9 55.1 0.170 190.8B
INTU Intuit Application Software 186.53 0.3 668.68 49.0 30.1 0.203 186.5B
TXN Texas Instruments Semiconductors 177.95 0.3 195.74 35.8 33.3 0.300 177.9B
ANET Arista Networks Communications Equipment 172.67 0.3 137.38 53.9 14.1 0.336 172.7B
QCOM Qualcomm Semiconductors 169.71 0.3 157.28 15.2 12.9 0.446 169.7B
ACN Accenture IT Consulting & Other Services 158.30 0.3 254.15 20.2 18.1 0.269 158.3B
ADBE Adobe Inc. Application Software 147.83 0.3 348.50 22.3 17.0 0.523 147.8B
APH Amphenol Electronic Components 135.14 0.2 110.69 44.1 51.2 0.310 135.1B
MU Micron Technology Semiconductors 132.86 0.2 118.72 21.4 9.2 0.131 132.9B
PANW Palo Alto Networks Systems Software 128.11 0.2 191.53 119.7 26.6 0.175 128.1B

Financials

Financials Sector - 75 companies, $7.7T market cap
Top 20 Companies by Market Cap
Ticker Company Name Sub-Industry Market_Cap_Billions Portfolio Weight (%) Price ($) Trailing P/E Forward P/E ROE Market Cap
JPM JPMorgan Chase Diversified Banks 823.58 1.5 299.51 15.4 17.9 0.162 823.6B
BRK.B Berkshire Hathaway Multi-Sector Holdings 691.33 1.2 501.49 17.2 25.0 0.099 691.3B
V Visa Inc. Transaction & Payment Processing Services 596.02 1.1 350.87 34.2 27.7 0.518 596B
MA Mastercard Transaction & Payment Processing Services 532.33 0.9 593.28 39.9 36.2 1.769 532.3B
BAC Bank of America Diversified Banks 370.79 0.7 50.06 14.7 13.7 0.095 370.8B
WFC Wells Fargo Diversified Banks 257.91 0.5 80.51 13.8 14.7 0.115 257.9B
MS Morgan Stanley Investment Banking & Brokerage 237.10 0.4 148.53 16.8 18.7 0.141 237.1B
AXP American Express Consumer Finance 225.26 0.4 323.71 22.7 21.4 0.328 225.3B
GS Goldman Sachs Investment Banking & Brokerage 221.16 0.4 730.56 16.1 17.6 0.127 221.2B
C Citigroup Diversified Banks 174.94 0.3 95.03 14.0 13.2 0.068 174.9B
SCHW Charles Schwab Corporation Investment Banking & Brokerage 174.66 0.3 96.22 25.9 25.3 0.156 174.7B
BLK BlackRock Asset Management & Custody Banks 170.26 0.3 1,099.49 26.6 22.4 0.139 170.3B
SPGI S&P Global Financial Exchanges & Data 164.63 0.3 539.24 41.4 32.1 0.113 164.6B
PGR Progressive Corporation Property & Casualty Insurance 144.68 0.3 246.72 13.9 17.9 0.373 144.7B
COF Capital One Consumer Finance 141.54 0.2 221.33 614.8 14.1 0.000 141.5B
BX Blackstone Inc. Asset Management & Custody Banks 123.34 0.2 167.34 45.2 28.7 0.288 123.3B
KKR KKR & Co. Asset Management & Custody Banks 120.13 0.2 134.83 63.6 22.2 0.075 120.1B
CB Chubb Limited Property & Casualty Insurance 110.92 0.2 278.22 12.3 11.8 0.136 110.9B
MMC Marsh McLennan Insurance Brokers 100.92 0.2 205.27 24.7 21.8 0.284 100.9B
ICE Intercontinental Exchange Financial Exchanges & Data 100.25 0.2 175.13 33.5 26.0 0.111 100.2B

Interactive Data Explorer

For detailed exploration of all 503 companies, use the interactive table below:

Data Quality Assessment

Data Quality Summary
Completeness and Quality of Financial Data
Data Quality Metric Value
Companies with Trailing EPS 503
Companies with Forward EPS 500
Companies with Trailing P/E 480
Companies with Forward P/E 503
Companies with ROE Data 475
Average Data Quality Score 7.4
Average Data Completeness 92.1%

Key Insights

  1. Market Concentration: The top 10 companies represent approximately 40% of the total S&P 500 market capitalization.

  2. Sector Dominance: Information Technology leads with $18.6 trillion in market cap, followed by Financials at $7.7 trillion.

  3. Data Quality: Excellent data coverage with 92.1% completeness and an average quality score of 7.4/10.

  4. Valuation Metrics: Forward P/E ratios are generally lower than trailing P/E ratios, suggesting earnings growth expectations.

  5. Geographic Distribution: All companies are US-based, providing exposure to the largest equity market globally.

  6. Portfolio Weights: Portfolio weight columns (defined as company market capitalization / total market capitalization) show each company’s and sector’s percentage allocation within the S&P 500 index.


Report generated on 2025-09-04 using data from Yahoo Finance via yfinance API.