v0.4.2 · PYTHON · FREE

Need financial data that is
simple?

80M+ prices. 75 years of fundamentals. 63,000 entities.

Read the docs →
quickstart.py
import xfinlink as xfl

prices       = xfl.prices("AAPL", start="2020-01-01")
fundamentals = xfl.fundamentals("AAPL", period_type="annual")
history      = xfl.resolve("AAPL")
EXPLORER

Explore the data.

Search any field. See real values.

USE CASES

What you can build.

v0.4.2 — DOCS

xfinlink documentation.

Three functions. Install, query, done. Everything you need to integrate xfinlink into a research pipeline, trading system, or weekend project.

Quick start

Install the package and make your first query in under a minute.

terminal
pip install xfinlink

Then in Python:

first_query.py
import xfinlink as xfl

prices = xfl.prices("AAPL", start="2020-01-01")
print(prices.head())

No API key. No rate limit to configure. Your queries are cached by default.

/v1/prices/{ticker}

Daily OHLCV prices with split adjustment. Coverage back to 1996 for every US-listed stock and ETF.

paramtypedefaultdescription
tickerstr | list[str]requiredTicker(s) to fetch.
startstr (ISO date)optionalEarliest date, inclusive.
endstr (ISO date)optionalLatest date, inclusive. Defaults to today.
fieldslist[str]optionalSubset of columns. Defaults to all 12 fields.
adjuststr"all"Adjustment mode: all, splits, or none.

Request:

request.py
df = xfl.prices("AAPL", start="2024-01-01", fields=["close", "volume"])

Response:

stdout
  date        ticker   close      volume
  2024-01-02  AAPL     185.64  45,123,456
  2024-01-03  AAPL     184.25  42,889,012
  2024-01-04  AAPL     181.91  49,301,234
  ...

/v1/fundamentals/{ticker}

Reported financials — income statement, balance sheet, cash flow — back to 1950 for most listed US companies.

paramtypedefaultdescription
tickerstr | list[str]requiredTicker(s) to fetch.
periodstr"annual""annual" | "quarterly"
fieldslist[str]optionalSubset of 65 available fields.
startstr (ISO date)optionalEarliest period_end.
endstr (ISO date)optionalLatest period_end.
request.py
df = xfl.fundamentals("AAPL", period_type="annual",
                  fields=["revenue", "net_income"])

/v1/resolve/{ticker}

Full entity history for a ticker. Every company that ever used this ticker, including bankruptcies, renames, and M&A events.

paramtypedefaultdescription
tickerstrrequiredTicker symbol to resolve.
as_ofstr (ISO date)optionalResolve as of a specific date.
includestroptionallineage, all_identifiers, events, related_entities
request.py
info = xfl.resolve("GM")
for entity in info["data"]["GM"]["entities"]:
    print(entity["name"], entity["ticker_valid_from"], entity["ticker_valid_to"])

Field reference

A curated list of the 92 fields across all three endpoints. See the Explorer on the home page for live values.

• /v1/fundamentals — 65 fields
revenuenet_incomeeps_basiceps_dilutedgross_profitoperating_incomeebitebitdatotal_assetstotal_liabilitiestotal_equitycash_and_equivalentslong_term_debtfree_cash_flowoperating_cash_flowcapexgross_marginoperating_marginnet_marginreturn_on_equityreturn_on_assets...
• /v1/prices — 12 fields
openhighlowcloseadjusted_closevolumevwapreturn_dailyreturn_weeklysplit_factordividendtrades
• /v1/resolve — 15 fields
nametickerticker_valid_fromticker_valid_tocikexchangecountrycurrencygics_sectorgics_industry_groupgics_industrygics_subindustrymarket_capeventsconstituents

Recipes

— P/E ratio for the S&P 500

pe_ratio.py
import xfinlink as xfl

tickers = xfl.resolve("^GSPC")["data"]["^GSPC"]["constituents"]
fund    = xfl.fundamentals(tickers, period_type="ttm", fields=["eps_diluted"])
prices  = xfl.prices(tickers, fields=["close"]).groupby("ticker").tail(1)
pe      = prices.merge(fund, on="ticker")
pe["pe"] = pe["close"] / pe["eps_diluted"]

— Screen: high-ROE software companies

screen_roe.py
tickers = xfl.universe(gics_subindustry="Systems Software")
df = xfl.fundamentals(tickers, period_type="ttm",
                      fields=["return_on_equity", "revenue"])
df = df[df["return_on_equity"] > 0.30].sort_values("revenue", ascending=False)

— Survivorship-bias-free backtest

backtest.py
# Universe = everyone who was in the S&P 500 on 2010-01-01,
# including companies that were later acquired or went bankrupt.
universe = xfl.constituents("^GSPC", as_of="2010-01-01")
prices   = xfl.prices(universe, start="2010-01-01", end="2025-01-01")
# Bankrupt tickers get NaN after delisting — handle explicitly.

Vibe coding

Paste this block into any LLM (Claude, ChatGPT, Cursor) as context. It teaches the model exactly what xfinlink can and can't do, so the code it writes actually runs.

context.md
# xfinlink — LLM context block

xfinlink is a free Python library for financial data.
Install: pip install xfinlink
Import:  import xfinlink as xfl

Three functions:

  xfl.prices(ticker, start=None, end=None, fields=None)
    → pandas.DataFrame of daily OHLCV + derived fields
    → fields: open, high, low, close, volume, return_daily,
              vwap, split_factor, dividend, adjusted_close, ...

  xfl.fundamentals(ticker, period_type="annual", fields=None, start=None, end=None)
    → pandas.DataFrame of reported financials
    → period_type: "annual" | "quarterly" | "ttm"
    → fields: revenue, net_income, eps_diluted, total_assets,
              operating_margin, return_on_equity, free_cash_flow, ...

  xfl.resolve(ticker)
    → dict with full entity history for a ticker symbol
    → every company that ever used this ticker, with dates + events

Coverage: 12,800+ tickers · 63,000+ entities · 80M+ prices · 75 years fundamentals.
Data is split-adjusted, point-in-time, survivorship-bias-free.
Rate limit: 300 req/hr, 200 unique tickers/day.

Rate limits & usage policy

FREE TIER

xfinlink is free. 300 req/hr, 200 unique tickers/day.

Need more? Email hello@xfinlink.com. IP addresses are hashed for rate limiting and never stored in raw form.

Data sources & methodology

Prices — exchange-sourced, adjusted for splits and dividends, reconciled daily against consolidated tape.

Fundamentals — built from SEC EDGAR public filings, parsed from XBRL with manual QA on 2,400+ of the largest issuers.

Entities — built from SEC filings, corporate actions, and exchange delisting notices. Every entity carries point-in-time validity dates.

CONTACT

Get in touch.

We read everything. Reply within one business day.