EEYF - Eric Evans' Yahoo Finance API
A rate-limited, reliable Rust adapter for the Yahoo Finance API designed for enterprise use.
⚠️ IMPORTANT: This library implements proper rate limiting to respect Yahoo Finance's API limits and prevent your IP from being blocked. Unlike other libraries, EEYF includes built-in protection against API abuse.
Key Features
- 🛡️ Built-in Rate Limiting - Prevents API abuse and IP blocking
- 🔄 Automatic Retry Logic - Handles transient failures gracefully
- 📊 Request Monitoring - Track your API usage in real-time
- 🏢 Enterprise Ready - Reliable for production workloads
- 🚀 Drop-in Replacement - Compatible with existing
yahoo_finance_apicode
Background and Thanks
This project started out as a fork of the yahoo! finance API crate. I would like to formally thank Mark Beinker and all of the many contributors to that crate as this crate wouldn't have been possible without their hard work as its base. On that note, if any of the maintainers of that crate would like to copy any/all code from this crate back to that one, feel free! I only split it so I could work without needing approval to push changes. I hope you approve of the ones I make.
I would also like to thank Yahoo! as without them we wouldn't have their wonderful Yahoo! Finance website that this crate retrieves data from.
License
This project is licensed under Apache 2.0 or MIT license (see files LICENSE-Apache2.0 and LICENSE-MIT).
📚 Documentation
- Quick Start - Get up and running in 5 minutes
- ROADMAP.md - Full feature roadmap and development plan
- GETTING_STARTED.md - Contributor guide for implementing roadmap items
- FFI Guide - Create language bindings for Python, Node.js, Go, Ruby, etc.
- Architecture Change - Language bindings transition to separate repos
- BLOCKING_REMOVAL.md - Recent changes and migration guide
🌍 Language Bindings
EEYF provides a comprehensive FFI (Foreign Function Interface) layer for creating language bindings. Language bindings are maintained in separate repositories for better ecosystem integration:
Creating Bindings
See docs/FFI_GUIDE.md for complete instructions on creating bindings for any language. The guide includes:
- Complete FFI layer design and implementation
- Reference implementations for Python, Node.js, Go, and Ruby
- Memory management and error handling patterns
- Distribution strategies and best practices
- CI/CD pipeline setup
Official Binding Repositories (Community-Maintained)
Community members can create and maintain language bindings. High-quality bindings that follow the FFI guide will be listed here:
- Python (
eeyf-python): Coming soon - PyPI package with ctypes/cffi bindings - Node.js (
eeyf-node): Coming soon - npm package with TypeScript support - Go (
eeyf-go): Coming soon - Go modules with CGO bindings - Ruby (
eeyf-ruby): Coming soon - RubyGems with FFI gem
Want to create a binding? Follow the FFI Integration Guide and open an issue to have your repository listed here.
Why Separate Repositories?
Language bindings are maintained separately to:
- ✅ Enable proper publishing to language package managers (PyPI, npm, crates.io, etc.)
- ✅ Follow language-specific best practices and conventions
- ✅ Allow independent versioning and release cycles
- ✅ Simplify contribution (no Rust knowledge required for binding improvements)
- ✅ Provide language-specific documentation and examples
This follows the proven patterns used by major projects like SQLite, protobuf, and tree-sitter.
⚠️ Module Status
Core Features (Fully Operational)
All core Yahoo Finance API functionality is 100% operational and production-ready:
- ✅ Historical data fetching
- ✅ Real-time quote streaming
- ✅ Options data retrieval
- ✅ Company information and financial statements
- ✅ Market hours checking
- ✅ Screener functionality
- ✅ Search capabilities (ticker, news, trending)
- ✅ Rate limiting and retry logic
- ✅ Circuit breaker pattern
- ✅ Response caching
- ✅ Data export (CSV, JSON)
Experimental Modules (Temporarily Disabled)
Three advanced data processing modules are temporarily disabled in v0.1.0 pending refactoring:
- ⚠️
timeseries- Time series utilities (resampling, timezone handling) - ⚠️
transform- Data transformation (OHLC aggregation, technical indicators) - ⚠️
validate- Data validation (integrity checks, anomaly detection)
Status: These modules are under refactoring to work with both f64 and rust_decimal::Decimal types.
Workaround: To use these features now, enable the decimal feature:
[]
= { = "0.1", = ["decimal"] }
Timeline: These modules will be re-enabled in v0.1.1 or v0.2.0 after refactoring is complete.
See CHANGELOG.md for detailed information about changes between versions.
Quick Start
Recommended Usage (with Rate Limiting)
For production use, always enable rate limiting to prevent API violations:
use YahooConnector;
use tokio_test;
Custom Rate Limiting Configuration
use ;
use Duration;
Basic Usage
All request functions return async futures and are designed for modern async/await workflows. They need to be called from within an async function with .await or via functions like block_on. All examples use the tokio runtime and tests use the tokio-test crate.
Get the Most Recent Quote
use eeyf as yahoo;
use OffsetDateTime;
use tokio_test;
Get Quotes from a Time Period
use eeyf as yahoo;
use ;
use tokio_test;
Another method to retrieve a range of quotes is by requesting the quotes for a given period and lookup frequency. Here is an example retrieving the daily quotes for the last month:
use eeyf as yahoo;
use tokio_test;
Note: See the Time Period Labels and Valid Parameter Combinations sections for what can and can't be used in the above code
Search Tickers for a String (e.g. company name)
use eeyf as yahoo;
use tokio_test;
Some fields like longname are optional and will be replaced by default values if missing (e.g. empty string). If you do not like this behavior, use search_ticker_opt instead which contains Option<String> fields, returning None if the field found missing in the response.
Rate Limiting Features
Monitoring Rate Limits
if let Some = provider.rate_limit_status
Why Rate Limiting Matters
Yahoo Finance has API limits that unprotected libraries don't respect:
- ~2000 requests per hour per IP
- Burst limits of ~10-20 requests per minute
- Stricter limits during market hours
- IP blocking for violations
Without rate limiting, you risk:
- Getting your IP temporarily or permanently blocked
- Service disruptions during critical market periods
- Inconsistent data availability
- Potential legal issues from API abuse
Default Rate Limit Settings
EEYF uses conservative defaults (90% of Yahoo's limits):
- 1800 requests per hour (leaves 200 request buffer)
- 10 burst requests (allows small batches)
- 100ms minimum interval (prevents rapid-fire requests)
These settings are safe for production use while maximizing throughput.
Migration from yahoo_finance_api
EEYF is designed as a drop-in replacement. Simply change your dependency:
# Before
# yahoo_finance_api = "4.1.0"
# After
= "0.1.0"
Then update your imports and add rate limiting:
// Before (UNSAFE - no rate limiting)
use yahoo_finance_api as yahoo;
let provider = new.unwrap;
// After (SAFE - with protection)
use eeyf as yahoo; // Drop-in replacement
let provider = with_rate_limiting.unwrap;
Advanced Features
Bulk Requests with Automatic Pacing
let symbols = vec!;
for symbol in symbols
Error Handling
EEYF provides detailed error information:
match provider.get_latest_quotes.await
Best Practices
- Always use rate limiting in production
- Monitor your usage with
rate_limit_status() - Handle rate limit errors gracefully
- Use conservative limits for critical applications
- Implement exponential backoff for retries
- Cache responses when appropriate to reduce API calls
Time Period Labels
Time periods are given as strings, combined from the number of periods (except for "ytd" and "max") and a string label specifying a single period. The following period labels are supported:
| label | description |
|---|---|
| m | minute |
| h | hour |
| d | day |
| wk | week |
| mo | month |
| y | year |
| ytd | year-to-date |
| max | maximum |
Valid Parameter Combinations
| range | interval |
|---|---|
| 1d | 1m, 2m, 5m, 15m, 30m, 90m, 1h, 1d, 5d, 1wk, 1mo, 3mo |
| 1mo | 2m, 3m, 5m, 15m, 30m, 90m, 1h, 1d, 5d, 1wk, 1mo, 3mo |
| 3mo | 1h, 1d, 1wk, 1mo, 3mo |
| 6mo | 1h, 1d, 1wk, 1mo, 3mo |
| 1y | 1h, 1d, 1wk, 1mo, 3mo |
| 2y | 1h, 1d, 1wk, 1mo, 3mo |
| 5y | 1d, 1wk, 1mo, 3mo |
| 10y | 1d, 1wk, 1mo, 3mo |
| ytd | 1m, 2m, 5m, 15m, 30m, 90m, 1h, 1d, 5d, 1wk, 1mo, 3mo |
| max | 1m, 2m, 5m, 15m, 30m, 90m, 1h, 1d, 5d, 1wk, 1mo, 3mo |