Metadata-Version: 2.4
Name: xfinlink
Version: 0.5.4
Summary: Free financial data API client — prices, fundamentals, entity resolution for all US equities
Author: xfinlink team
License-Expression: MIT
Project-URL: Homepage, https://xfinlink.com
Project-URL: Repository, https://github.com/dignaga69/xfinlink
Project-URL: Documentation, https://xfinlink.com/docs
Keywords: finance,stock,prices,fundamentals,SEC,EDGAR,ticker,entity-resolution,financial-data,API
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Financial and Insurance Industry
Classifier: Intended Audience :: Science/Research
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Office/Business :: Financial
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: httpx>=0.24
Requires-Dist: pandas>=1.5
Provides-Extra: local
Requires-Dist: sqlalchemy>=2.0; extra == "local"
Requires-Dist: pyarrow; extra == "local"
Requires-Dist: pydantic; extra == "local"
Provides-Extra: dev
Requires-Dist: pytest; extra == "dev"
Requires-Dist: pytest-asyncio; extra == "dev"
Dynamic: license-file

# xfinlink

Validate and fix financial data merges. Catches silent identifier errors — ticker recycling, bankruptcies, renames, spin-offs — that corrupt research datasets.

## Install

```bash
pip install xfinlink
```

That's it. No Docker. No database setup. Works immediately.

## Quick start

```python
import pandas as pd
from xfinlink import validate_dataframe

panel = pd.read_csv("my_research_data.csv")

report = validate_dataframe(panel, id_column="ticker", date_column="date")
print(report.summary)
# "1247 rows checked. 828 clean. 419 issues found."
```

## Fix errors automatically

```python
from xfinlink import fix_dataframe

fixed = fix_dataframe(panel, id_column="ticker", date_column="date")
# Adds _entity_id, _canonical_name, _cik, _xfinlink_flag columns
```

## What it catches

- **Ticker recycling**: GM before 2009 vs GM after 2010 — different companies, different CIKs
- **Ticker hijacking**: META was an ETF before Facebook claimed it in 2022
- **Corporate renames**: GHC was WPO (Washington Post) before 2013
- **Spin-offs**: HPE didn't exist before the HP split in 2015
- **Take-privates**: DELL went private 2013-2018, different legal entity before and after

## Single identifier lookup

```python
from xfinlink import resolve

result = resolve("ticker", "GM", date="2008-06-15")
# Returns: General Motors Corporation (pre-bankruptcy)

result = resolve("ticker", "GM", date="2012-01-15")
# Returns: General Motors Company (post-bankruptcy)
```

## CLI

```bash
xfinlink status                # Database stats
xfinlink resolve ticker AAPL   # Look up any identifier
xfinlink validate data.csv --id-column ticker --date-column date
xfinlink fix data.csv --id-column ticker --date-column date
xfinlink serve                 # Local API server
xfinlink mcp                   # AI agent interface
```

## Want WRDS identifiers? (PERMNOs, GVKEYs)

```bash
pip install xfinlink[wrds]
xfinlink enrich --wrds
```

One command, ~5 minutes. Uses your WRDS credentials. Data stays on your machine.

## For AI agents

```bash
xfinlink mcp
```

See [CLAUDE.md](CLAUDE.md) for integration details.
