Download market data from Yahoo! Finance API
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.
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 exchangeThe 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'
}
}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
}
}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})")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 dataTop 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
# 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)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 ratesParent Sector Information:
sector_key: Machine-readable sector identifiersector_name: Human-readable sector nameTop Performing Companies DataFrame:
Top Growth Companies DataFrame:
# 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}")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")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']}")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']}")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']})")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']}")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'])})")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