Software Library — Financial Data

xFinance

Reliable financial data with automatic failover

A Python financial data library that delivers yfinance's simplicity with better reliability. Automatic multi-source failover—when Yahoo Finance is rate-limited or unavailable, data transparently falls back to Stooq, SEC, ECB, Binance, or CoinGecko. No code changes. No API keys needed.

Data Sources
6
Circuit Breaker
Per-source
Caching
5 min TTL
Concurrent
50× faster
01 — Problem

The yfinance
Problem

yfinance relies on a single source: Yahoo Finance. When Yahoo hits its ~950 request per session limit, or when Yahoo's API breaks (which happens frequently), users get rate limit errors or empty DataFrames with no fallback.

xFinance solves this with automatic multi-source failover. If Yahoo is throttled, data silently falls back to Stooq. If that fails, it tries SEC, ECB, Binance, CoinGecko. Same API. Same data structure. No code changes.

Single Point of Failure
1 source
yfinance only tries Yahoo
Automatic Failover
6 sources
xFinance tries 6 in sequence
Rate Limit Crashes
✗ Fixed
Circuit breaker + retry logic
02 — Design

Data Source
Router

xFinance implements a pluggable DataSourceRouter that tries sources in priority order. Each source is wrapped in a circuit breaker: after 5 consecutive failures, that source is "open" for 60 seconds. Further requests skip it without wasting HTTP calls. Transient errors trigger exponential backoff with up to 4 retries.

01 ——
Circuit Breaker
Per-source, 5 failure threshold, 60s cooldown. Prevents cascading failures.
02 ——
Automatic Retry
Exponential backoff. Catches 50x errors, timeouts, rate limits.
03 ——
Caching
Per-instance in-memory, 5-minute TTL. Eliminates redundant network calls.
03 — Sources

Six Data
Providers

xFinance queries sources in priority order. Each supports a different mix of data types. Yahoo Finance covers everything (but is rate-limited). Stooq covers equities and forex cheaply. SEC provides audited fundamentals. ECB covers forex. Binance and CoinGecko cover crypto.

Source Priority & Coverage Try order: Yahoo → Stooq → SEC → ECB → Binance → CoinGecko

Yahoo Finance: Prices, Info, Forex, Crypto, Fundamentals, Options
Stooq: Prices, Forex (cheap & fast)
SEC EDGAR: Company Info, Fundamentals (audited 10-K/10-Q)
ECB Frankfurter: Forex data (no rate limits)
Binance: Prices, Info, Crypto (fast, reliable)
CoinGecko: Prices, Info, Crypto (free tier: 30 req/min)
04 — Usage

yfinance
Compatible

Use xFinance exactly like yfinance. Same method names. Same return types (pandas DataFrames). Same lazy evaluation and caching. Drop-in replacement: change import yfinance to import xfinance.

Single Ticker (Multi-Source Failover, Cached) import xfinance as xf

t = xf.Ticker("AAPL")
df = t.history(period="1y")          # OHLCV DataFrame
info = t.info                                 # Company metadata
income = t.income_stmt                         # Financials
Concurrent Multi-Symbol Download (50× faster) df = xf.download(["AAPL", "MSFT", "GOOGL"], period="1y")
print(df["Close"])                            # All close prices
print(df[["AAPL", "MSFT"]])                   # Subset of symbols
05 — Benchmarks

Speed &
Reliability

Concurrent downloads are 50× faster than sequential. Circuit breaker and cache reduce API pressure. No API keys needed—all sources are public or free-tier.

Feature yfinance xFinance Benefit
Rate Limit Handling Crashes (SourceRateLimitError) Automatic fallback ✓ Works every time
Failover Sources None (1 source) 5 alternatives + plugin arch ✓ Resilient
Multi-Symbol Speed Sequential (~10s for 100 tickers) Concurrent (~0.2s for 100 tickers) ✓ 50× faster
Caching None Per-instance, 5-min TTL ✓ Instant repeats
API Keys Required No (unofficial) No (all public/free) ✓ Zero setup
Error Transparency Silent failures (empty DataFrame) Rich exceptions + source provenance ✓ Debuggable
06 — Example

Forex with
Automatic Failover

Without xFinance, if Yahoo hits rate limits, you get an error and no data. With xFinance, it silently falls back to Stooq, then ECB, until one succeeds. Same code. No retry logic needed.

Before (yfinance) — Crashes on Rate Limit import yfinance as yf

t = yf.Ticker("USD/EUR")
df = t.history(period="1y")          # ← SourceRateLimitError!
# You're blocked. No automatic fallback.
After (xFinance) — Automatic Failover import xfinance as xf

t = xf.Ticker("USD/EUR")
df = t.history(period="1y")          # ← Returns from Stooq or ECB if Yahoo is throttled
# Silent fallback. Works every time.
07 — Extensibility

Custom Data
Sources

Add your own data source with a simple plugin. Implement the DataSource protocol (<100 lines), register in pyproject.toml, and the router automatically discovers and uses it. No xFinance code changes needed.

Building a Custom Data Source Plugin from xfinance.sources.base import DataSource, PricesParams
from xfinance.models.source import DataSourceMeta, SupportedDataType

class MySource(DataSource):
    meta = DataSourceMeta(
        name="mysource",
        supported_types=[SupportedDataType.PRICES, SupportedDataType.INFO],
        rate_limit_per_minute=1000,
    )

    def supports(self, data_type, symbol):
        return data_type in self.meta.supported_types

    async def fetch_prices(self, params, *, client):
        # Your implementation
        pass
08 — Getting Started

Installation &
Terms

Install via pip. Requires Python 3.10+. Dependencies: httpx, pandas, pydantic, pybreaker, tenacity.

Installation pip install xfinance

No API keys needed. All sources are public or free-tier. Users are responsible for complying with each provider's Terms of Service: use yfinance-based data for personal research only; respect rate limits and fair-use guidelines. Full documentation and examples available at xfinance.readthedocs.io.