# Field dictionary and calculation notes

Every delivery uses this 34-column header, in this order, one row per contract per
session. Columns a given upstream cannot populate are empty, never zero.

| # | column | type | deep mirror | broad mirror | live Cboe | notes |
|---|--------|------|-------------|--------------|-----------|-------|
| 1 | `contract` | text | yes | built | yes | OCC symbol, e.g. `SPY200316C00180000` |
| 2 | `underlying` | text | yes | yes | yes | |
| 3 | `expiration` | date | yes | yes | yes | |
| 4 | `type` | text | yes | yes | yes | `call` / `put` |
| 5 | `strike` | decimal | yes | yes | yes | as listed on the session |
| 6 | `style` | text | `A` | `A` | `A` | `A` American, `E` European (index) |
| 7 | `quote_date` | date | yes | yes | yes | session |
| 8 | `bid` | decimal | yes | yes | yes | |
| 9 | `bid_size` | int | yes | no | yes | contracts |
| 10 | `ask` | decimal | yes | yes | yes | |
| 11 | `ask_size` | int | yes | no | yes | contracts |
| 12 | `quote_time` | time | `16:00:00` | `16:00:00` | feed time | see *Snapshot* |
| 13 | `volume` | int | yes | **no** | yes | session contracts |
| 14 | `open_interest` | int | yes | **no** | yes | prior close |
| 15 | `open` | decimal | no | no | yes | contract session OHLC |
| 16 | `high` | decimal | no | no | yes | |
| 17 | `low` | decimal | no | no | yes | |
| 18 | `close` | decimal | no | no | yes | last trade price |
| 19 | `trade_vwap` | decimal | no | no | no | |
| 20 | `transactions` | int | no | no | no | |
| 21 | `multileg_volume` | int | no | no | no | |
| 22 | `active_minutes` | int | no | no | no | |
| 23 | `last_trade_date` | datetime | no | no | yes | |
| 24 | `underlying_close` | decimal | yes | join | yes | at the snapshot |
| 25 | `settlement_time` | text | no | no | no | `AM`/`PM` for index roots |
| 26 | `iv_bid` | decimal | no | no | no | |
| 27 | `iv_ask` | decimal | no | no | no | |
| 28 | `iv` | decimal | yes | yes | yes | annualised, 0.2051 = 20.51 % |
| 29 | `iv_flag` | int | 0 | 0 | 0 | 0 mid, 1 bid-side, 2 ask-side |
| 30 | `delta` | decimal | yes | yes | yes | per 1.00 of underlying |
| 31 | `gamma` | decimal | yes | yes | yes | per 1.00 |
| 32 | `theta` | decimal | yes | yes | yes | per calendar day |
| 33 | `vega` | decimal | yes | yes | yes | per 1.00 vol point |
| 34 | `rho` | decimal | yes | yes | yes | per 1.00 rate point |
| 35 | `source` | text | `deep-mirror` | `dolthub` | `cboe-delayed` | |
| 36 | `ingest_utc` | datetime | yes | yes | yes | |

`source` and `ingest_utc` are additions to the 34-column industry layout; drop
them if you need an exact byte match to someone else's schema.

## Snapshot time

The deep and broad mirrors are end-of-day files: the quote is the last
consolidated top-of-book at or before the 16:00 ET close. `quote_time` is set to
`16:00:00` to make that explicit. There is **no 15:45 tradeable snapshot** in
these files. If your backtest needs a pre-close executable quote, take the
15:45 variant (delivery option, priced separately) or treat the 16:00 quote as a
mark, not a fill.

The live Cboe capture records the feed's own timestamp (roughly 15 minutes
behind the tape) in `quote_time`.

## Greeks and IV

Greeks are Black-Scholes-Merton with a continuous dividend yield, solved from
the quote mid, per contract, using the session's risk-free curve and the
underlying close. IV is the mid-solution; `iv_flag` is 0 unless the mid is
unusable, in which case the bid (1) or ask (2) side is used and flagged.

Theta is per calendar day, vega and rho per one point (1.00) of vol and rate.
Delta and gamma are per 1.00 of underlying, not per contract multiplier.

Rows where the solver does not converge inside 100 iterations carry empty IV and
greeks rather than a sentinel. The mirror has no such rows in the shipped
sample; `catalog/quality.json` tracks solver coverage per run.

## Strikes, splits and corporate actions

Strikes are **as listed on that session**, never restated to today's terms.

On a split, the pre-split contracts are **re-listed under new OCC symbols at the
adjusted strike** on the ex-date, and a fresh unadjusted series is listed
alongside them. NVDA 10:1 on 2024-06-10 is the worked example:

| session | contract | strike | mid |
|---|---|---|---|
| 2024-06-07 | `NVDA240621C00010000` | 10.00 | 1,198.45 |
| 2024-06-10 | `NVDA240621C00001000` | 1.00 | 121.68 (adjusted series) |
| 2024-06-10 | `NVDA240621C00010000` | 10.00 | 111.80 (new series) |

Same expiry, same type, same root, **different contract id**. There is no
corporate-action flag and no adjusted-root marker. To carry a position across
the ex-date you must map `old contract -> adjusted contract` yourself: same
expiry and type, `strike_after = strike_before / ratio`. The adjusted series is
otherwise identified only by strikes that sit off the standard grid (0.50, 1.00,
1.50 where the new grid starts at 10.00).

If you need the exchange root preserved (`NVDA1`, `NVDA2`), take the
adjusted-root delivery option.

## Known absences

- No exchange or NBBO indicator per quote; top-of-book only.
- No trade prints, so no per-contract VWAP, transaction count or multi-leg volume.
- No contract session OHLC for the historical mirrors (live capture only).
- No pre-2020 broad-universe coverage and no pre-2008 coverage at all; see
  `COVERAGE.md`.
