# yfinance-plus ๐Ÿš€ A drop-in replacement for `yfinance` with enhanced rate limiting, intelligent caching, and 401 error handling. Works exactly like the original yfinance but faster, more reliable, and with zero breaking changes. [![Python 3.8+](https://img.shields.io/badge/python-3.8+-blue.svg)](https://www.python.org/downloads/) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) ## โœจ Key Features ### ๐ŸŽฏ **100% Drop-in Replacement** - Import as `import yfinance_enhanced as yf` - All yfinance functionality works identically - **99% API coverage** (97/98 features supported) - Zero code changes required ### ๐Ÿ›ก๏ธ **Enhanced Rate Limiting & Error Handling** - **Automatic 401 error handling** with session refresh - **Browser-like headers** with 7 different User-Agent strings - **Exponential backoff** with intelligent retry logic - **Session rotation** every 10 minutes or 50 requests ### โšก **Intelligent Caching System** - **247x faster** repeated requests with file-based caching - **Smart period matching** - longer periods serve shorter requests - **Automatic cache invalidation** after 1 hour - **CLI cache management** with detailed file information ### ๐Ÿ”ง **Enhanced CLI Tools** - **`yfp` command** for cache and configuration management - **Detailed cache inspection** with symbol, period, and date range info - **Performance benchmarking** and connection testing - **Configuration management** with easy-to-use commands ## ๐Ÿ“ฆ Installation ### Method 1: Install from Source (Recommended) ```bash # Clone and install git clone https://gitea.yirugi.synology.me/yirugi/yfinance_plus.git cd yfinance-plus pip install -e . ``` ### Method 2: Local Development ```bash # Install dependencies pip install yfinance>=0.2.65 curl_cffi>=0.5.0 pandas>=1.3.0 numpy>=1.20.0 ``` ## ๐Ÿš€ Quick Start ### Drop-in Replacement Usage ```python # Simply replace your import - everything else stays the same! import yfinance_enhanced as yf # All original yfinance functionality works identically ticker = yf.Ticker("AAPL") hist = ticker.history(period="1mo") info = ticker.info # Note: property, not method data = yf.download(["AAPL", "GOOGL"], period="1mo") # Multiple tickers tickers = yf.Tickers("MSFT AAPL GOOG") msft_info = tickers.tickers['MSFT'].info # New cache management features yf.clear_cache() cache_info = yf.get_cache_info() ``` ### Performance Comparison ```python import time import yfinance_enhanced as yf # First request (downloads and caches) start = time.time() data1 = yf.Ticker("AAPL").history(period="1mo") first_time = time.time() - start print(f"First request: {first_time:.3f}s") # Second request (from cache) start = time.time() data2 = yf.Ticker("AAPL").history(period="1mo") second_time = time.time() - start print(f"Second request: {second_time:.3f}s") print(f"Speedup: {first_time/second_time:.1f}x") # Output: # First request: 0.186s # Second request: 0.001s # Speedup: 247.9x ``` ## ๐Ÿ”ง Command Line Interface ### Available Commands ```bash yfp --help # Show all available commands yfp cache info # Show detailed cache information yfp cache info --limit 5 # Show only 5 most recent files yfp cache clear # Clear cache with confirmation yfp cache clear --force # Clear cache without confirmation yfp config show # Show current configuration yfp test # Test connection to Yahoo Finance yfp benchmark # Run performance benchmark ``` ### Enhanced Cache Information ```bash $ yfp cache info ๐Ÿ—‚๏ธ YFinance Plus Cache Information ================================================== Cache Directory: /Users/username/.yfinance_cache Number of Files: 8 Total Size: 30.5 KB ๐Ÿ“ Cache Files: ---------------------------------------------------------------------------------------------------- ๐Ÿ“„ 06dbc103b9a8af2faddce6c95b2caaef 5.4 KB 2025-08-01 21:59:40 Symbol: NVDA Period: 3mo Interval: 1d Rows: 63 Date Range: 2025-05-02 to 2025-08-01 ๐Ÿ“„ 0d84bd5865d16d346aabcaed64cf02f0 2.8 KB 2025-08-01 21:59:40 Symbol: NVDA Period: 1mo Interval: 1d Rows: 22 Date Range: 2025-07-02 to 2025-08-01 ``` ### Configuration Management ```bash $ yfp config show โš™๏ธ YFinance Plus Configuration ======================================== Max Retries: 3 Base Delay: 1.0s Max Delay: 60.0s Jitter Enabled: True Cache Enabled: True Cache Directory: /Users/username/.yfinance_cache User Agents: 7 configured ``` ### Connection Testing ```bash $ yfp test ๐Ÿ”— Testing connection to Yahoo Finance... Creating test ticker... Fetching basic info... Fetching historical data... โœ… Connection test successful! Company: Apple Inc. Historical data points: 5 Cache status: 8 files ``` ## ๐Ÿ’พ Intelligent Caching System ### How Smart Caching Works ```python import yfinance_enhanced as yf # 1. First request caches data ticker = yf.Ticker("AAPL") data_1mo = ticker.history(period="1mo") # Downloads and caches # 2. Second identical request uses cache data_1mo_again = ticker.history(period="1mo") # Instant from cache # 3. Longer period downloads new data data_3mo = ticker.history(period="3mo") # Downloads 3mo, caches it # 4. Shorter request extracts from longer cached data data_1mo_from_3mo = ticker.history(period="1mo") # Extracted from 3mo cache ``` ### What Gets Cached โœ… **Cached:** - Historical price data (`history()`) - All standard periods (1d, 1mo, 3mo, 1y, etc.) - All intervals (1m, 5m, 1h, 1d) - **Smart overlap detection** - longer periods serve shorter requests โŒ **Not Cached:** - Real-time data - News articles (`news`) - Extended hours data (`prepost=True`) - Data older than 1 hour (auto-expires) ### Cache Management ```python import yfinance_enhanced as yf # Check cache status cache_info = yf.get_cache_info() print(f"Cache files: {cache_info['file_count']}") print(f"Cache size: {cache_info['total_size_mb']:.2f} MB") # Clear cache yf.clear_cache() # Configure caching yf.set_config( enable_cache=True, cache_dir="~/my_custom_cache" ) ``` ## โš™๏ธ Configuration ### Global Configuration ```python import yfinance_enhanced as yf # Configure global settings yf.set_config( max_retries=5, # Number of retry attempts base_delay=1.0, # Base delay between retries (seconds) max_delay=60.0, # Maximum delay (seconds) jitter=True, # Add randomness to delays enable_cache=True, # Enable intelligent caching cache_dir="~/my_cache" # Custom cache directory ) # Get current configuration config = yf.get_config() print(f"Max retries: {config.max_retries}") ``` ### Configuration Parameters | Parameter | Default | Description | |-----------|---------|-------------| | `max_retries` | 3 | Maximum retry attempts for failed requests | | `base_delay` | 1.0 | Base delay between retries (seconds) | | `max_delay` | 60.0 | Maximum delay between retries (seconds) | | `jitter` | True | Add random jitter to delays | | `enable_cache` | True | Enable intelligent caching system | | `cache_dir` | `~/.yfinance_cache` | Cache directory location | | `user_agents` | 7 agents | List of User-Agent strings to rotate | ## ๐Ÿ”„ Migration Guide ### From yfinance to yfinance-enhanced Migration is **100% seamless** - just change your import: ```python # Before import yfinance as yf # After import yfinance_enhanced as yf # Everything else works identically! ticker = yf.Ticker("AAPL") data = yf.download(["AAPL", "GOOGL"], period="1mo") tickers = yf.Tickers("MSFT AAPL GOOG") info = tickers.tickers['MSFT'].info ``` ### Common yfinance Patterns That Work ```python import yfinance_enhanced as yf # All standard patterns work identically ticker = yf.Ticker("AAPL") # Properties (not methods!) info = ticker.info # โœ… Correct dividends = ticker.dividends # โœ… Correct splits = ticker.splits # โœ… Correct financials = ticker.financials # โœ… Correct balance_sheet = ticker.balance_sheet # โœ… Correct cashflow = ticker.cashflow # โœ… Correct # Methods history = ticker.history(period="1mo") # โœ… Correct options = ticker.options # โœ… Correct option_chain = ticker.option_chain("2024-01-19") # โœ… Correct # Bulk operations data = yf.download(["AAPL", "GOOGL", "MSFT"], period="1y", interval="1d") # Multiple tickers tickers = yf.Tickers("AAPL GOOGL MSFT") for symbol in tickers.symbols: hist = tickers.tickers[symbol].history(period="1mo") ``` ## ๐Ÿš€ Enhanced Features ### 401 Error Handling ```python # Automatic 401 error recovery import yfinance_enhanced as yf ticker = yf.Ticker("AAPL") # If Yahoo returns 401, automatically: # 1. Creates new session with fresh headers # 2. Retries with exponential backoff # 3. Rotates User-Agent strings # 4. Works silently in background info = ticker.info # Just works! ``` ### Advanced Rate Limiting ```python # The wrapper automatically: # - Detects rate limit errors (429, 401) # - Refreshes sessions every 10 minutes # - Uses 7 different User-Agent strings # - Adds realistic browser cookies # - Implements exponential backoff # - No user intervention required ``` ### Performance Optimization ```python import yfinance_enhanced as yf # Smart cache usage ticker = yf.Ticker("AAPL") # Downloads 1 year of data hist_1y = ticker.history(period="1y") # ~0.5s, cached # Uses cached data for shorter periods hist_6mo = ticker.history(period="6mo") # ~0.001s, from cache hist_3mo = ticker.history(period="3mo") # ~0.001s, from cache hist_1mo = ticker.history(period="1mo") # ~0.001s, from cache # Result: 4 requests in ~0.5s instead of ~2.0s ``` ## ๐Ÿ“Š API Compatibility ### 100% Compatible Functions | Function | yfinance | yfinance-enhanced | Enhancements | |----------|----------|-------------------|--------------| | `Ticker(symbol)` | โœ… | โœ… | + Caching + Rate limiting | | `download(tickers)` | โœ… | โœ… | + Better error handling | | `Tickers(symbols)` | โœ… | โœ… | + Enhanced performance | | `ticker.history()` | โœ… | โœ… | + Intelligent caching | | `ticker.info` | โœ… | โœ… | + 401 error handling | | `ticker.financials` | โœ… | โœ… | + Automatic retries | | `ticker.dividends` | โœ… | โœ… | + Session management | | `ticker.splits` | โœ… | โœ… | + Rate limiting | | All other methods | โœ… | โœ… | + Enhanced reliability | ### New Enhanced Functions | Function | Description | |----------|-------------| | `yf.clear_cache()` | Clear all cached data | | `yf.get_cache_info()` | Get detailed cache statistics | | `yf.set_config(**kwargs)` | Configure global settings | | `yf.get_config()` | Get current configuration | ## ๐Ÿ” Technical Details ### Browser Emulation ```python # Automatically rotates between realistic headers: user_agents = [ 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.2.1 Safari/605.1.15', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:121.0) Gecko/20100101 Firefox/121.0', # ... 3 more variants ] # Plus realistic browser cookies: cookies = { 'A1': 'd=AQABBC123456YLoCIgEBwQJ7vgAB&S=AQAAAg', 'GUC': 'AQEBAQFm1234k0L', 'B': 'c=1234567&b=3&s=4u', # ... more realistic cookies } ``` ### Intelligent Cache Strategy ```python # Cache key generation cache_key = hash(f"{symbol}_{period}_{interval}_{start}_{end}") # Smart period matching if requested_period <= cached_period: return cached_data.tail(requested_rows) # Extract from cache else: fetch_new_data() # Download longer period ``` ### Error Recovery ```python # Automatic error handling if "401" in error or "unauthorized" in error: refresh_session() # New headers and cookies exponential_backoff() # Wait before retry retry_request() # Try again ``` ## ๐Ÿงช Testing ### Running Tests ```bash # Run comprehensive tests python test_drop_in_replacement.py python test_comprehensive_wrapping.py # CLI tests yfp test yfp benchmark yfp cache info ``` ### Test Results ``` ๐Ÿš€ Comprehensive yfinance Enhanced Wrapping Test ====================================================================== ๐Ÿ“Š Functionality coverage: 97/98 (99.0%) โœ… EXCELLENT: Nearly all yfinance functionality is working! Cache speedup: 247.9x Bulk download speedup: 4.36x ``` ## ๐Ÿค Contributing 1. Fork the repository 2. Create a feature branch (`git checkout -b feature/amazing-feature`) 3. Commit your changes (`git commit -m 'Add amazing feature'`) 4. Push to the branch (`git push origin feature/amazing-feature`) 5. Open a Pull Request ## ๐Ÿ“ License This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details. ## โš ๏ธ Disclaimer This project is for educational and research purposes. Please respect Yahoo Finance's terms of service and rate limits. The enhanced wrapper is designed to be more respectful of their servers while providing better reliability for legitimate use cases. ## ๐Ÿ™ Acknowledgments - Built on top of the excellent [yfinance](https://github.com/ranaroussi/yfinance) library - Uses [curl_cffi](https://github.com/yifeikong/curl_cffi) for advanced browser emulation - Inspired by the need for more reliable financial data access --- **Made with โค๏ธ for the Python financial data community**