Metadata-Version: 2.4
Name: otql
Version: 0.1.0
Summary: Open Terminal Query Language (OTQL) — Python SDK for financial statements, valuation multiples, peer analytics, and SEC EDGAR provenance.
Author: Paulo Tanaka
License: MIT
Keywords: finance,sec-edgar,valuation,multiples,bql,otql,stocks,dataframe
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Financial and Insurance Industry
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
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: Typing :: Typed
Requires-Python: >=3.9
Description-Content-Type: text/markdown
Requires-Dist: numpy>=1.24.0
Requires-Dist: pandas>=2.0.0
Requires-Dist: pydantic>=2.0.0
Provides-Extra: dev
Requires-Dist: build>=1.0.0; extra == "dev"
Requires-Dist: pytest>=7.4.0; extra == "dev"
Requires-Dist: pyright>=1.1.400; extra == "dev"
Requires-Dist: ruff>=0.5.0; extra == "dev"
Requires-Dist: twine>=5.0.0; extra == "dev"

# `otql` — Open Terminal Query Language Python SDK

`otql` is the external Python query library and analytical SDK for the `stock-analysis` financial terminal. It provides both a declarative, composable query engine modeled after Bloomberg Query Language (`oq.univ`, `oq.data`, `oq.func`, `otql.Request`, `otql.combined_df`) and direct `pandas.DataFrame` domain accessors for every dataset surfaced in the application.

## Installation

### Local Editable Install (from repository root)
```bash
backend/venv/bin/pip install -e ./sdk
```

### Connecting to a Running Terminal Server
```python
import otql

# Connect to a local or remote stock-analysis server
oq = otql.Service(server_url="http://localhost:5173")

# Or configure globally (also reads OTQL_SERVER_URL from the environment)
otql.configure(server_url="http://localhost:5173")
```

## Quickstart

### 1. Declarative OTQL Query (`oq.univ`, `oq.data`, `oq.func`, `otql.Request`)
```python
import otql

oq = otql.Service(server_url="http://localhost:5173")

univ = oq.univ.filter(
    oq.univ.equities(),
    (oq.data.market_cap() > 10e9) & (oq.data.roic() > 15.0),
)

ev_ebitda = oq.data.ev_ebitda()
sector_median = oq.func.ungroup(oq.func.group(ev_ebitda, by=oq.data.sector()).median())

req = otql.Request(
    univ,
    {
        "Sector": oq.data.sector(),
        "ROIC (%)": oq.data.roic(),
        "EV/EBITDA": ev_ebitda,
        "Sector Median EV/EBITDA": sector_median,
        "3Y Rev CAGR (%)": oq.data.total_revenues(period_offset=oq.func.range(-3, 0)).cagr(),
    },
)

resp = oq.execute(req)
df = otql.combined_df(resp)
```

### 2. Direct Domain Accessors
```python
# Standardized & As-Reported Financial Statements with SEC iXBRL Citations
inc = oq.statement("AAPL", "income", frequency="annual")
print(inc.df)
print(inc.citations_df)

# 74 Historical Valuation Multiples & Institutional Factor Frameworks
mult = oq.multiples("AAPL", frequency="annual")
print(mult.df)
print(mult.stats_5y_df)

# Relative Valuation: Peer Comps, Football Field, Spread Z-Scores, Regression & Sector Matrix
peers = oq.peers("AAPL")
print(peers.comps_df)
print(peers.football_field_df)

reg = oq.regression("AAPL", x_metric="roic", y_metric="ev_ebitda")
print(reg.residuals_df)

wpe_df = oq.sector_matrix(group_by="macro_sector")

# Analyst Estimates (ANR / BI) & Filing Disclosures (BRC / DS)
est = oq.estimates("AAPL")
print(est.consensus_bridge_df())
print(est.guidance_df())
```

## Building & Publishing to PyPI

```bash
# 1. Build source distribution (.tar.gz) and wheel (.whl)
python3 -m build sdk --outdir sdk/dist

# 2. Validate package metadata
twine check sdk/dist/*

# 3. Upload to TestPyPI (optional verification)
twine upload --repository testpypi sdk/dist/*

# 4. Publish to PyPI
twine upload sdk/dist/*
```
