CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-yfinance

Download market data from Yahoo! Finance API

Overview
Eval results
Files

market-sector.mddocs/

Market and Sector Analysis

Market status information, sector performance data, and industry-level analysis for broader market intelligence. These capabilities provide macroeconomic context and sector-specific insights for investment research and market analysis.

Capabilities

Market Status and Summary

Access comprehensive market status information including trading hours, market state, and summary data across exchanges.

class Market:
    def __init__(self, market: str, session=None, timeout: int = 30):
        """
        Create a Market object for accessing market-level data.
        
        Parameters:
        - market: str, market identifier (e.g., 'US', 'NYSE', 'NASDAQ')
        - session: requests.Session, optional session for HTTP requests
        - timeout: int, request timeout in seconds
        """
    
    # Properties
    status: dict  # Market status information including trading hours and state
    summary: dict  # Market summary data organized by exchange

Market Status Information

The status property provides detailed market timing and operational information:

# Market status structure
{
    'market': 'US',
    'timezone': 'America/New_York',
    'current_time': '2024-01-15 14:30:00',
    'market_state': 'REGULAR',  # REGULAR, PRE, POST, CLOSED
    'next_open': '2024-01-16 09:30:00',
    'next_close': '2024-01-15 16:00:00',
    'is_open': True,
    'session_info': {
        'regular_market_start': '09:30:00',
        'regular_market_end': '16:00:00',
        'pre_market_start': '04:00:00',
        'post_market_end': '20:00:00'
    }
}

Market Summary Data

The summary property provides aggregated market data by exchange:

# Market summary structure
{
    'NYSE': {
        'advancing_issues': 1205,
        'declining_issues': 892,
        'unchanged_issues': 67,
        'total_volume': 2847362100,
        'advance_decline_ratio': 1.35
    },
    'NASDAQ': {
        'advancing_issues': 1834,
        'declining_issues': 1456,
        'unchanged_issues': 123,
        'total_volume': 3967234800,
        'advance_decline_ratio': 1.26
    }
}

Usage Examples

import yfinance as yf

# US market analysis
us_market = yf.Market('US')

# Check if market is open
market_status = us_market.status
is_trading = market_status['is_open']
current_state = market_status['market_state']

print(f"Market is {'open' if is_trading else 'closed'}")
print(f"Current market state: {current_state}")

# Market breadth analysis
market_summary = us_market.summary
for exchange, data in market_summary.items():
    advancing = data.get('advancing_issues', 0)
    declining = data.get('declining_issues', 0)
    ratio = data.get('advance_decline_ratio', 0)
    
    print(f"{exchange}: {advancing} up, {declining} down (A/D: {ratio:.2f})")

Sector-Level Analysis

Access sector-specific data including top ETFs, mutual funds, and constituent industries.

class Sector:
    def __init__(self, key: str, session=None):
        """
        Create a Sector object for accessing sector-level data.
        
        Parameters:
        - key: str, sector key identifier (e.g., 'technology', 'healthcare', 'finance')
        - session: requests.Session, optional session for HTTP requests
        """
    
    # Properties
    top_etfs: Dict[str, str]  # Top ETFs in sector {symbol: name}
    top_mutual_funds: Dict[str, str]  # Top mutual funds {symbol: name}
    industries: pd.DataFrame  # Industries within the sector with performance data

Sector Properties Details

Top ETFs: Dictionary mapping ETF symbols to names for the sector

{
    'XLK': 'Technology Select Sector SPDR Fund',
    'VGT': 'Vanguard Information Technology ETF',
    'IYW': 'iShares U.S. Technology ETF',
    'FTEC': 'Fidelity MSCI Information Technology Index ETF'
}

Top Mutual Funds: Dictionary mapping mutual fund symbols to names

{
    'FXNAX': 'Fidelity U.S. Sustainability Index Fund',
    'VITAX': 'Vanguard Information Technology Index Fund',
    'TRBCX': 'T. Rowe Price Blue Chip Growth Fund'
}

Industries DataFrame: Contains detailed industry breakdown within the sector

  • Index: Industry names
  • Columns: Performance metrics, market cap data, constituent counts

Usage Examples

# Technology sector analysis
tech_sector = yf.Sector('technology')

# Get top investment vehicles
top_tech_etfs = tech_sector.top_etfs
top_tech_funds = tech_sector.top_mutual_funds

print("Top Technology ETFs:")
for symbol, name in top_tech_etfs.items():
    print(f"  {symbol}: {name}")

# Analyze sector industries
tech_industries = tech_sector.industries
print("\nTechnology Sector Industries:")
print(tech_industries)

# Industry performance comparison
if not tech_industries.empty:
    # Assuming industries DataFrame has performance columns
    best_performing = tech_industries.nlargest(3, 'performance')
    print(f"\nBest performing tech industries:")
    print(best_performing)

Industry-Level Analysis

Access detailed industry-specific data including top performing companies and growth metrics.

class Industry:
    def __init__(self, key: str, session=None):
        """
        Create an Industry object for accessing industry-level data.
        
        Parameters:
        - key: str, industry key identifier (e.g., 'software', 'semiconductors', 'biotechnology')
        - session: requests.Session, optional session for HTTP requests
        """
    
    # Properties
    sector_key: str  # Parent sector key
    sector_name: str  # Parent sector display name
    top_performing_companies: pd.DataFrame  # Top performing companies in industry
    top_growth_companies: pd.DataFrame  # Companies with highest growth rates

Industry Properties Details

Parent Sector Information:

  • sector_key: Machine-readable sector identifier
  • sector_name: Human-readable sector name

Top Performing Companies DataFrame:

  • Columns: symbol, name, price, change, change_percent, market_cap, volume
  • Sorted by performance metrics (typically price change or returns)

Top Growth Companies DataFrame:

  • Columns: symbol, name, revenue_growth, earnings_growth, projected_growth
  • Sorted by growth metrics

Usage Examples

# Software industry analysis
software_industry = yf.Industry('software')

# Check parent sector
print(f"Industry: Software")
print(f"Parent Sector: {software_industry.sector_name} ({software_industry.sector_key})")

# Top performing companies
top_performers = software_industry.top_performing_companies
print(f"\nTop Performing Software Companies:")
print(top_performers[['symbol', 'name', 'change_percent']].head())

# High growth companies
growth_companies = software_industry.top_growth_companies
print(f"\nHigh Growth Software Companies:")
print(growth_companies[['symbol', 'name', 'revenue_growth']].head())

# Create watchlist from top performers
watchlist_symbols = top_performers['symbol'].head(10).tolist()
print(f"\nWatchlist: {watchlist_symbols}")

Advanced Market Analysis Patterns

Cross-Sector Comparison

def compare_sectors(sector_keys, metric='performance'):
    """Compare multiple sectors across key metrics."""
    
    sector_data = {}
    
    for sector_key in sector_keys:
        sector = yf.Sector(sector_key)
        sector_data[sector_key] = {
            'top_etfs': sector.top_etfs,
            'top_funds': sector.top_mutual_funds,
            'industries': sector.industries
        }
    
    # Create comparison summary
    comparison = {}
    for sector_key, data in sector_data.items():
        etf_count = len(data['top_etfs'])
        fund_count = len(data['top_funds'])
        industry_count = len(data['industries']) if not data['industries'].empty else 0
        
        comparison[sector_key] = {
            'etf_options': etf_count,
            'fund_options': fund_count,
            'industry_diversity': industry_count
        }
    
    return comparison, sector_data

# Usage
sectors = ['technology', 'healthcare', 'finance', 'energy']
comparison, detailed_data = compare_sectors(sectors)

for sector, metrics in comparison.items():
    print(f"{sector.capitalize()}: {metrics['etf_options']} ETFs, "
          f"{metrics['fund_options']} funds, {metrics['industry_diversity']} industries")

Industry Leadership Analysis

def analyze_industry_leaders(industry_key, top_n=5):
    """Analyze leadership and growth trends within an industry."""
    
    industry = yf.Industry(industry_key)
    
    # Get top companies by different metrics
    top_performers = industry.top_performing_companies.head(top_n)
    growth_leaders = industry.top_growth_companies.head(top_n)
    
    # Create detailed analysis
    analysis = {
        'industry': industry_key,
        'sector': industry.sector_name,
        'performance_leaders': [],
        'growth_leaders': [],
        'overlap': []
    }
    
    # Process performance leaders
    for _, company in top_performers.iterrows():
        analysis['performance_leaders'].append({
            'symbol': company['symbol'],
            'name': company['name'],
            'performance_metric': company.get('change_percent', 0)
        })
    
    # Process growth leaders
    for _, company in growth_leaders.iterrows():
        analysis['growth_leaders'].append({
            'symbol': company['symbol'],
            'name': company['name'],
            'growth_metric': company.get('revenue_growth', 0)
        })
    
    # Find overlap between performance and growth leaders
    perf_symbols = set(top_performers['symbol'])
    growth_symbols = set(growth_leaders['symbol'])
    overlap_symbols = perf_symbols.intersection(growth_symbols)
    
    analysis['overlap'] = list(overlap_symbols)
    
    return analysis

# Usage
software_analysis = analyze_industry_leaders('software', top_n=10)
print(f"Software Industry Analysis:")
print(f"Performance Leaders: {[comp['symbol'] for comp in software_analysis['performance_leaders']]}")
print(f"Growth Leaders: {[comp['symbol'] for comp in software_analysis['growth_leaders']]}")
print(f"Both Performance & Growth: {software_analysis['overlap']}")

Market Breadth Analysis

def analyze_market_breadth(market_key='US'):
    """Analyze market breadth indicators."""
    
    market = yf.Market(market_key)
    summary = market.summary
    
    breadth_metrics = {}
    
    for exchange, data in summary.items():
        advancing = data.get('advancing_issues', 0)
        declining = data.get('declining_issues', 0)
        unchanged = data.get('unchanged_issues', 0)
        total_volume = data.get('total_volume', 0)
        
        total_issues = advancing + declining + unchanged
        
        if total_issues > 0:
            breadth_metrics[exchange] = {
                'advance_decline_ratio': advancing / declining if declining > 0 else float('inf'),
                'advance_percent': (advancing / total_issues) * 100,
                'decline_percent': (declining / total_issues) * 100,
                'unchanged_percent': (unchanged / total_issues) * 100,
                'total_volume': total_volume,
                'breadth_momentum': 'Positive' if advancing > declining else 'Negative'
            }
    
    # Overall market breadth
    total_advancing = sum(data.get('advancing_issues', 0) for data in summary.values())
    total_declining = sum(data.get('declining_issues', 0) for data in summary.values())
    
    overall_breadth = {
        'overall_ad_ratio': total_advancing / total_declining if total_declining > 0 else float('inf'),
        'market_sentiment': 'Bullish' if total_advancing > total_declining else 'Bearish',
        'by_exchange': breadth_metrics
    }
    
    return overall_breadth

# Usage
breadth_analysis = analyze_market_breadth()
print(f"Overall A/D Ratio: {breadth_analysis['overall_ad_ratio']:.2f}")
print(f"Market Sentiment: {breadth_analysis['market_sentiment']}")

for exchange, metrics in breadth_analysis['by_exchange'].items():
    print(f"{exchange}: {metrics['advance_percent']:.1f}% advancing, "
          f"momentum: {metrics['breadth_momentum']}")

Sector Rotation Analysis

def analyze_sector_rotation(sectors, timeframe='1mo'):
    """Analyze sector rotation patterns by comparing sector ETF performance."""
    
    sector_analysis = {}
    
    for sector_key in sectors:
        sector = yf.Sector(sector_key)
        top_etfs = sector.top_etfs
        
        if top_etfs:
            # Get the primary ETF (usually first one) for sector representation
            primary_etf = list(top_etfs.keys())[0]
            
            # Get ETF performance data
            etf_ticker = yf.Ticker(primary_etf)
            history = etf_ticker.history(period=timeframe)
            
            if not history.empty:
                total_return = (history['Close'].iloc[-1] / history['Close'].iloc[0] - 1) * 100
                volatility = history['Close'].pct_change().std() * 100
                
                sector_analysis[sector_key] = {
                    'primary_etf': primary_etf,
                    'etf_name': top_etfs[primary_etf],
                    'total_return': total_return,
                    'volatility': volatility,
                    'risk_adjusted_return': total_return / volatility if volatility > 0 else 0
                }
    
    # Rank sectors by performance
    sorted_sectors = sorted(sector_analysis.items(), 
                          key=lambda x: x[1]['total_return'], reverse=True)
    
    rotation_analysis = {
        'timeframe': timeframe,
        'leader_sectors': sorted_sectors[:3],
        'laggard_sectors': sorted_sectors[-3:],
        'all_sectors': dict(sorted_sectors)
    }
    
    return rotation_analysis

# Usage
sectors = ['technology', 'healthcare', 'finance', 'energy', 'utilities', 'materials']
rotation = analyze_sector_rotation(sectors, timeframe='3mo')

print("Sector Rotation Analysis (3 months):")
print("\nLeading Sectors:")
for sector, data in rotation['leader_sectors']:
    print(f"  {sector.capitalize()}: {data['total_return']:+.2f}% "
          f"({data['primary_etf']})")

print("\nLagging Sectors:")
for sector, data in rotation['laggard_sectors']:
    print(f"  {sector.capitalize()}: {data['total_return']:+.2f}% "
          f"({data['primary_etf']})")

Market Timing Indicators

def generate_market_timing_signals(market_key='US'):
    """Generate market timing signals based on breadth and sector data."""
    
    market = yf.Market(market_key)
    status = market.status
    summary = market.summary
    
    signals = {
        'timestamp': status.get('current_time'),
        'market_state': status.get('market_state'),
        'signals': []
    }
    
    # Breadth-based signals
    total_advancing = sum(data.get('advancing_issues', 0) for data in summary.values())
    total_declining = sum(data.get('declining_issues', 0) for data in summary.values())
    
    if total_advancing > 0 and total_declining > 0:
        ad_ratio = total_advancing / total_declining
        
        if ad_ratio > 2.0:
            signals['signals'].append({
                'type': 'BULLISH',
                'indicator': 'Advance/Decline Ratio',
                'value': ad_ratio,
                'description': 'Strong market breadth - many stocks advancing'
            })
        elif ad_ratio < 0.5:
            signals['signals'].append({
                'type': 'BEARISH',
                'indicator': 'Advance/Decline Ratio',
                'value': ad_ratio,
                'description': 'Weak market breadth - many stocks declining'
            })
    
    # Volume-based signals
    total_volume = sum(data.get('total_volume', 0) for data in summary.values())
    
    # Note: This would typically compare to historical averages
    # For demonstration, using arbitrary thresholds
    if total_volume > 5_000_000_000:  # 5B+ shares
        signals['signals'].append({
            'type': 'BULLISH',
            'indicator': 'High Volume',
            'value': total_volume,
            'description': 'High trading volume indicates strong participation'
        })
    
    # Market state signals
    if status.get('is_open'):
        signals['signals'].append({
            'type': 'NEUTRAL',
            'indicator': 'Market State',
            'value': status.get('market_state'),
            'description': f"Market is currently {status.get('market_state').lower()}"
        })
    
    return signals

# Usage
timing_signals = generate_market_timing_signals()
print(f"Market Timing Analysis - {timing_signals['timestamp']}")
print(f"Market State: {timing_signals['market_state']}")

for signal in timing_signals['signals']:
    print(f"{signal['type']}: {signal['indicator']} - {signal['description']}")

Integration with Other yfinance Features

Portfolio Sector Allocation

def analyze_portfolio_sector_allocation(portfolio_symbols):
    """Analyze sector allocation of a portfolio."""
    
    portfolio_sectors = {}
    total_value = 0
    
    for symbol in portfolio_symbols:
        ticker = yf.Ticker(symbol)
        info = ticker.info
        
        sector = info.get('sector', 'Unknown')
        market_cap = info.get('marketCap', 0)
        
        if sector not in portfolio_sectors:
            portfolio_sectors[sector] = {
                'symbols': [],
                'total_market_cap': 0,
                'count': 0
            }
        
        portfolio_sectors[sector]['symbols'].append(symbol)
        portfolio_sectors[sector]['total_market_cap'] += market_cap
        portfolio_sectors[sector]['count'] += 1
        total_value += market_cap
    
    # Calculate allocations
    for sector_data in portfolio_sectors.values():
        sector_data['allocation_percent'] = (
            sector_data['total_market_cap'] / total_value * 100 
            if total_value > 0 else 0
        )
    
    return portfolio_sectors

# Usage
portfolio = ["AAPL", "GOOGL", "MSFT", "JNJ", "JPM", "PFE", "XOM", "WMT"]
sector_allocation = analyze_portfolio_sector_allocation(portfolio)

print("Portfolio Sector Allocation:")
for sector, data in sector_allocation.items():
    print(f"{sector}: {data['allocation_percent']:.1f}% "
          f"({data['count']} stocks: {', '.join(data['symbols'])})")

Sector-Based Stock Screening

def screen_stocks_by_sector_performance(sector_key, performance_threshold=5.0):
    """Screen stocks within high-performing sectors."""
    
    # First, analyze the sector
    sector = yf.Sector(sector_key)
    industries = sector.industries
    
    if industries.empty:
        return []
    
    # Get top performing industries (assuming performance column exists)
    top_industries = industries.nlargest(3, 'performance') if 'performance' in industries.columns else industries.head(3)
    
    screened_stocks = []
    
    for industry_name in top_industries.index:
        try:
            # Create industry object (this assumes industry key matches name)
            industry = yf.Industry(industry_name.lower().replace(' ', '_'))
            
            # Get top performing companies
            top_companies = industry.top_performing_companies
            
            # Filter by performance threshold
            if not top_companies.empty and 'change_percent' in top_companies.columns:
                filtered_companies = top_companies[
                    top_companies['change_percent'] > performance_threshold
                ]
                
                for _, company in filtered_companies.iterrows():
                    screened_stocks.append({
                        'symbol': company['symbol'],
                        'name': company['name'],
                        'sector': sector_key,
                        'industry': industry_name,
                        'performance': company['change_percent']
                    })
        
        except Exception as e:
            print(f"Error processing industry {industry_name}: {e}")
            continue
    
    return screened_stocks

# Usage
tech_performers = screen_stocks_by_sector_performance('technology', performance_threshold=3.0)
print("High-performing technology stocks:")
for stock in tech_performers[:10]:  # Top 10
    print(f"{stock['symbol']}: {stock['performance']:+.2f}% ({stock['industry']})")

Install with Tessl CLI

npx tessl i tessl/pypi-yfinance

docs

bulk-data.md

config-utils.md

index.md

live-streaming.md

market-sector.md

screening.md

search-lookup.md

ticker-data.md

tile.json