Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion account/plan-limits.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ For users working with options, take care before repeatedly requesting quotes fo
:::

:::note[Trial plans]
Starter Trial and Trader Trial do not support `mode=cached`.
Starter Trial, Trader Trial, and Prime Trial do not support `mode=cached`.
:::

## Device Restrictions
Expand Down
24 changes: 24 additions & 0 deletions api/options/quotes.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,30 @@ foreach (var quote in (await client.Options.GetQuoteAsync("AAPL271217C00250000")

The option symbol according to OCC symbology.

- **underlying** `array[string]`

The ticker symbol of the underlying security.

- **expiration** `array[number]`

The option's expiration date and time. Equity options expire at 4:00 PM Eastern and index options expire at 4:15 PM Eastern. All timestamps use US Eastern Time (America/New_York). See [Response Timezone](/docs/api/dates-and-times#response-timezone) for details.

- **side** `array[string]`

The response will be `call` or `put`.

- **strike** `array[number]`

The exercise price of the option.

- **firstTraded** `array[date]`

The date the option was first traded.

- **dte** `array[number]`

The number of days until the option expires.

- **ask** `array[number]`

The ask price.
Expand Down
2 changes: 1 addition & 1 deletion api/rate-limiting.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,5 +82,5 @@ We provide the following headers in our responses to help you manage the rate li
- Paying customers can make use of the reduced-price cached mode. Use the `mode=cached` parameter on supported bulk endpoints to retrieve previously cached quotes instead of making a live request. This can save thousands of credits. For more details, refer to the [mode parameter documentation](/api/universal-parameters/mode).

:::note[Trial plans]
`mode=cached` is not available on Starter Trial and Trader Trial plans.
`mode=cached` is not available on Starter Trial, Trader Trial, and Prime Trial plans.
:::
27 changes: 19 additions & 8 deletions internal/byok-audit-prompt.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,12 @@ reading as a failure.

## The prompt

{/* TODO(compliance): confirm whether the 4:15:01 PM ET stock cutoff, taken from
account/data-freshness.md, is also the exchange redistribution-fee boundary for
stock data. The prompt's "One case that is neither a PASS nor a plain FAIL"
section treats it as historical, and so as fee-free, until compliance says
otherwise. See #222. */}

````
You are an independent compliance auditor. Audit the repository at [REPO PATH]
against the Market Data BYOK model and the Market Data data policies. Write your
Expand Down Expand Up @@ -183,17 +189,17 @@ or UNRESOLVED.
| ID | The rule |
|----|----------|
| E1 | Every request carries a unique `User-Agent` that names the application and its version. A library default such as `axios/1.6.0`, `python-requests/2.31.0`, or `okhttp/4.12.0` fails this rule. |
| E2 | Option chain requests use `mode=cached` unless the use case needs live data. A live chain costs one credit per contract; a cached chain costs one credit. |
| E2 | Option chain requests use `mode=cached` unless the use case needs live data. A live chain costs one credit per contract; a cached chain costs one credit. Cached mode is available only on paid plans that are not trials. Free Forever and every trial (Starter Trial, Trader Trial, Prime Trial) get a `402` for `mode=cached`, so on a `402` the application repeats the request without `mode`. |
| E3 | Polling intervals fit a credit budget. A free key holds 100 credits a day. State the worst-case daily credit spend you can derive from the code. |
| E4 | The application handles `429`, `402`, and `403` with a message to the user. A `403` is the single-IP control and clears after five minutes with no requests. |
| E4 | The application handles `429`, `402`, and `403` with a message to the user. A `403` is the single-IP control. The block expires five minutes after the IP switch; further requests during the block do not extend it. |

### Group F — Onboarding and entitlement (all P2)

| ID | The rule |
|----|----------|
| F1 | Onboarding tells the user they need a second account, and links to the Market Data sign-up page. |
| F2 | Onboarding explains the verification step and the wait of up to one business day before real-time data arrives. |
| F3 | The application works on a delayed, historical, or quota-limited key, and reads response timestamps rather than assuming the data is live. A missing entitlement raises no error: the API returns the freshest data the user is entitled to. |
| F3 | The application works on a delayed, historical, or quota-limited key, and reads response timestamps rather than assuming the data is live. When the request sends no `mode`, a missing entitlement raises no error: the API returns the freshest data the user is entitled to. A paid plan is also downgraded silently. On a Free Forever or trial key, an explicit `mode=live`, `mode=delayed`, or `mode=eod` returns `402` "Feed not available for your plan.", and so does a date older than the plan allows. The application omits `mode` unless it needs one, and handles the `402`. |
| F4 | The application does not assume every user is non-professional. A user our compliance team classifies as professional never receives real-time data on a self-service plan. |

## What is NOT a finding
Expand All @@ -220,18 +226,23 @@ Do not report these. Each one is a legitimate design.

A developer server that handles only **historical** data is not BYOK, and it is
also not automatically a violation. The exchanges charge no redistribution fee
for historical data, meaning data from a completed session once the next session
has opened. Delayed data does not qualify.
for historical data, meaning data from a completed session. Delayed data does not
qualify.

If you find a server path that carries only historical data, record it as a P1
against A2, and add a note that the product may qualify under the historical-only
model. Recommend that the developer contact Market Data sales rather than
recommending a code change. Say plainly that you cannot grant that model, and
that only Market Data can.

Data becomes historical at the open of the next trading session. A product that
serves the previous session's data at 06:00 Eastern is serving delayed data and
is fee-liable until the bell.
Stocks and options become historical at different times:

- Stock data becomes historical at 4:15:01 PM Eastern on the session day.
- Option data becomes historical at 9:30:01 AM Eastern, at the open of the next
trading session.

A product that serves the previous session's option data at 06:00 Eastern is
serving delayed data and is fee-liable until the bell.

## Search seeds

Expand Down
37 changes: 32 additions & 5 deletions sheets/options/optionchain.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
---
title: OPTIONCHAIN
description: The OPTIONCHAIN formula fetches a current option chain into your spreadsheet. See the syntax, sample usage and data availability.
description: The OPTIONCHAIN formula fetches a current or end-of-day historical option chain into your spreadsheet. See the syntax, samples and data availability.
sidebar_position: 3
sidebar_custom_props:
badge: h
---

Fetches a current option chain from Market Data.
Fetches a current option chain, or the end-of-day option chain of a past trading day, from Market Data.

## Video Tutorial
<iframe width="100%" height="503" src="https://www.youtube.com/embed/Pwnsp5SsU3M" title="How To View and Filter The Options Chain" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
Expand All @@ -18,10 +18,16 @@ Fetches a current option chain from Market Data.
=OPTIONCHAIN("AAPL","all,noheaders","60 DTE","150,160)
=OPTIONCHAIN("AAPL","all","60 DTE","100-200","calls")
```
### Historical Chains
```excel-formula
=OPTIONCHAIN("AAPL","strike,bid,ask","45 DTE","200-250","puts","2026-09-01")
=OPTIONCHAIN("AAPL",,,,,"last session")
=OPTIONCHAIN(A2,"strike,bid,ask","45 DTE","200-250","puts",B2)
```

## Syntax
```excel-formula
=OPTIONCHAIN(underlying symbol, [attributes], expiration date, [strikes], [filters])
=OPTIONCHAIN(underlying symbol, [attributes], expiration date, [strikes], [filters], [as of])
```

- **underlying symbol** _(REQUIRED)_ Use the stock, etf, or underlying index symbol.
Expand All @@ -32,6 +38,7 @@ Fetches a current option chain from Market Data.
- "side" - Call or put.
- "strike" - The option's strike price.
- "first traded" - The date this option first began to trade.
- "dte" - Days to expiration: the calendar days until the option expires, counted from today on a current quote and from the quote date on a historical one.
- "date", "updated" - The date and time of the quote.
- "bid" – The bid price of the option.
- "bid size" – The quantity of contracts offered at the bid price.
Expand All @@ -55,7 +62,8 @@ Fetches a current option chain from Market Data.
- **expiration date** - _(OPTIONAL)_ - The expiration date of the option chain. Options from this expiration will be returned. If no value is specified, the next monthly expiration will be used.
- "date" - A single date in YYYY-MM-DD or MM/DD/YYYY format enclosed between quotes.
- \[date cell reference] - A cell reference to a date in Sheets.
- "dte _number_" - Days to expiry. Return the expiration date most closely matching the indicated number. For example, if today was Jan 1 and you used a DTE of 45, the expiration closest to Feb 15 would be selected.
- "dte _number_" - Days to expiry. Return the expiration date most closely matching the indicated number. For example, if today was Jan 1 and you used a DTE of 45, the expiration closest to Feb 15 would be selected. With an **as of** date, the days are counted from that date instead of today.
- The expiration date is always the contract's expiration, never the quote date. To see a chain as it was on a past day, use **as of**.
- **strikes** _(OPTIONAL)_ – Limit the strikes returned from the option chain formula to only the specified strikes or deltas. The formula will assume strikes for numbers greater than 1 and deltas for numbers less than 1 or when the word `delta` is placed before the number(s).
- \[number] - A single number or a cell reference to a number. Example: `150`
- \[decimal] - A decimal number will be interpreted as a delta value to be matched and the formula will return the strike that most closely matches the delta provided. Example: `.60`
Expand All @@ -68,18 +76,26 @@ Fetches a current option chain from Market Data.
- "string of decimals" - Seperate multiple deltas with commas. Example: `".50,.60.,70"`
- "logical expression" - A logical expression. Example: `"<200 delta <.50"`
- "limit \[number]" - Limit the output to \[number] strikes closest to the money. Example: `"limit 4"`
- Deltas are only available for current chains. Selecting strikes by delta together with an **as of** date returns an error; use strikes instead.
- **filters** _(OPTIONAL)_ – Use specific keywords to further filter the option chain.
- "call", "calls" - Only return calls.
- "put", "puts" - Only return puts.
- "itm", "in the money" - Only return in the money options.
- "otm", "out of the money" - Only return out of the money options.
- "nonstandard", "non-standard" - Include non-standard contracts in the optionchain output.
- **as of** _(OPTIONAL)_ – The quote date. Leave it out for the current chain, or give one past trading day to get that day's end-of-day chain. See [Working With Historical Chains](#working-with-historical-chains).
- _(omitted)_ or "current" - The current chain, the same as a formula without this parameter.
- "date" - A single date in YYYY-MM-DD or MM/DD/YYYY format enclosed between quotes.
- \[date cell reference] - A cell reference to a date in Sheets.
- "last session" - The most recent trading day whose end-of-day chain has been published.
- "yesterday", "today" - The calendar day before today, or today. On a weekend or holiday these return an error, so "last session" is usually the better choice.
- An empty cell or `""` returns an error, not the current chain. To switch a sheet between current and historical chains with one cell, write "current" in it.

## Usage Information

### Data Availability

The `OPTIONCHAIN` function fetches current option chain data. The type of data you receive depends on your user type and OPRA entitlement. This may include real-time data, 15-minute delayed data, or historical data, depending on the plan or access level. To get real-time options data, users need to sign the OPRA agreement.
Without an **as of** date, the `OPTIONCHAIN` function fetches current option chain data. The type of data you receive depends on your user type and OPRA entitlement. This may include real-time data, 15-minute delayed data, or historical data, depending on the plan or access level. To get real-time options data, users need to sign the OPRA agreement.

| User Type | OPRA Entitlement | Data Type |
|------------------|------------------|------------------------|
Expand All @@ -89,6 +105,17 @@ The `OPTIONCHAIN` function fetches current option chain data. The type of data y
| Professional | ❌ | Historical (1 day old) |
| Unknown | Any | Historical (1 day old) |

### Working With Historical Chains

With an **as of** date, `OPTIONCHAIN` returns the chain as it closed on that trading day.

- Only end-of-day chains are available. There are no intraday snapshots, and only one date per formula.
- The columns are the same as for a current chain. Implied volatility and the greeks (delta, gamma, theta, vega) are blank, and selecting strikes by delta is not available.
- Open interest is the figure settled out of the previous session, as described under the "open interest" attribute.
- A date in the future, a weekend or a market holiday returns an error. Today's chain returns a "not available yet" error until the end-of-day chain is published after the close.
- A relative date such as "last session" is resolved when the formula calculates. It updates when the sheet is refreshed or a referenced cell changes, not on its own as days pass.
- Historical data is subject to your plan's limits. [Learn more about plan limits](/account/plan-limits).

:::info[What are entitlements?]
Entitlements are permissions granted by exchanges that allow access to their data. To get real-time options data, users need to sign the [OPRA agreement](/account/entitlements). [Learn more about entitlements](/account/entitlements).
:::
Expand Down
Loading
Loading