How to Read an Option Chain, Column by Column
An option chain lists every strike and expiration for one stock. See what the bid, ask, volume, implied volatility and delta columns each measure.
An option chain is the table a broker shows for one underlying stock or fund: every listed expiration, every strike price, and a row of live numbers for the call and the put at each strike. Reading one is a matter of knowing what each column measures and how the two coordinates, expiration and strike, locate a single contract inside the grid. This page walks a real chain column by column, using the S&P 500 tracker SPY on July 15, 2026 as the worked example.
What is an option chain?
Every listed option is defined by four facts: the underlying symbol, the expiration date, the strike price, and whether it is a call or a put. The chain is that definition turned into a layout. A selector at the top picks the expiration. Strikes then run down the middle of the screen, calls occupy the columns on one side and puts the columns on the other. Choose one expiration and you are reading a flat slice of the grid: one row per strike, one set of quote columns per side.
The columns themselves describe that one contract, not the underlying stock. A single underlying can carry dozens of expirations and hundreds of strikes, so the full chain for a heavily traded name runs to thousands of rows. Brokers hide most of them by default and open near the money, the region where the strike sits closest to the current share price.
Reading one expiration, strike by strike
Here is one real slice: SPY calls and puts expiring August 21, 2026, priced at the July 15 close, across the strikes bracketing the share price.
The exact SQL behind every number
SELECT toString(toUInt32(strike_price)) AS strike,
round(any(underlying_close), 2) AS underlying_price,
round(maxIf(option_close, option_type = 'C'), 2) AS call_last,
round(maxIf(option_close, option_type = 'P'), 2) AS put_last,
round(maxIf(delta, option_type = 'C'), 2) AS call_delta,
round(minIf(delta, option_type = 'P'), 2) AS put_delta
FROM global_markets.options_greeks
WHERE underlying_symbol = 'SPY'
AND date = toDate('2026-07-15')
AND expiration_date = toDate('2026-08-21')
AND strike_price BETWEEN 735 AND 770
AND toUInt32(strike_price) % 5 = 0
AND iv_converged
GROUP BY strike_price
HAVING countIf(option_type = 'C') > 0 AND countIf(option_type = 'P') > 0
ORDER BY strike_priceTwo patterns show up immediately. Call prices fall as the strike rises, from $28.82 at the $735 strike to $6.1 at $770: the right to buy at a lower price is worth more. Put prices move the opposite way across the same eight rows, from $6.07 up to $19.16. The two ladders cross near the share price of $754.68, and the strike where the call and the put trade closest together marks the money.
The delta columns describe that geometry in a different unit. Delta is the change in an option's price for a $1 change in the underlying, and it doubles as a rough gauge of how likely a contract is to finish in the money. At the $735 strike the call reads 0.73 and the put reads -0.26. By the $770 strike the call has fallen to 0.34. A call and a put on the same row always carry deltas roughly one apart in magnitude, a property of two contracts covering opposite halves of the same distribution. The rest of these sensitivity columns are covered in the option greeks explained.
The bid, the ask, and why they are not one price
The chain quotes two prices for every contract. The bid is the highest price a buyer is currently willing to pay. The ask is the lowest price a seller will accept. The gap between them is the spread. A market order to buy fills at the ask and a market order to sell fills at the bid, so the spread is a real cost paid at entry and again at exit. The "last" price a chain displays can be minutes old and can sit anywhere relative to the current quote.
Spreads are not uniform down a chain. Below, the median quoted bid and ask for the same expiration across seven call strikes, measured over the regular session on July 15, 2026.
The exact SQL behind every number
SELECT concat('$', toString(toUInt32(toFloat64(toUInt32OrZero(substring(ticker, length(ticker) - 7, 8))) / 1000)), ' call') AS strike,
round(quantileDeterministic(0.5)(toFloat64(bid_price), toUInt64(sip_timestamp)), 2) AS median_bid,
round(quantileDeterministic(0.5)(toFloat64(ask_price), toUInt64(sip_timestamp)), 2) AS median_ask,
round(100 * quantileDeterministic(0.5)(toFloat64(ask_price - bid_price), toUInt64(sip_timestamp)), 1) AS median_spread_cents,
toUInt64(count()) AS quotes_recorded
FROM global_markets.cache_options_quotes
WHERE ticker IN ('O:SPY260821C00740000', 'O:SPY260821C00750000', 'O:SPY260821C00760000',
'O:SPY260821C00770000', 'O:SPY260821C00780000', 'O:SPY260821C00800000',
'O:SPY260821C00820000')
AND sip_timestamp >= '2026-07-15 13:30:00'
AND sip_timestamp < '2026-07-15 20:00:00'
AND bid_price > 0
AND ask_price > bid_price
GROUP BY ticker
ORDER BY toUInt32OrZero(substring(ticker, length(ticker) - 7, 8))The deep in-the-money strike at the top of the panel quoted a median spread of 12 cents against a bid of $24.18. The far out-of-the-money strike at the bottom quoted 1 cent against a bid of $0.12. In absolute terms the cheap contract carries the tighter spread. As a fraction of its own price it is far wider, and that fraction is what a round trip actually costs. The mechanics of the two-sided quote are unpacked in the bid ask spread. The same panel shows the other axis spreads move along: the busy strikes near the money recorded well over a hundred thousand quote updates in the session, the distant ones a few thousand.
Volume and open interest
Two columns count activity, and readers mix them up constantly. Volume counts contracts traded during the current session and resets to zero overnight. Open interest counts contracts still open at the end of the previous session, so it updates once a day and describes accumulated positioning rather than today's flow. A strike can show heavy volume with almost no open interest, which happens when traders open and close inside the same day.
The exact SQL behind every number
SELECT toString(toUInt32(strike_price)) AS strike,
toUInt64(sumIf(volume, option_type = 'C')) AS call_volume,
toUInt64(sumIf(volume, option_type = 'P')) AS put_volume
FROM global_markets.options_greeks
WHERE underlying_symbol = 'SPY'
AND date = toDate('2026-07-15')
AND expiration_date = toDate('2026-08-21')
AND strike_price BETWEEN 735 AND 770
AND toUInt32(strike_price) % 5 = 0
AND iv_converged
GROUP BY strike_price
HAVING countIf(option_type = 'C') > 0 AND countIf(option_type = 'P') > 0
ORDER BY strike_priceVolume clusters. Across these eight strikes the call side ran from 81 contracts at the lowest strike up to 4547 at the highest, and the put side leaned the other way. Round numbers and strikes near the share price take most of the flow, and a strike two or three steps away can carry a small fraction of it. Where a chain row shows a wide spread, thin volume in the same row is usually sitting beside it. Volume versus open interest measures the whole tape on this point.
Implied volatility, strike by strike
The implied volatility column converts a contract's price into an annualized percentage: the volatility figure that would make a pricing model return the quoted price. It is a restatement of price, not a forecast. Contracts on the same underlying and the same expiration routinely carry different implied volatilities at different strikes, and plotting the column against strike draws the shape known as the smile, or the skew.
The exact SQL behind every number
SELECT toString(toUInt32(strike_price)) AS strike,
round(100 * avg(implied_volatility), 1) AS implied_vol_pct,
round(100 * (strike_price / any(underlying_close) - 1), 1) AS strike_vs_spot_pct
FROM global_markets.options_greeks
WHERE underlying_symbol = 'SPY'
AND date = toDate('2026-07-15')
AND expiration_date = toDate('2026-08-21')
AND strike_price BETWEEN 640 AND 840
AND toUInt32(strike_price) % 20 = 0
AND iv_converged
AND implied_volatility BETWEEN 0.02 AND 3
GROUP BY strike_price
ORDER BY strike_priceThe curve is not flat. The lowest strike on the panel sits -15.2% from the share price and priced at 23.6%, the middle of the range sits far lower, and the top strike turns back up to 12.8%. In index options the downside wing typically prices above the upside wing, a persistent asymmetry rather than a daily quirk. Two things follow for anyone reading the column. A single "IV" number quoted for a stock is an average over a surface that is not flat, and comparing implied volatility between two strikes only makes sense once their distance from the share price is on the table. Implied volatility defines the measure and volatility skew maps the shape.
How a same-day chain differs
Chains for contracts expiring the same session, the 0DTE contracts, look like every other chain and behave differently in one respect: everything on them moves faster. Time value drains over hours rather than months, delta swings hard as the share price crosses a strike, and the strike grid is usually finer near the money. The composition of one day's tape shows how much of the activity now sits there.
The exact SQL behind every number
WITH dateDiff('day', toDate('2026-07-15'), toDate(concat('20', substring(ticker, length(ticker) - 14, 2), '-', substring(ticker, length(ticker) - 12, 2), '-', substring(ticker, length(ticker) - 10, 2)))) AS dte
SELECT multiIf(dte = 0, 'same day (0DTE)', dte <= 7, '1-7 days', dte <= 30, '8-30 days',
dte <= 90, '31-90 days', 'over 90 days') AS expires_in,
round(sum(volume) / 1e6, 2) AS contracts_m,
round(100 * toFloat64(sum(volume)) / (SELECT toFloat64(sum(volume))
FROM global_markets.options_minute_aggs
WHERE window_start >= '2026-07-15 00:00:00' AND window_start < '2026-07-16 00:00:00'
AND substring(ticker, 3, length(ticker) - 17) = 'SPY'), 1) AS pct_of_spy_volume,
toUInt64(uniqExact(ticker)) AS distinct_contracts
FROM global_markets.options_minute_aggs
WHERE window_start >= '2026-07-15 00:00:00'
AND window_start < '2026-07-16 00:00:00'
AND substring(ticker, 3, length(ticker) - 17) = 'SPY'
AND dte >= 0
GROUP BY expires_in
ORDER BY min(dte)Contracts expiring that same afternoon took 66.9% of SPY option volume on July 15, 2026, 8.48 million contracts spread over just 170 distinct strikes. Everything dated beyond ninety days accounted for 0.8% of the volume while listing 1502 distinct contracts. That shape is worth carrying into any chain you open: the widest part of the grid holds the least trading, and the narrow same-day slice holds most of it. Zero day options covers that slice on its own terms.
Reading one row end to end
Take the $755 strike from the first panel, with SPY at $754.68. The call last traded at $14.03 and the put at $11.52, the closest pair on the slice, which identifies this as the at-the-money row. The call delta of 0.54 says a $1 move in SPY moves that call about 0.54 dollars, and the put on the same row carries a delta of -0.46 for the same $1 move in the opposite direction.
One contract covers 100 shares, so a chain quoting $14.03 is quoting per share, and the contract costs roughly 100 times that before commissions. The multiplier is the single most common misreading of a chain. Everything else on the row describes the same contract from another angle: the spread is what it costs to transact, the volume is how much company you have, the implied volatility is the volatility assumption embedded in the price. Call options and put options cover the payoff mechanics each row rests on.
FAQ
What do the columns on an option chain mean?
Strike and expiration identify the contract. Bid and ask are the live two-sided quote, last is the most recent trade price, volume counts today's trades, and open interest counts positions still outstanding from prior sessions. Implied volatility restates the price as an annualized percentage, and the greeks columns measure sensitivity to the share price, to time, and to volatility.
What is the difference between volume and open interest?
Volume counts contracts traded during the current session and starts at zero each morning. Open interest counts contracts still open after the previous session settled, so it is one day old and changes only as positions are opened or closed rather than transferred between traders.
Why do two strikes on the same expiration show different implied volatilities?
Options at different strikes cover different parts of the range of possible future prices, and the market prices those parts differently. In the SPY example above, the lowest strike on the panel priced near 23.6% while the middle of the range sat well below it, the curve traders call the smile or the skew.
What does a delta of 0.50 on an option chain mean?
A delta of 0.50 means the contract's price moves about 50 cents for a $1 move in the underlying share price, and it is commonly read as a rough approximation of the chance the contract finishes in the money. Delta sits near 0.50 for calls at the strike closest to the current share price and falls toward zero for distant strikes.
Does an option chain price refer to one share or one contract?
The quoted price is per share. A standard US equity option covers 100 shares, so a contract quoted at $2.00 costs about $200 plus fees. Chains almost never display that multiplier.
Every figure above comes from a stored, versioned query over the options tape. Expand any panel to read the SQL, or pull the same chain yourself on the Strasmore terminal.