Metadata-Version: 2.4
Name: ol-sdk
Version: 0.2.2
Summary: Python client for Oxford Ledge Financial Terminal
Project-URL: Homepage, https://www.oxfordledge.com
Project-URL: Repository, https://github.com/hs902/oxford-ledge-sdk
Author-email: Oxford Ledge <support@oxfordledge.com>
License-Expression: MIT
License-File: LICENSE
Keywords: bonds,credit,equities,finance,fundamentals,investing,screening
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Financial and Insurance Industry
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
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: Topic :: Office/Business :: Financial
Classifier: Topic :: Office/Business :: Financial :: Investment
Classifier: Typing :: Typed
Requires-Python: >=3.8
Requires-Dist: requests>=2.28.0
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == 'dev'
Requires-Dist: responses>=0.20.0; extra == 'dev'
Provides-Extra: pandas
Requires-Dist: pandas>=1.3.0; extra == 'pandas'
Description-Content-Type: text/markdown

> **Last Updated:** 2026-04-04 09:40 ET

# Oxford Ledge Python SDK

The official Python client for the [Oxford Ledge Financial Terminal](https://www.oxfordledge.com) -- equities, credit, screening, AI analysis, and more from your Python scripts and Jupyter notebooks.

## Installation

```bash
pip install oxford-ledge-sdk
```

For DataFrame support in Jupyter:

```bash
pip install oxford-ledge-sdk[pandas]
```

## Quick Start

```python
import oxford_ledge_sdk as ol

# Set your API key (get one at https://www.oxfordledge.com)
ol.set_api_key("ol_live_YOUR_KEY_HERE")  # Get your key at oxfordledge.com

# Company profile
company = ol.get_company("AAPL")
print(company.name, company.sector, company.market_cap)

# Fundamentals
fundamentals = ol.get_fundamentals("MSFT")
print(fundamentals.pe_ratio, fundamentals.roe)

# Historical prices (returns a ResultList)
prices = ol.get_prices("AAPL", start="2024-01-01")

# Screen for undervalued stocks
results = ol.screen(pe_max=15, roe_min=20, sector="Technology")

# AI-powered analysis
answer = ol.ask("Is AAPL undervalued based on its fundamentals?", ticker="AAPL")
print(answer)
```

## Using the Client Directly

For more control (custom timeouts, multiple keys), use the client class:

```python
from oxford_ledge_sdk import OxfordLedgeClient

client = OxfordLedgeClient(
    api_key="ol_live_YOUR_KEY_HERE",
    timeout=60,
    max_retries=5,
)

company = client.get_company("TSLA")
client.close()

# Or use as a context manager
with OxfordLedgeClient(api_key="ol_live_YOUR_KEY_HERE") as client:
    bonds = client.search_bonds("Apple")
    borrowers = client.search_borrowers("Apex Technology")
```

## DataFrame Support (Jupyter)

Any method that returns a `ResultList` supports `.to_dataframe()`:

```python
import oxford_ledge_sdk as ol
ol.set_api_key("ol_live_YOUR_KEY_HERE")  # Get your key at oxfordledge.com

# Price history as a DataFrame
prices = ol.get_prices("AAPL", start="2024-01-01")
df = prices.to_dataframe()
df.plot(x="date", y="close", title="AAPL Price History")

# Screener results as a DataFrame
results = ol.screen(pe_max=20, dividend_yield_min=2)
df = results.to_dataframe()
df.sort_values("pe_ratio").head(10)

# Bond search
bonds = ol.search_bonds("Microsoft")
bonds.to_dataframe()[["issuer", "coupon", "maturity", "rating"]]
```

## API Reference

### Configuration

| Function | Description |
|----------|-------------|
| `ol.set_api_key(key)` | Set API key for module-level functions |
| `ol.set_base_url(url)` | Override base URL (for local dev) |

### Company Data

| Function | Description |
|----------|-------------|
| `ol.get_company(ticker)` | Company profile, quote, summary |
| `ol.get_fundamentals(ticker, years=None)` | Financial fundamentals |
| `ol.get_fundamentals_pit(ticker, date)` | Point-in-time fundamentals |
| `ol.get_fundamentals_history(ticker, start, end)` | Fundamental time series |
| `ol.get_company_financials(ticker)` | Full 3-statement financials |
| `ol.get_peers(ticker)` | Peer company tickers |
| `ol.get_data_coverage(ticker)` | Data source coverage map |

### Ownership & Insiders

| Function | Description |
|----------|-------------|
| `ol.get_13f(ticker)` | Institutional holders (13F) |
| `ol.get_13d(ticker)` | Activist / large-holder filings |
| `ol.get_insiders(ticker)` | Insider transactions |
| `ol.get_insider_activity(ticker, days=90)` | Insider buy/sell activity |
| `ol.search_funds(query)` | Search 13F institutional filers |
| `ol.get_fund_holdings(cik)` | Fund 13F holdings by CIK |

### Prices & Market

| Function | Description |
|----------|-------------|
| `ol.get_prices(ticker, start, end, period)` | Historical price data |
| `ol.get_price_history(ticker, days=365)` | Daily price history |
| `ol.get_indicators()` | Market indicators (indices, rates) |
| `ol.get_global_markets()` | International market overview |
| `ol.get_sector_breakdown()` | Sector performance |
| `ol.get_calendar()` | Economic/earnings calendar |
| `ol.get_macro_events(days=7)` | Upcoming macro events |
| `ol.get_fred()` | FRED macro data (GDP, CPI, etc.) |
| `ol.get_yield_curve()` | Treasury yield curve history |
| `ol.get_index_movers()` | Top movers in major indices |
| `ol.get_market_earnings()` | Upcoming earnings calendar |
| `ol.get_random_ticker()` | Random ticker for discovery |

### Screening

| Function | Description |
|----------|-------------|
| `ol.screen(**filters)` | Run stock screener with filters |

Supported filters: `pe_max`, `pe_min`, `roe_min`, `roe_max`, `sector`, `market_cap_min`, `market_cap_max`, `dividend_yield_min`, and more.

### Bonds & Credit

| Function | Description |
|----------|-------------|
| `ol.search_bonds(query)` | Search corporate bonds |
| `ol.search_borrowers(query)` | Search BDC borrowers |
| `ol.get_bdc_portfolio(ticker)` | BDC portfolio holdings |
| `ol.list_bdcs()` | List all BDCs |
| `ol.get_bdc_borrower(query)` | Look up BDC borrower holders |
| `ol.get_debt_maturities(ticker)` | Debt maturity schedule |
| `ol.get_capital_structure(ticker)` | Capital structure breakdown |
| `ol.get_credit_movers()` | Bond price gainers/losers |

### Estimates & Valuation

| Function | Description |
|----------|-------------|
| `ol.get_estimates(ticker)` | Analyst estimates |
| `ol.get_estimate_revisions(ticker)` | Estimate revision momentum |
| `ol.get_estimate_movers(days=30)` | Biggest estimate movers |
| `ol.get_rating_events(ticker)` | Credit rating changes |
| `ol.get_valuation_history(ticker)` | Historical multiples |
| `ol.get_capital_allocation(ticker)` | Buybacks, dividends, capex |
| `ol.get_sensitivity(ticker)` | DCF sensitivity analysis |
| `ol.get_implied_assumptions(ticker)` | Market-implied assumptions |
| `ol.get_portfolio_analytics(tickers)` | Portfolio-level analytics |

### News

| Function | Description |
|----------|-------------|
| `ol.get_headlines()` | Latest market headlines |
| `ol.search_news(query, ticker, days, limit)` | Search news articles |
| `ol.get_news_for_ticker(ticker)` | News for a specific ticker |

### ETFs

| Function | Description |
|----------|-------------|
| `ol.get_etf(ticker)` | ETF data, holdings, sectors |
| `ol.compare_etfs(tickers)` | Compare 2-5 ETFs (overlap) |
| `ol.list_etfs()` | List all known ETFs |

### Dividends

| Function | Description |
|----------|-------------|
| `ol.get_dividend_forecast(tickers)` | Dividend forecast |

### Presentations & Lore

| Function | Description |
|----------|-------------|
| `ol.search_presentations(query)` | Investor presentations |
| `ol.search_lore(query)` | Financial lore and wisdom |
| `ol.get_value_investing_random()` | Random investing fact |
| `ol.search_value_investing(query)` | Search investing facts |
| `ol.get_recommended_reading()` | Curated reading list |
| `ol.get_recommended_reading_random()` | Random book recommendation |

### Options & Short Interest

| Function | Description |
|----------|-------------|
| `ol.get_options(ticker)` | Options chain |
| `ol.get_short_interest(ticker)` | Short interest data |
| `ol.get_options_sentiment(type, days)` | Put/call ratios (CBOE) |

### AI Analysis

| Function | Description |
|----------|-------------|
| `ol.ask(question, ticker=None)` | Ask the AI analyst |

## Error Handling

```python
import oxford_ledge_sdk as ol
from oxford_ledge_sdk import AuthenticationError, RateLimitError, NotFoundError, QuotaExceededError

ol.set_api_key("ol_live_YOUR_KEY_HERE")  # Get your key at oxfordledge.com

try:
    company = ol.get_company("INVALID")
except NotFoundError:
    print("Ticker not found")
except AuthenticationError:
    print("Check your API key")
except RateLimitError as e:
    print(f"Rate limited. Retry after {e.retry_after}s")
except QuotaExceededError:
    print("Monthly budget exhausted -- check billing at oxfordledge.com")
```

## Rate Limits

The SDK automatically:
- Tracks requests to stay within 60 RPM
- Retries on 429 (rate limit) and 5xx (server error) with exponential backoff
- Raises `QuotaExceededError` when monthly budget is exhausted (distinct from rate limiting)

## Models

All structured responses use lightweight dataclasses. Access the raw API response via the `.raw` attribute:

```python
company = ol.get_company("AAPL")
print(company.name)          # Typed field
print(company.raw["beta"])   # Full raw response dict
```

Available models: `Company`, `Quote`, `Fundamentals`, `Bond`, `Borrower`, `NewsItem`, `Presentation`.

## Requirements

- Python 3.8+
- `requests >= 2.28.0`
- `pandas >= 1.3.0` (optional, for DataFrame support)

## Get Your API Key

Sign up at [oxfordledge.com](https://www.oxfordledge.com) to get your API key. Keys start with `ol_live_` (production) or `ol_test_` (sandbox).

## Disclaimer

This software is provided "as is", without warranty of any kind, under
the MIT License (see LICENSE). It is a developer tool for accessing and
parsing financial data. **It is not investment, financial, legal, or
tax advice, and nothing it returns is a recommendation to buy, sell, or
hold any security.** Data may be incomplete, delayed, or inaccurate.
You are responsible for independently verifying anything you rely on
and for your own investment decisions. Data returned by the Oxford
Ledge API is governed by the terms at https://www.oxfordledge.com.

## Contributions

By submitting a pull request or patch, you agree your contribution is
licensed under the same MIT License as this project (inbound = outbound).
