Metadata-Version: 2.4
Name: orbo
Version: 0.1.1
Summary: Python SDK for TSETMC
Author: Mohsen_Ghahremani
License-Expression: MIT
Keywords: tsetmc,iran,stock,options,finance
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Operating System :: OS Independent
Requires-Python: >=3.11
Description-Content-Type: text/markdown
Requires-Dist: httpx>=0.28.0
Requires-Dist: pandas>=2.3.0
Requires-Dist: rich>=14.0.0
Requires-Dist: pydantic>=2.11.0
Requires-Dist: jdatetime>=5.0.0
Requires-Dist: pyarrow>=20.0
Provides-Extra: dev
Requires-Dist: pytest>=8.4; extra == "dev"
Requires-Dist: ruff>=0.12; extra == "dev"
Requires-Dist: mypy>=1.17; extra == "dev"

# orbo

**Python SDK for TSETMC — Tehran Stock Exchange data.**

[فارسی](README.fa.md) | English

---

`orbo` gives you clean, typed, Pandas-friendly access to every public data feed on [TSETMC](https://www.tsetmc.com): daily OHLCV history, intraday tick trades, the order-book update stream, option chains, market indices, real/legal client-type flows, and live session data — all with Jalali dates, price-adjustment built-in, and retry logic out of the box.

```python
import orbo

# Search and fetch
stock = orbo.Instrument("شپنا")
df    = stock.history(adjust=True)     # adjusted daily OHLCV — Jalali dates
stats = stock.stats()                  # returns, skewness, kurtosis, tail type

# Intraday order-flow
session    = stock.intraday("20260628")
classified = orbo.TradeSideEngine().classify(session.trades, session.orderbook)
footprint  = orbo.FootprintEngine().build(classified)
print(footprint.summary())             # POC, delta, buy%, classified%

# Live snapshot
snap = stock.live()
print(snap.price[["close","last_price","time"]])
print(snap.orderbook)                  # 5-level live book

# Option chain
chain = orbo.OptionChain.fetch()
df    = chain.for_expiry("اهرم", "1405-04-31")

# Market indices
idx = orbo.find_index("شاخص كل")
df  = idx.history()
```

---

## Installation

```bash
pip install orbo
```

**Requires Python ≥ 3.11.**

Dependencies: `httpx`, `pandas`, `pydantic`, `jdatetime`, `pyarrow`.

> **VPN required in Iran.** TSETMC's CDN API (`cdn.tsetmc.com`) is accessible from inside Iran without VPN. Outside Iran, a VPN pointed at a domestic IP is needed.

---

## Quickstart

### 1 — Daily price history

```python
import orbo

stock = orbo.Instrument("فملی")        # resolve by symbol
df    = stock.history()                # full OHLCV history, Jalali dates
df    = stock.history(adjust=True)     # price-adjusted (dividends + capital increases)
df    = stock.history(count=30)        # last 30 trading days

print(df[["date","close","volume"]].tail())
```

### 2 — Descriptive statistics and return distribution

```python
stats = stock.stats(adjust=True)

print(stats.descriptive)     # mean, median, std, min, max, range
print(stats.distribution)    # skewness, kurtosis, tail_type, is_fat_tail
print(stats.monthly)         # compounded monthly returns
print(stats.cumulative.iloc[-1])   # total return since first day
```

### 3 — Intraday tick data and order flow

```python
session  = stock.intraday("20260628")

df_trades = session.trades           # tick-by-tick trades, sorted by trade_no
df_ob     = session.orderbook        # incremental order-book update stream
df_pt     = session.price_tape       # official closing price tape
df_ct     = session.client_type      # real vs legal buy/sell breakdown
df_sh     = session.shareholders     # major shareholders
```

### 4 — Aggressor-side classification (Lee-Ready)

```python
classified = orbo.TradeSideEngine().classify(
    session.trades,
    session.orderbook,    # enables Quote Rule; falls back to Tick Rule
)
# each row gains: side ("buy"|"sell"|"unknown"), method ("quote"|"tick"|"tick_carry")
```

### 5 — Footprint chart data

```python
result = orbo.FootprintEngine().build(classified)

print(result.poc_price)      # Point of Control
print(result.total_delta)    # net buying pressure
print(result.bars)           # per-price: buy_vol, sell_vol, delta, imbalance
```

### 6 — Option chain

```python
chain = orbo.OptionChain.fetch()       # all markets
chain = orbo.OptionChain.fetch(1)      # TSE only

print(chain.underlyings)               # ["اهرم", "توان", ...]
df = chain.for_expiry("اهرم", "1405-04-31")   # one strike table
print(chain.summary())                 # n_strikes, OI per expiry

chain.refresh()                        # re-fetch live prices
```

### 7 — Market indices

```python
# All indices snapshot
df = orbo.index_snapshot()

# One index by name
idx = orbo.find_index("شاخص كل")
df  = idx.history()          # full daily history, Jalali dates
df  = idx.today()            # intraday time series
df  = idx.companies()        # constituent stocks with live prices

# Statistics on index history
stats = idx.stats()
```

### 8 — Live data

```python
snap = orbo.Instrument("شپنا").live()  # fetches 4 endpoints in one connection

snap.price        # current session price (same schema as today())
snap.trades       # all trades so far today
snap.orderbook    # 5-level full snapshot (not incremental)
snap.client_type  # real/legal flows for the session
```

### 9 — Batch intraday (multiple days with retry)

```python
sessions, failed = orbo.fetch_intraday_range(
    inscode = "7745894403636165",
    dates   = ["20260622", "20260623", "20260624", "20260625"],
    fields  = ["trades", "orderbook"],
)
if failed:
    print("Could not fetch:", failed)
```

---

## Architecture

```
orbo/
├── clients/        HTTP layer — httpx wrappers with retry
├── data/           transformers — raw JSON → typed DataFrames
├── engines/        pure computation — no network, no I/O
│   ├── adjustment.py   cumulative price adjustment (Lee-Ready)
│   ├── trade_side.py   aggressor classification (Quote + Tick Rule)
│   ├── footprint.py    per-price buy/sell aggregation
│   ├── daily_stats.py  return series + distribution stats
│   └── intra_stats.py  intraday VWAP + distribution
├── models/         Pydantic domain objects
├── registry/       local instrument lookup (Parquet cache)
├── history/        InstrumentHistory — daily OHLCV
├── intraday/       IntradaySession — tick data per day
├── index/          MarketIndex — TSE/OTC indices
├── option_chain/   OptionChain — listed option contracts
└── instrument.py   Instrument — unified high-level API
```

**Design principles:**
- Engines are pure functions on DataFrames — no network, no files, fully testable.
- Transformers own all field renaming and Jalali date conversion — nothing else does.
- Every HTTP client retries automatically (3 attempts, exponential backoff).
- `insCode` and `dEven` are never trusted from the API when they arrive null — the caller injects them.

---

## Supported Endpoints

| Category | Endpoint | orbo method |
|---|---|---|
| Daily OHLCV | GetClosingPriceDailyList | `stock.history()` |
| Live price | GetClosingPriceInfo | `stock.today()`, `stock.live().price` |
| Price adjustment | GetPriceAdjustList | `stock.history(adjust=True)` |
| Capital increases | GetInstrumentShareChange | `stock.history(adjust=True)` |
| Intraday trades | GetTradeHistory | `session.trades` |
| Live trades | GetTrade | `stock.live().trades` |
| Order book (history) | BestLimits/{date} | `session.orderbook` |
| Order book (live) | BestLimits | `stock.live().orderbook` |
| Price tape | GetClosingPriceHistory | `session.price_tape` |
| Client type (history) | GetClientTypeHistory | `session.client_type` |
| Client type (live) | GetClientType | `stock.live().client_type` |
| Shareholders | Shareholder | `session.shareholders` |
| Trading status | GetInstrumentStateAll | `stock.state()` |
| Option chain | GetInstrumentOptionMarketWatch | `OptionChain.fetch()` |
| Index snapshot | GetIndexB1LastAll | `orbo.index_snapshot()` |
| Index history | GetIndexB2History | `idx.history()` |
| Index intraday | GetIndexB1LastDay | `idx.today()` |
| Index companies | GetIndexCompany | `idx.companies()` |
| Instrument search | GetInstrumentSearch | `orbo.search("فملی")` |

---

## What's coming

**`orbo-quant`** — a separate analytical library that reads from `orbo` and adds:

- Black-Scholes pricing and Greeks (Δ, Γ, Θ, Vega, Rho)
- Implied volatility solver
- IV surface construction
- Option strategy builder and P&L diagrams
- Portfolio optimization

`orbo` intentionally stays focused on data access. Analytics live in `orbo-quant`.

---

## Development

```bash
git clone https://github.com/your-username/orbo
cd orbo
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
pytest tests/ -v
```

---

## License

MIT © 2026
