# yfinance-plus ๐Ÿš€ A drop-in replacement for `yfinance` with improved 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_plus 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_plus 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_plus 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_plus 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_plus 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_plus 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-plus Migration is **100% seamless** - just change your import: ```python # Before import yfinance as yf # After import yfinance_plus 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_plus 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_plus 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_plus 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-plus | 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 yfinance-plus 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**