Metadata-Version: 2.4
Name: optionda
Version: 0.1.0
Summary: Terminal options desk: freeze IV, reprice on live spot (Yahoo or Alpaca).
Author: Yuanben
License: MIT
Project-URL: Homepage, https://github.com/ybenzou/optionda
Keywords: options,black-scholes,cli,alpaca,yfinance
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Intended Audience :: Financial and Insurance Industry
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Office/Business :: Financial :: Investment
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: httpx>=0.27
Requires-Dist: pydantic>=2.7
Requires-Dist: rich>=13.7
Requires-Dist: typer>=0.12
Requires-Dist: yfinance>=0.2.40
Provides-Extra: dev
Requires-Dist: pytest>=8.0; extra == "dev"
Dynamic: license-file

# optionda

Terminal options desk: manage small multi-account option books, freeze IV, and reprice on live underlying prints.

```bash
pip install optionda
# or from this repo:
pip install -e ./optionda
```

**MODEL marks only** — delayed/indicative data, not executable quotes.

## Quick start (no API key)

Requires Python 3.11+.

```bash
py -3.11 -m venv .venv
source .venv/Scripts/activate
pip install -e .

# one-time (like conda init)
optionda init
eval "$(optionda shellenv)"   # or open a new shell — default prompt: [optionda] (cyan)

optionda create demo
optionda activate demo        # prompt → [demo]
optionda deactivate           # prompt → [optionda]
optionda activate hedge       # prompt → [hedge]

optionda add AAPL270115C00200000 --qty 2 --entry 5.20

# per-line qty + cost (semicolon batch):
optionda add "INTC 261016 140 C x10 @ 3.482; SKHY 261016 200 C x1 @ 9.5"

# easiest batch: bare add → paste lines → blank line to finish
optionda add
# INTC 261016 140 C x10 @ 3.482
# TSLA 261218 500 C x2 @ 5.75
# <empty line>

optionda export
optionda run
```

`pip install` cannot safely edit your shell config (unlike the Conda installer). Run **`optionda init` once**, then **`optionda activate <name>`** each session (like `conda activate`). Undo init with `optionda init --reverse`.

Without `activate`, `export` / `run` / `add` / `delete` cannot read or change any account book — only the session-active account is visible.

**Cost is required on every `add`**: use `@ 5.20` on the line or `--entry 5.20`. Re-adding the same OCC+side merges qty and sets cost to the quantity-weighted average `(q1·c1 + q2·c2) / (q1+q2)`.

`add` **without** `--iv` pulls IV from Alpaca (if key configured) or Yahoo. Use `--iv` only as fallback.

In the table, **`Model$`** is the Black–Scholes theoretical premium (per share), **`Cost`** is your avg entry, and **`uPnL$`** compares them. Not a live option bid/ask.

UI uses **Rich** (`Panel`, `Rule`, `Table`, `Live` spinner). No `tqdm` / `popen` required for the desk view.

## Optional Alpaca key (15s refresh)

```bash
optionda key alpaca <KEY_ID> <SECRET>   # verifies against Alpaca before saving
optionda key status                     # re-checks live credentials
optionda run                            # refresh every 15s
optionda key clear alpaca
```

`key alpaca` probes `data.alpaca.markets` (SPY latest trade). Invalid keys are **not** saved.

Credentials live in `~/.optionda/credentials.toml` (mode `0600` when the OS allows). Override the data root with `OPTIONDA_HOME`.

Per-account tracking files (under the optionda data library, **not** your shell cwd):

Two separate write paths:

| Path | Role | Write mode |
|------|------|------------|
| `~/.optionda/books/<account>.txt` | Current book only (human snapshot) | **Overwrite** on add/delete/refresh |
| `~/.optionda/logs/<account>.jsonl` | Full event stream for charts / history | **Append only** |
| `~/.optionda/surfaces/<underlying>.json` | Last valid Alpaca IV smile | **Overwrite** only on successful `refresh-iv` |

JSONL `event` types: `add`, `merge`, `delete`, `refresh_iv`, `export`, `run`.  
`refresh_iv` records calibrated surface metadata. `export`/`run` rows include `valuation_mode`, `surface_iv`, and `surface_as_of`.

```bash
optionda add …          # rewrite book + append add/merge event
optionda delete …       # rewrite book + append delete event
optionda refresh-iv     # calibrate Alpaca vendor-IV smiles while quotes are fresh
optionda export         # print surface/frozen Model$ + append export mark
optionda run            # each tick appends a run mark
```

**Spot (24/5):** Alpaca stock spots query `overnight` → `boats` → `delayed_sip` → `iex` and keep the **newest** trade/quote. Basic plans usually get `overnight` (≈Futu night session); `boats` needs a higher data tier.

### Local overnight IV surface

Run `optionda refresh-iv` **during the US option session**, when Alpaca chain quotes are current. It collects valid Alpaca vendor-IV nodes, filters zero/wide/stale quotes, and saves a per-underlying expiry smile.

At night, `run` / `export` update the 24/5 stock Spot, use the saved expiry smile with **sticky delta** interpolation, and then reprice with Black–Scholes. The `IVsrc` column is `surface` when this succeeds and `frozen` when optionda falls back to the stored position IV. Surfaces older than 36 hours are not used.

This is a local, auditable model—not a copy of Futu's proprietary IV surface. Alpaca's free `indicative` chain is still the calibration input; OPRA improves the input only when the user has a subscription. optionda deliberately does **not** infer a new IV from frozen overnight option quotes.

```toml
# ~/.optionda/config.toml
alpaca_options_feed = "auto"       # try opra, then indicative
```

For a paid match to exchange IV, subscribe to Alpaca OPRA.

## Commands

| Command | Purpose |
|---------|---------|
| `optionda create <name>` | Create account |
| `optionda list` | List accounts (`*` = session-active) |
| `optionda book` | Show current positions (no fetch / no log write) |
| `optionda activate <name>` | Session-activate (prompt → cyan `[name]`) |
| `optionda deactivate` | Back to cyan `[optionda]` |
| `optionda init` | Persist hook in shell rc (like `conda init`) |
| `optionda add …` | Add with required cost; same OCC+side merges qty + avg cost |
| `optionda delete <id\|OCC>` | Remove position |
| `optionda refresh-iv` | Calibrate local Alpaca IV smiles and refresh fallback IVs |
| `optionda run` | Live table until Ctrl+C |
| `optionda export` | One-shot snapshot |
| `optionda key …` | Configure Alpaca credentials |

## Repository

Standalone project: [github.com/ybenzou/optionda](https://github.com/ybenzou/optionda). Not part of the Next.js frontend app.
