Equity vs Index Put/Call Ratio: What's High?
Equity and index put/call ratios have different normal ranges. See how each is built, why the index number runs higher, and what a fair comparison needs.
A high put/call ratio is not one number. At least three are published off the same options tape. One counts single-stock options only. One counts index products only. The third blends both. Each has its own normal range, which is why a reading of 1.20 can be an outlier in one series and an ordinary session in another. If the measure itself is new, what the put/call ratio measures covers the basics.
Why does the index put/call ratio run higher than the equity ratio?
Start with who is buying. An index put is the cheapest single instrument that covers an entire diversified book. A fund holding four hundred positions does not buy four hundred separate puts. It buys puts on the index, rolls them on a calendar, and books the premium as an insurance cost. That volume is protection on shares the fund already owns, and it arrives whether the manager is optimistic or not.
Single-stock options carry a different mix. Much of the volume is call buying on individual names, and covered-call writing adds more call volume on the other side. Put buying on single names is real, and it sits next to a much larger call flow.
The formula cannot tell those flows apart. Divide a hedging-heavy put flow by a thin call flow and the quotient lands near or above 1.00. Divide a modest put flow by a thick call flow and it lands near 0.50. One formula, two normal ranges.
The panel below counts contract volume over the trailing sixty sessions for eight household stocks and four broad-market ETFs, then divides put volume by call volume for each underlying.
The exact SQL behind every number
SELECT
underlying_symbol AS symbol,
if(underlying_symbol IN ('SPY', 'QQQ', 'IWM', 'DIA'),
'broad-market ETF',
'single stock') AS bucket,
round(sumIf(volume, startsWith(lower(option_type), 'p'))
/ sumIf(volume, startsWith(lower(option_type), 'c')), 2) AS put_call_ratio,
round(sumIf(volume, startsWith(lower(option_type), 'c')) / 1e6, 1) AS call_volume_millions,
round(sumIf(volume, startsWith(lower(option_type), 'p')) / 1e6, 1) AS put_volume_millions
FROM global_markets.options_greeks
WHERE date >= (SELECT toDate(max(date))
FROM global_markets.options_greeks
WHERE volume > 0) - 60
AND volume > 0
AND underlying_symbol IN ('AAPL', 'MSFT', 'NVDA', 'AMZN', 'TSLA', 'JPM', 'KO', 'JNJ',
'SPY', 'QQQ', 'IWM', 'DIA')
GROUP BY symbol
HAVING sumIf(volume, startsWith(lower(option_type), 'c')) > 0
ORDER BY put_call_ratio ASCThe spread across the sample is wide. The lowest reading is 0.43 on MSFT, and the highest is 2.86 on IWM, which traded 9.6 million call contracts over the window. The bucket column marks which rows are single stocks and which are broad-market ETFs. Read the ratio column against it.
One caveat before going further. A published index ratio uses options on the index level itself, cash settled at expiration rather than delivering shares. Mini index options are the smaller-notional version of that contract. The panels here use broad-market ETF options as the per-underlying stand-in for the same hedging flow, which is the exact place vendors disagree.
What does each published ratio count?
- Equity-only: options on shares of individual companies, the single-name flow, call heavy in most sessions.
- Index-only: options on an index level, cash settled, carrying most of the portfolio-hedging volume.
- Total: every contract in both buckets, put volume over call volume.
All three count volume, meaning contracts changing hands during the session rather than positions still open afterward. Volume versus open interest separates those two ideas.
Is the total put/call ratio an average of the other two?
No. The total is a weighted blend, and the weight is call volume. Write w for the index bucket's share of call volume across both buckets. The total equals the equity ratio plus w times the distance between the two ratios. When the index bucket is a sliver of call volume, the total sits almost on top of the equity ratio. When it dominates, the total climbs toward the index ratio.
The next panel freezes both components at their measured sixty-session levels and sweeps w from zero to one hundred percent.
The exact SQL behind every number
WITH components AS
(
SELECT
round(sumIf(volume, startsWith(lower(option_type), 'p') AND underlying_symbol NOT IN ('SPY', 'QQQ', 'IWM', 'DIA'))
/ sumIf(volume, startsWith(lower(option_type), 'c') AND underlying_symbol NOT IN ('SPY', 'QQQ', 'IWM', 'DIA')), 3) AS equity_ratio,
round(sumIf(volume, startsWith(lower(option_type), 'p') AND underlying_symbol IN ('SPY', 'QQQ', 'IWM', 'DIA'))
/ sumIf(volume, startsWith(lower(option_type), 'c') AND underlying_symbol IN ('SPY', 'QQQ', 'IWM', 'DIA')), 3) AS index_ratio
FROM global_markets.options_greeks
WHERE date >= (SELECT toDate(max(date))
FROM global_markets.options_greeks
WHERE volume > 0) - 60
AND volume > 0
AND underlying_symbol IN ('AAPL', 'MSFT', 'NVDA', 'AMZN', 'TSLA', 'JPM', 'KO', 'JNJ',
'SPY', 'QQQ', 'IWM', 'DIA')
HAVING sumIf(volume, startsWith(lower(option_type), 'c') AND underlying_symbol IN ('SPY', 'QQQ', 'IWM', 'DIA')) > 0
AND sumIf(volume, startsWith(lower(option_type), 'c') AND underlying_symbol NOT IN ('SPY', 'QQQ', 'IWM', 'DIA')) > 0
)
SELECT
concat(toString(step * 10), '%') AS index_share_of_call_volume,
equity_ratio,
index_ratio,
round(equity_ratio + (index_ratio - equity_ratio) * (step / 10), 3) AS blended_total_ratio
FROM
(
SELECT
equity_ratio,
index_ratio,
arrayJoin(range(11)) AS step
FROM components
)
ORDER BY stepWith the components fixed at 0.562 and 1.396, the blend reads 0.562 when the index bucket contributes none of the call volume and 1.396 when it contributes all of it. At an even split, 50% of call volume in the index bucket, the total prints 0.979. Neither component changed across those eleven rows. Only the mix did.
Can the total ratio rise while both parts fall?
It can, and that is the trap in a single headline number. Here is a hypothetical pair of sessions with round numbers, picked for the arithmetic.
Day one: the equity bucket trades 1,000,000 calls and 600,000 puts, a ratio of 0.60. The index bucket trades 200,000 calls and 280,000 puts, a ratio of 1.40. The total is 880,000 puts over 1,200,000 calls, or 0.73.
Day two: both ratios fall. Equity prints 0.55 on 600,000 calls and 330,000 puts. Index prints 1.30 on 800,000 calls and 1,040,000 puts. The total is 1,370,000 over 1,400,000, or 0.98.
Both components fell. The total rose by a quarter of a point. The one other thing that moved was the share of call volume sitting in the higher-ratio bucket, which went from 17 percent to 57 percent. A reader watching the total alone would record a jump in put activity that neither bucket experienced.
That share is not a constant in live data. The panel below tracks both bucket ratios and the ETF bucket's share of call volume, session by session.
The exact SQL behind every number
SELECT
toString(date) AS session_date,
formatDateTime(date, '%b %e') AS session_label,
round(sumIf(volume, startsWith(lower(option_type), 'p') AND underlying_symbol NOT IN ('SPY', 'QQQ', 'IWM', 'DIA'))
/ sumIf(volume, startsWith(lower(option_type), 'c') AND underlying_symbol NOT IN ('SPY', 'QQQ', 'IWM', 'DIA')), 2) AS equity_ratio,
round(sumIf(volume, startsWith(lower(option_type), 'p') AND underlying_symbol IN ('SPY', 'QQQ', 'IWM', 'DIA'))
/ sumIf(volume, startsWith(lower(option_type), 'c') AND underlying_symbol IN ('SPY', 'QQQ', 'IWM', 'DIA')), 2) AS index_style_ratio,
round(index_style_ratio - equity_ratio, 2) AS ratio_gap,
round(100 * sumIf(volume, startsWith(lower(option_type), 'c') AND underlying_symbol IN ('SPY', 'QQQ', 'IWM', 'DIA'))
/ sumIf(volume, startsWith(lower(option_type), 'c')), 1) AS etf_share_of_calls_pct
FROM global_markets.options_greeks
WHERE date >= (SELECT toDate(max(date))
FROM global_markets.options_greeks
WHERE volume > 0) - 45
AND volume > 0
AND underlying_symbol IN ('AAPL', 'MSFT', 'NVDA', 'AMZN', 'TSLA', 'JPM', 'KO', 'JNJ',
'SPY', 'QQQ', 'IWM', 'DIA')
GROUP BY date
HAVING sumIf(volume, startsWith(lower(option_type), 'c') AND underlying_symbol IN ('SPY', 'QQQ', 'IWM', 'DIA')) > 0
AND sumIf(volume, startsWith(lower(option_type), 'c') AND underlying_symbol NOT IN ('SPY', 'QQQ', 'IWM', 'DIA')) > 0
ORDER BY dateOn Jun 29, the earliest session in view, the single-stock bucket printed 0.5 against 1.55 for the ETF bucket, a gap of 1.05, with 45.2 percent of call volume in the ETF bucket. On Aug 12 those columns read 0.55, 1.34 and a gap of 0.79, with the ETF share at 49.5 percent. The gap column is positive at both ends of the 32 sessions on display, and the share column moves underneath it.
Why do two sources print different put/call ratios for the same day?
Bucketing, and ETF options are the ambiguous case. An ETF is a listed security, which argues for the equity bucket. It also tracks an index, which argues for the index bucket. Publishers resolve that differently: some fold ETF options into the equity ratio, some report exchange traded products as a separate series, some group them with index products. The label on the chart reads the same in every case.
The size of that choice is measurable. The panel below computes one bucket's ratio twice over the same sessions, once with ETF options left out and once with them counted in.
The exact SQL behind every number
SELECT
toString(date) AS session_date,
formatDateTime(date, '%b %e') AS session_label,
round(sumIf(volume, startsWith(lower(option_type), 'p') AND underlying_symbol NOT IN ('SPY', 'QQQ', 'IWM', 'DIA'))
/ sumIf(volume, startsWith(lower(option_type), 'c') AND underlying_symbol NOT IN ('SPY', 'QQQ', 'IWM', 'DIA')), 2) AS equity_ratio_etfs_excluded,
round(sumIf(volume, startsWith(lower(option_type), 'p'))
/ sumIf(volume, startsWith(lower(option_type), 'c')), 2) AS equity_ratio_etfs_included
FROM global_markets.options_greeks
WHERE date >= (SELECT toDate(max(date))
FROM global_markets.options_greeks
WHERE volume > 0) - 30
AND volume > 0
AND underlying_symbol IN ('AAPL', 'MSFT', 'NVDA', 'AMZN', 'TSLA', 'JPM', 'KO', 'JNJ',
'SPY', 'QQQ', 'IWM', 'DIA')
GROUP BY date
HAVING sumIf(volume, startsWith(lower(option_type), 'c') AND underlying_symbol NOT IN ('SPY', 'QQQ', 'IWM', 'DIA')) > 0
ORDER BY dateOn Aug 12, the last session in the panel, the single-stock-only figure was 0.55 and the version with ETF options folded in was 0.94. Same day, same tape, same words on the axis. A threshold learned from one publisher's series does not carry over to another's.
What counts as a high put/call ratio, then?
The workable rule is narrow. Compare a ratio only against its own history, from the same source and the same construction. A percentile answers that question: where does today's reading sit within the last year of that exact series? A fixed line at 1.00 does not, since 1.00 is an extreme print in an equity series and a routine one in an index series.
Two habits keep the comparison honest. Read the construction note before quoting a level, ETF handling above all. And read the components alongside the total, since the total can move on mix alone. Whether a high put/call ratio is bullish takes the interpretation further, and how the put/call ratio is calculated walks the arithmetic step by step.
Data notes and bucket definitions
The ETF bucket is SPY, QQQ, IWM and DIA. The single-stock bucket is AAPL, MSFT, NVDA, AMZN, TSLA, JPM, KO and JNJ. Both are samples of their category rather than the whole market, so the levels here illustrate the split without reproducing any publisher's headline number.
Every panel sums contract volume for the session, calls and puts separately, then divides. There is no dollar or premium weighting.
Each window is anchored to the most recent session with recorded volume rather than to the calendar day, and the put and call sides are matched on the first letter of the contract type so a feed that writes P and C rather than put and call still buckets correctly.
A contract counts whenever the session recorded volume for it, deep out-of-the-money strikes included. Far strikes carry a large share of hedging put volume, and dropping them would understate the ETF bucket.
Options on an index level, cash settled and European exercise, are a different product from ETF options. The per-underlying panels use ETF options as the stand-in for index hedging flow, which is the bucketing question raised above.
The most recent session or two can be absent at the front edge while the day's records land.
FAQ
What is a normal put/call ratio for equity options?
Single-stock options usually print below 1.00, with call volume the larger side in most sessions. Across the twelve names in the trailing-sixty-session panel above, the lowest reading was 0.43. Normal for any one series is set by that series' own history rather than by a shared threshold.
Why is the index put/call ratio usually above 1?
Index puts are the standard portfolio hedge, and that buying arrives on a schedule from managers who already hold the shares. The hedging volume lands on the put side of the same fraction a directional trade would use, and the series sits at a higher level across its whole record.
Which put/call ratio do sentiment charts usually show?
Most published charts show either the total or the equity-only series, and the axis label rarely says which. Check the construction note before measuring a chart against a threshold quoted somewhere else, since the series run at different levels.
Can I compare put/call ratios from two different providers?
Levels do not transfer. Providers differ on ETF handling and on which exchanges' volume is counted. Direction and percentile rank within one provider's own series are the parts of the comparison that survive.
Every panel here ships with the SQL that produced it, so any of these splits can be rebuilt with a different universe or window. Ask the same question in plain English on the Strasmore terminal.