Advanced financial sentiment analysis tool with policy impact assessment
Project description
๐ Stockholm Finance
Advanced financial sentiment analysis with interactive terminal dashboard, intelligent caching, and real-time market data integration.
๐ Quick Start
# Install
pip install stockholm-finance
# Run
stockholm-finance
โจ Features
- ๐ฏ Sentiment Analysis: NLP-powered market sentiment from financial news
- ๐ Interactive Dashboard: Professional terminal UI with real-time data
- ๐พ Smart Caching: TTL-based caching for optimal performance
- ๐๏ธ Policy Analysis: Government policy impact assessment
- ๐ Live Charts: Interactive price history and trend visualization
- ๐ Real-time Updates: Live market data integration
๐ Usage
Command Line
stockholm-finance # Launch interactive dashboard
stockholm-finance --quick # Quick startup mode (fewer tickers)
stockholm-finance --verbose # Debug information
stockholm-finance --warm-cache # Pre-warm cache for faster startup
stockholm-finance --quick --warm-cache # Quick mode with cache warming
Performance Optimization
Stockholm includes several performance optimizations for faster startup:
- ๐ฅ Hot Loading: Dashboard appears immediately while data loads progressively in background
- ๐ฆ Intelligent Caching: Reduces API calls by 80-90% with smart TTL-based caching
- โก Background Data Fetching: Continuous cache warming while dashboard is running
- ๐ Cache Pre-warming: Use
--warm-cacheto populate cache before startup
# For fastest startup experience:
stockholm-finance --quick --warm-cache
# Benchmark performance improvements:
python scripts/benchmark_startup.py
Python API
from src.core.financial_analyzer import main
main() # Launch dashboard programmatically
๐๏ธ Development
Setup
git clone https://github.com/aykaym/stockholm.git
cd stockholm
pip install -e ".[dev]"
Testing
pytest tests/ -v # Run tests
pytest tests/ --cov=src # With coverage
Code Quality
trunk check --all # Lint all files
trunk fmt # Format code
๐ Releases
Releases are automated via GitHub Actions:
git tag v1.0.x # Create version tag
git push origin v1.0.x # Trigger release pipeline
The pipeline automatically:
- โ Runs tests and quality checks
- โ Builds clean distribution packages
- โ
Publishes to PyPI as
stockholm-finance - โ Creates GitHub release with artifacts
- โ Builds and pushes Docker image
๐ค AI Assistant Context
For AI assistants working with this codebase:
Code Style & Quality
- Linter: Uses Trunk for code quality (Black + Ruff)
- Pre-commit hooks: Automatically run
trunk check --fixbefore commits - Style: Follow Black formatting, 88-character line limit
- Imports: Use isort for import organization
Project Structure
src/
โโโ core/ # Financial analysis engines
โ โโโ financial_analyzer.py # Main entry point & orchestration
โ โโโ sentiment_analyzer.py # NLP-based market sentiment analysis
โ โโโ policy_analyzer.py # Government policy impact analysis
โ โโโ earnings_fetcher.py # Quarterly earnings data fetching
โโโ data/ # Data fetching and caching
โ โโโ data_fetcher.py # Multi-source data aggregation
โ โโโ cached_data_fetcher.py# Cached API wrappers
โ โโโ cache_manager.py # Smart TTL cache management
โโโ ui/ # Textual dashboard interface
โ โโโ textual_dashboard.py # Interactive TUI dashboard
โ โโโ display_utils.py # Terminal output utilities
โโโ config/ # Configuration management
โโโ config.py # Application configuration
Key Technologies
- UI Framework: Textual for terminal interface
- Charts:
textual_plotextfor interactive terminal plots - Data:
yfinancefor market data,feedparserfor news - NLP:
textblobfor sentiment analysis - Caching: Custom TTL-based file caching system
Core Systems
Performance Optimization System
Stockholm includes advanced performance optimizations for instant startup and responsive user experience.
๐ฅ Hot Loading Architecture:
# Progressive data loading phases
LOADING_PHASES = {
'critical': ['prices', 'basic_market_data'], # Load first (2-3s)
'secondary': ['news', 'government_data'], # Load second (5-8s)
'analysis': ['sentiment', 'policy_analysis'], # Complete analysis (10-15s)
}
# Background data fetching
class BackgroundDataFetcher:
def start_background_fetching(self):
# Continuous cache warming while dashboard runs
# Updates UI components as fresh data arrives
# Reduces perceived startup time by 70%
โก Startup Performance Comparison:
- Cold Start (empty cache): ~25-30 seconds
- Warm Start (pre-warmed cache): ~8-12 seconds
- Hot Loading (progressive): ~2-3 seconds to UI, data loads in background
๐ Performance Features:
- Immediate UI Display: Dashboard appears in 2-3 seconds
- Progressive Data Loading: Critical data first, analysis second
- Background Cache Warming: Continuous data ingestion while running
- Smart Cache Pre-warming:
--warm-cacheflag for fastest startup
Intelligent Caching System
The caching system is the performance backbone of Stockholm, achieving 85% API call reduction.
Architecture:
# TTL Configuration (in minutes)
CACHE_TTL = {
'news': 15, # Financial news updates
'prices': 5, # Real-time stock prices
'company_names': 1440, # Company metadata (24 hours)
'market_data': 10, # Market indices
'policy_news': 30, # Government announcements
'analyst_data': 60, # Analyst recommendations
'earnings': 1440, # Quarterly earnings data
}
Cache Key Generation:
- Uses MD5 hashes of request parameters
- Format:
{data_type}_{hash}.cache - Example:
prices_a1b2c3d4.cachefor AAPL price data
Performance Metrics:
- Cold cache: ~81 API calls for full dashboard
- Warm cache: ~40 API calls (51% reduction)
- Hot cache: ~25 API calls (69% reduction)
- Cache hit rate: 70%+ on subsequent runs
Cache Management:
# Monitor cache performance
python tools/cache_monitor.py --stats
# Clear specific cache types
python tools/cache_monitor.py --clear news
# Emergency cache clear
python tools/clear_all_cache.py
Implementation Details:
- File-based storage in
cache/directory - Atomic writes to prevent corruption
- Request tracking in
request_log.json - Automatic cleanup of expired entries
- Thread-safe operations for concurrent access
Sentiment Analysis Engine
Advanced NLP system for market sentiment analysis with multi-ticker support.
Core Algorithm:
def analyze_sentiment_around_ticker(text, ticker):
"""Context-aware sentiment analysis around ticker mentions."""
# 1. Find ticker positions in text
# 2. Extract surrounding context (ยฑ50 words)
# 3. Apply TextBlob sentiment analysis
# 4. Weight by proximity to ticker mention
# 5. Return sentiment score (-1 to +1)
Multi-Ticker Detection:
- Regex patterns for ticker identification:
r'\b[A-Z]{1,5}\b' - Context validation against known ticker list
- Handles edge cases:
$AAPL,AAPL:,(AAPL) - Filters false positives (common words like "IT", "US")
Batch Processing:
- Processes 100+ articles in parallel
- Memory-efficient streaming for large datasets
- Error handling for malformed articles
- Progress tracking for long operations
Sector Classification:
SECTOR_MAPPING = {
'AAPL': 'Technology',
'MSFT': 'Technology',
'JPM': 'Financial Services',
'JNJ': 'Healthcare',
# ... 130+ tickers mapped
}
Conflict Detection:
- Identifies articles mentioning competing stocks
- Calculates sentiment divergence between tickers
- Flags potential market-moving conflicts
- Used for risk assessment and correlation analysis
Policy Analysis System
Government policy impact assessment with weighted sentiment analysis.
Data Sources:
- Federal Reserve RSS feeds (5 different categories)
- Treasury Department announcements
- SEC regulatory updates
- Congressional financial committee news
Impact Classification Algorithm:
POLICY_KEYWORDS = {
'high_impact': [
'interest rate', 'federal funds rate', 'monetary policy',
'quantitative easing', 'inflation target', 'recession',
'fomc', 'rate hike', 'rate cut', 'dovish', 'hawkish'
],
'medium_impact': [
'banking regulation', 'stress test', 'capital requirements',
'liquidity', 'financial stability', 'systemic risk'
],
'sector_specific': [
'energy policy', 'healthcare reform', 'tax policy',
'trade policy', 'infrastructure', 'climate policy'
]
}
def calculate_policy_impact(article):
"""Calculate policy impact score (0-5 scale)."""
# 1. Keyword matching with weights
# 2. Source credibility scoring
# 3. Recency factor (newer = higher impact)
# 4. Article length consideration
# 5. Return weighted impact score
Combined Analysis Formula:
final_sentiment = (market_sentiment * 0.7) + (policy_sentiment * 0.3)
Policy Categories:
- Monetary Policy: Fed decisions, interest rates, QE
- Regulatory: Banking rules, compliance, oversight
- Enforcement: Penalties, investigations, sanctions
- Economic: GDP, employment, inflation data
Interactive Dashboard
Professional terminal UI built with Textual framework.
Tab Architecture:
- Overview Tab: Market summary, top performers, sector analysis
- Tickers Tab: Interactive table with 130+ stocks, real-time data
- News Tab: Categorized news tree with sentiment visualization
- Policy Tab: Government policy analysis and impact assessment
Real-time Update System:
class DashboardApp(App):
def __init__(self):
self.refresh_timer = self.set_interval(300, self.refresh_data) # 5 min
async def refresh_data(self):
"""Background data refresh without blocking UI."""
# 1. Check cache validity
# 2. Fetch only expired data
# 3. Update UI components
# 4. Show progress indicators
Interactive Elements:
- Sortable Tables: Click column headers to sort by any metric
- Modal Dialogs: Detailed ticker information with charts
- Filter Controls: Dropdown menus for sector/sentiment filtering
- Progress Bars: Real-time feedback during data operations
- Status Bar: Connection status, last update time, cache stats
Keyboard Navigation:
BINDINGS = [
("q", "quit", "Quit"),
("r", "refresh", "Refresh Data"),
("f", "toggle_filter", "Toggle Filters"),
("1", "show_tab('overview')", "Overview Tab"),
("2", "show_tab('tickers')", "Tickers Tab"),
("3", "show_tab('news')", "News Tab"),
("4", "show_tab('policy')", "Policy Tab"),
("ctrl+e", "export_data", "Export Data"),
]
Color Coding System:
- Green: Positive sentiment (>0.1), price increases (>1%)
- Red: Negative sentiment (<-0.1), price decreases (<-1%)
- Yellow: Neutral sentiment (-0.1 to 0.1), minimal price change
- Blue: Policy-related content, high-impact news
- Gray: No data, loading states, disabled elements
Performance Optimizations:
- Lazy loading for large datasets
- Virtual scrolling for ticker tables
- Debounced user input handling
- Efficient re-rendering with dirty checking
- Background data fetching to prevent UI blocking
Data Flow Architecture
Request Processing Pipeline
graph TD
A[User Request] --> B[Cache Check]
B -->|Hit| C[Return Cached Data]
B -->|Miss| D[API Request Queue]
D --> E[Rate Limiting]
E --> F[External API Call]
F --> G[Data Validation]
G --> H[Cache Storage]
H --> I[Return Fresh Data]
C --> J[UI Update]
I --> J
API Integration Layer
Primary Data Sources:
DATA_SOURCES = {
'yfinance': {
'endpoints': ['info', 'history', 'news', 'recommendations'],
'rate_limit': '2000/hour',
'reliability': '95%',
'cache_strategy': 'aggressive'
},
'feedparser': {
'feeds': ['fed_press', 'fed_monetary', 'fed_speeches', 'fed_banking'],
'rate_limit': 'unlimited',
'reliability': '99%',
'cache_strategy': 'moderate'
},
'textblob': {
'type': 'local_processing',
'rate_limit': 'unlimited',
'cache_strategy': 'none'
}
}
Error Handling Strategy:
def robust_api_call(func, *args, **kwargs):
"""Robust API calling with exponential backoff."""
for attempt in range(3):
try:
return func(*args, **kwargs)
except (ConnectionError, Timeout) as e:
wait_time = 2 ** attempt # Exponential backoff
time.sleep(wait_time)
except RateLimitError:
time.sleep(60) # Wait 1 minute for rate limit reset
except Exception as e:
log_error(f"API call failed: {e}")
return None
return None # All retries failed
Data Validation Pipeline:
- Schema Validation: Ensure required fields exist
- Type Checking: Validate data types (float for prices, etc.)
- Range Validation: Check for reasonable values (prices > 0)
- Completeness Check: Verify minimum data requirements
- Sanitization: Clean text data, remove HTML tags
Concurrent Processing System
async def fetch_multiple_tickers(tickers):
"""Concurrent data fetching with controlled parallelism."""
semaphore = asyncio.Semaphore(10) # Max 10 concurrent requests
async def fetch_single(ticker):
async with semaphore:
return await cached_data_fetcher.get_ticker_data(ticker)
tasks = [fetch_single(ticker) for ticker in tickers]
results = await asyncio.gather(*tasks, return_exceptions=True)
return process_results(results)
Memory Management:
- Streaming processing for large datasets
- Garbage collection after batch operations
- Memory-mapped files for large cache entries
- Lazy loading of non-critical data
Development Workflow
CI/CD Pipeline Architecture
Trigger Mechanisms:
# Automatic triggers
on:
push:
branches: [main, develop]
tags: ['v*.*.*']
pull_request:
branches: [main]
# Manual triggers
workflow_dispatch:
inputs:
test_type: [quick, full, build-only, lint-only]
python_version: [3.8, 3.9, 3.10, 3.11, 3.12]
create_artifacts: boolean
Pipeline Stages:
- Code Quality: Trunk linting (Black + Ruff), pre-commit hooks
- Testing: pytest with coverage, matrix testing across Python versions
- Security: Dependency vulnerability scanning
- Build: Clean package building, content verification
- Release: PyPI publishing, Docker image, GitHub release
Release Process:
# Version bump
git tag v1.0.x -m "Release message"
git push origin v1.0.x
# Triggers automated pipeline:
# 1. Run full test suite
# 2. Build clean packages (excludes tests/, tools/, debug/)
# 3. Publish to PyPI as 'stockholm-finance'
# 4. Build multi-platform Docker image
# 5. Create GitHub release with artifacts
# 6. Send notifications
Testing Framework Architecture
Test Organization:
tests/
โโโ conftest.py # Shared fixtures and configuration
โโโ test_runner.py # Custom test runner with coverage
โโโ unit/
โ โโโ test_sentiment_analyzer.py # 12 tests, core NLP functionality
โ โโโ test_cache_simple.py # 12 tests, caching system
โ โโโ test_policy_analyzer.py # 13 tests, policy analysis
โโโ integration/
โ โโโ test_data_pipeline.py # End-to-end data flow
โ โโโ test_dashboard_integration.py # UI component integration
โโโ performance/
โโโ test_cache_performance.py # Cache hit rates, response times
โโโ test_batch_processing.py # Large dataset handling
Test Coverage Strategy:
- Unit Tests: 80%+ coverage for core components
- Integration Tests: Critical data flow paths
- Performance Tests: Cache efficiency, memory usage
- Regression Tests: Previous bug scenarios
Mock Strategy:
# External API mocking
@patch('yfinance.Ticker')
def test_with_mocked_yfinance(mock_ticker):
mock_ticker.return_value.info = {'symbol': 'AAPL', 'price': 150.0}
# Cache mocking for isolated testing
@patch('src.data.cache_manager.CacheManager')
def test_without_cache(mock_cache):
mock_cache.get.return_value = None # Force cache miss
Dependency Management
Package Configuration:
- requirements.txt: Production dependencies only
- pyproject.toml: Complete package metadata and dev dependencies
- setup.py: Fallback configuration for older pip versions
Dependency Categories:
DEPENDENCIES = {
'core': ['textblob', 'yfinance', 'requests', 'numpy'],
'ui': ['textual', 'rich', 'textual_plotext'],
'data': ['feedparser', 'python-dateutil', 'pytz'],
'dev': ['pytest', 'pytest-cov', 'black', 'ruff'],
'build': ['build', 'twine', 'wheel']
}
Version Pinning Strategy:
- Major versions pinned: Prevent breaking changes
- Minor versions flexible: Allow bug fixes and features
- Security updates: Automated dependency updates via Dependabot
Package Details
- PyPI Name:
stockholm-finance(notstockholm- name conflict) - Entry Point: Single command
stockholm-finance(removedstockholm-dashboard) - Python Support: 3.8+ with matrix testing
- Docker: Multi-platform builds pushed to GitHub Container Registry
Testing Framework
- 37 tests total: All passing with zero failures
- Test modules:
test_sentiment_analyzer.py,test_cache_simple.py,test_policy_analyzer.py - Coverage: Cache manager (80%), Sentiment analyzer (39%)
- Test runner:
tests/test_runner.pywith coverage reporting - Fixtures: Shared test data in
conftest.py
Debugging and Troubleshooting
Common Issues and Solutions
Cache-Related Issues:
# Problem: Stale data showing in dashboard
# Solution: Clear specific cache type
python tools/cache_monitor.py --clear news
# Problem: High API usage despite caching
# Solution: Check cache hit rates
python tools/cache_monitor.py --stats
# Problem: Cache corruption errors
# Solution: Emergency cache clear
python tools/clear_all_cache.py
API Integration Issues:
# Problem: yfinance connection errors
# Debug: Test specific ticker
python tools/debug/debug_yfinance.py AAPL
# Problem: Rate limiting errors
# Debug: Check request patterns
python tools/cache_monitor.py --estimate
# Problem: Data validation failures
# Debug: Inspect raw API responses
python tools/debug/debug_time.py
Dashboard Issues:
# Problem: UI rendering problems
# Solution: Check terminal compatibility
python -c "import textual; print('Textual OK')"
# Problem: Slow dashboard performance
# Debug: Profile data loading
python main.py --verbose
# Problem: Keyboard shortcuts not working
# Solution: Check terminal focus and key bindings
Debug Tools and Scripts
Cache Monitoring:
tools/cache_monitor.py --stats # Performance statistics
tools/cache_monitor.py --estimate # API savings estimation
tools/cache_monitor.py --clear # Interactive cache clearing
API Debugging:
tools/debug/debug_yfinance.py # Deep yfinance API testing
tools/debug/debug_time.py # Time-related debugging
tools/debug/investigate_dominion_loss.py # Specific ticker investigation
Performance Analysis:
tools/debug/explain_earnings_trends.py # Earnings data analysis
python main.py --verbose # Detailed execution logging
python -m cProfile main.py # Performance profiling
Logging and Monitoring
Log Levels:
LOGGING_CONFIG = {
'DEBUG': 'Detailed execution flow, cache operations',
'INFO': 'Normal operations, API calls, user actions',
'WARNING': 'Recoverable errors, rate limiting, stale data',
'ERROR': 'API failures, data corruption, critical errors',
'CRITICAL': 'System failures, unrecoverable errors'
}
Performance Metrics:
- API Call Tracking: Request counts, response times, error rates
- Cache Performance: Hit/miss ratios, storage usage, cleanup frequency
- Memory Usage: Peak memory, garbage collection frequency
- UI Responsiveness: Render times, user interaction latency
Error Recovery Strategies
Graceful Degradation:
def fetch_with_fallback(ticker):
"""Fetch data with multiple fallback strategies."""
try:
return primary_data_source(ticker)
except APIError:
try:
return cached_data_source(ticker)
except CacheError:
return minimal_data_fallback(ticker)
Data Consistency Checks:
def validate_ticker_data(data):
"""Comprehensive data validation."""
checks = [
('price', lambda x: x > 0, 'Price must be positive'),
('volume', lambda x: x >= 0, 'Volume cannot be negative'),
('timestamp', lambda x: x < time.time(), 'Timestamp cannot be future'),
]
for field, validator, message in checks:
if not validator(data.get(field)):
raise ValidationError(f"{field}: {message}")
Important Notes
- Always use package managers (pip, not manual edits) for dependencies
- Pre-commit hooks will auto-fix most linting issues
- Release workflow only publishes to PyPI for non-draft, non-prerelease versions
- Dashboard is primary interface - no separate CLI analyzer
- Cache system is critical - don't bypass it, use cached_data_fetcher.py
- All external API calls should go through cached_data_fetcher.py
- UI components use Textual framework - follow their patterns
- Error handling should be graceful with fallback strategies
- Performance monitoring is built-in - use the debug tools
- Data validation is mandatory for all external data sources
๐ License
MIT License - see LICENSE file for details.
Built with โค๏ธ for financial analysis
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file stockholm_finance-1.1.12.tar.gz.
File metadata
- Download URL: stockholm_finance-1.1.12.tar.gz
- Upload date:
- Size: 87.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0ec6e5722e342eeb8c6af23b95f2e6af81bb49cdfb6c52a1b00cebb0f3c05f4c
|
|
| MD5 |
b5865413589acb1e413a245790122505
|
|
| BLAKE2b-256 |
3da2e60e1dc8ea2f748e41e52dcbb280df62bebef4d2eb383471f8130d7536f4
|
Provenance
The following attestation bundles were made for stockholm_finance-1.1.12.tar.gz:
Publisher:
release.yml on aykaym/stockholm
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
stockholm_finance-1.1.12.tar.gz -
Subject digest:
0ec6e5722e342eeb8c6af23b95f2e6af81bb49cdfb6c52a1b00cebb0f3c05f4c - Sigstore transparency entry: 244430269
- Sigstore integration time:
-
Permalink:
aykaym/stockholm@6637a2e512d79e33075910eea0f52eaf3bd215fa -
Branch / Tag:
refs/tags/v1.1.12 - Owner: https://github.com/aykaym
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@6637a2e512d79e33075910eea0f52eaf3bd215fa -
Trigger Event:
push
-
Statement type:
File details
Details for the file stockholm_finance-1.1.12-py3-none-any.whl.
File metadata
- Download URL: stockholm_finance-1.1.12-py3-none-any.whl
- Upload date:
- Size: 94.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
48350a12f62bfae15fee5b663784e4811aa52c3973dd326d90bea4c7a5f63f9c
|
|
| MD5 |
e2a48692b253e0e18d24dc5cabce32f9
|
|
| BLAKE2b-256 |
a940979c4703aea775c27e201ea55bad4879aaa4e69e1f1a04f29a03ff895309
|
Provenance
The following attestation bundles were made for stockholm_finance-1.1.12-py3-none-any.whl:
Publisher:
release.yml on aykaym/stockholm
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
stockholm_finance-1.1.12-py3-none-any.whl -
Subject digest:
48350a12f62bfae15fee5b663784e4811aa52c3973dd326d90bea4c7a5f63f9c - Sigstore transparency entry: 244430272
- Sigstore integration time:
-
Permalink:
aykaym/stockholm@6637a2e512d79e33075910eea0f52eaf3bd215fa -
Branch / Tag:
refs/tags/v1.1.12 - Owner: https://github.com/aykaym
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@6637a2e512d79e33075910eea0f52eaf3bd215fa -
Trigger Event:
push
-
Statement type: