How Dem Calculate Put/Call Ratio
See how dem calculate put/call ratio with volume and open interest formulas, why index readings dey higher, and wetin count as normal reading for 2026.
Put/call ratio dey come from dividing number of put contracts wey traders trade by number of call contracts wey dem trade for the same period. If 250,000 puts and 500,000 calls change hands for one session, the ratio na 0.50. Every argument about the indicator, volume versus open interest, and equity versus index, dey go back to wetin dem count for each side of that division. For the simple definition, start with wetin put/call ratio be. This page do the arithmetic.
Put/call ratio formula, step by step
The formula get two inputs and one operation: count the puts wey trade, count the calls wey trade, then divide the first one by the second one. Put na contract wey give owner the right to sell 100 shares of the underlying at fixed strike price on or before expiry. Call give the right to buy at fixed strike. Volume count the contracts wey change hand during the session, and e reset to zero when market open next time.
Nothing for the count get weighting. One lot for far out of the money weekly count the same as one lot for the busiest strike for the board, and dem no scale either one by the money wey dey at risk. The ratio na contract count.
The choice wey change the answer na which contracts dem count. The panel below run the same arithmetic across eight liquid names for one full month.
The exact SQL behind every number
SELECT
underlying_symbol AS symbol,
sumIf(volume, right_letter = 'P') AS put_volume,
sumIf(volume, right_letter = 'C') AS call_volume,
round(toFloat64(sumIf(volume, right_letter = 'P'))
/ toFloat64(sumIf(volume, right_letter = 'C')), 2) AS put_call_ratio
FROM
(
SELECT
underlying_symbol,
volume,
substring(ticker, length(ticker) - 8, 1) AS right_letter
FROM global_markets.options_greeks
WHERE date >= '2026-07-01'
AND date < '2026-08-01'
AND underlying_symbol IN ('SPY', 'QQQ', 'IWM', 'AAPL', 'MSFT', 'NVDA', 'TSLA', 'KO')
AND volume > 0
)
GROUP BY symbol
HAVING call_volume > 0 AND put_volume > 0
ORDER BY put_call_ratio DESCFor July 2026, IWM carry the highest ratio among the eight, at 3.11 puts per call, while MSFT get the lowest at 0.38. Na one formula and one month, but the gap between the top and bottom name wide pass the day-to-day movement wey people dey write about. Ratio wey dem quote without attaching the category get almost no information.
Volume based or open interest based
Two different counts fit fill the numerator and denominator.
The volume version dey count contracts wey traders trade inside the window. Na flow measure wey start from zero every session, and e describe wetin people do today. Every headline ratio for market coverage na this one.
The open interest version dey divide puts wey still dey outstanding by calls wey still dey outstanding. Open interest na the number of contracts wey people open but never close, exercise, or allow expire. Na stock measure be this: accumulated position, no be activity for the day. E dey move slowly. If 30,000 puts change hands between two existing holders during one session, volume go increase by 30,000, but open interest go remain flat. Options volume versus open interest explain the bookkeeping.
Make we use hypothetical name wey finish Tuesday with 40,000 puts and 50,000 calls outstanding. The open interest ratio na 0.80. On Wednesday, traders trade 30,000 puts and 10,000 calls, giving volume ratio of 3.00. Both numbers dey describe the same option chain for the same day. Dem differ by almost four times, and both correct. Open interest ratios still dey under the max pain calculation, wey dey weight strikes by contracts outstanding, no be by contracts traded.
Flow measures dey jump around. Below na the daily volume ratio for one ETF and one single stock across the same month.
The exact SQL behind every number
SELECT
toString(d) AS session_date,
concat(formatDateTime(d, '%b '), toString(toDayOfMonth(d))) AS day_label,
round(toFloat64(sumIf(volume, sym = 'SPY' AND right_letter = 'P'))
/ toFloat64(sumIf(volume, sym = 'SPY' AND right_letter = 'C')), 2) AS spy_put_call_ratio,
round(toFloat64(sumIf(volume, sym = 'AAPL' AND right_letter = 'P'))
/ toFloat64(sumIf(volume, sym = 'AAPL' AND right_letter = 'C')), 2) AS aapl_put_call_ratio
FROM
(
SELECT
date AS d,
underlying_symbol AS sym,
volume,
substring(ticker, length(ticker) - 8, 1) AS right_letter
FROM global_markets.options_greeks
WHERE date >= '2026-07-01'
AND date < '2026-08-01'
AND underlying_symbol IN ('SPY', 'AAPL')
AND volume > 0
)
GROUP BY d
HAVING countIf(sym = 'SPY' AND right_letter = 'C') > 0
AND countIf(sym = 'AAPL' AND right_letter = 'C') > 0
ORDER BY dFor Jul 1, SPY print 1.1 against 0.49 for AAPL. By Jul 31, the pair read 2 and 0.55. Across 22 sessions, the daily prints dey jump around, and the two series dey sit for different levels on the chart. The gap between the levels na the more useful of the two facts.
Equity, index, ETP and total: Cboe ratios four
The number wey dem quote as “the put/call ratio” come from Cboe daily market statistics, wey dey publish several of dem. Na so Cboe name the categories:
- Equity put/call ratio: options on individual stocks.
- Index put/call ratio: options on indexes, including SPX and VIX.
- Exchange traded products put/call ratio: options on ETFs, where SPY, QQQ and IWM dey.
- Total put/call ratio: all the categories join together.
Dem calculate each one the same way: total puts divide by total calls inside the category. So, na only wetin dey inside each bucket dey make the readings different. The buckets no be interchangeable.
Index options na the standard instrument to hedge whole portfolio with one trade. Fund wey hold broad book of stocks fit buy index puts against am, and e no get matching reason to buy index calls. That demand dey one-sided, and e enter fully inside the numerator of the index category. Single-stock flow get the opposite tilt. Call buying for individual names make up large and persistent part of the volume. The two categories dey different levels because of their structure. Comparing one reading with benchmark from the other category na the most common mistake for this indicator.
Broad market ETFs get the same hedging role as index options, but dem dey count am inside the exchange traded products category. The panel below dey track monthly median for both sides of that split.
The exact SQL behind every number
WITH
daily AS
(
SELECT
d,
toFloat64(sumIf(volume, right_letter = 'P' AND sym IN ('SPY', 'QQQ', 'IWM')))
/ toFloat64(sumIf(volume, right_letter = 'C' AND sym IN ('SPY', 'QQQ', 'IWM'))) AS etf_ratio,
toFloat64(sumIf(volume, right_letter = 'P' AND sym NOT IN ('SPY', 'QQQ', 'IWM')))
/ toFloat64(sumIf(volume, right_letter = 'C' AND sym NOT IN ('SPY', 'QQQ', 'IWM'))) AS stock_ratio
FROM
(
SELECT
date AS d,
underlying_symbol AS sym,
volume,
substring(ticker, length(ticker) - 8, 1) AS right_letter
FROM global_markets.options_greeks
WHERE date >= '2025-08-01'
AND date < '2026-08-01'
AND underlying_symbol IN ('SPY', 'QQQ', 'IWM', 'AAPL', 'MSFT', 'NVDA', 'TSLA', 'KO')
AND volume > 0
)
GROUP BY d
HAVING countIf(right_letter = 'C' AND sym IN ('SPY', 'QQQ', 'IWM')) > 0
AND countIf(right_letter = 'C' AND sym NOT IN ('SPY', 'QQQ', 'IWM')) > 0
)
SELECT
toString(toStartOfMonth(d)) AS month,
formatDateTime(toStartOfMonth(d), '%b %Y') AS month_label,
round(quantileExact(0.5)(etf_ratio), 2) AS etf_median_ratio,
round(quantileExact(0.5)(stock_ratio), 2) AS stock_median_ratio
FROM daily
GROUP BY month, month_label
ORDER BY monthThe panel cover Aug 2025 reach Jul 2026. For both ends, the ETF basket median daily ratio dey near or above 1.0: 1.52 for the first month and 1.49 for the last. The single-stock basket remain below 1.0 for both ends, 0.6 and 0.56, across all 12 months wey the chart show. That steady gap na why benchmark must name its category before e fit mean anything.
Wetin count as normal put/call ratio
Normal na a range, and na the category get that range, no be the indicator. The panel below use every session for the trailing twelve months and show the median daily ratio for each basket, plus the 10th and 90th percentile edges around am.
The exact SQL behind every number
WITH
daily AS
(
SELECT
d,
toFloat64(sumIf(volume, right_letter = 'P' AND sym IN ('SPY', 'QQQ', 'IWM')))
/ toFloat64(sumIf(volume, right_letter = 'C' AND sym IN ('SPY', 'QQQ', 'IWM'))) AS etf_ratio,
toFloat64(sumIf(volume, right_letter = 'P' AND sym NOT IN ('SPY', 'QQQ', 'IWM')))
/ toFloat64(sumIf(volume, right_letter = 'C' AND sym NOT IN ('SPY', 'QQQ', 'IWM'))) AS stock_ratio,
toFloat64(sumIf(volume, right_letter = 'P'))
/ toFloat64(sumIf(volume, right_letter = 'C')) AS all_ratio
FROM
(
SELECT
date AS d,
underlying_symbol AS sym,
volume,
substring(ticker, length(ticker) - 8, 1) AS right_letter
FROM global_markets.options_greeks
WHERE date >= '2025-08-01'
AND date < '2026-08-01'
AND underlying_symbol IN ('SPY', 'QQQ', 'IWM', 'AAPL', 'MSFT', 'NVDA', 'TSLA', 'KO')
AND volume > 0
)
GROUP BY d
HAVING countIf(right_letter = 'C' AND sym IN ('SPY', 'QQQ', 'IWM')) > 0
AND countIf(right_letter = 'C' AND sym NOT IN ('SPY', 'QQQ', 'IWM')) > 0
)
SELECT
p.2 AS category,
round(quantileExact(0.1)(p.3), 2) AS p10_ratio,
round(quantileExact(0.5)(p.3), 2) AS median_ratio,
round(quantileExact(0.9)(p.3), 2) AS p90_ratio
FROM
(
SELECT arrayJoin([
tuple(1, 'Broad market ETFs', etf_ratio),
tuple(2, 'Single stocks', stock_ratio),
tuple(3, 'All eight names', all_ratio)
]) AS p
FROM daily
)
GROUP BY p.1, p.2
ORDER BY p.1For the single stock basket, the median session na 0.58. 0.45 na the 10th percentile, while 0.76 na the 90th percentile. The broad market ETF basket dey higher across the distribution: median of 1.54, between edges of 1.25 and 1.86.
So, 1.20 high? Against the single stock basket, 1.20 print dey above the 90th percentile of 0.76, so e unusual. Against the ETF basket, e close to normal. Against the index category, where the hedging flow we describe above dey concentrate, you need judge the same figure against another set of levels. Na one number, but the category don settle the verdict before interpretation even start.
These ranges dey change too. Percentiles wey you calculate over the trailing twelve months describe only the trailing twelve months. A benchmark range copied from article wey dem write ten years ago describe market wey get different contract mix and almost no zero day expiry trading inside am. Recalculate the percentiles over a recent window na the only honest way to call a reading high or low.
Interpretation na separate work from calculation. Some people read high reading as bearish positioning, while contrarians see am as crowded hedge. Whether a high put/call ratio is bullish explain and properly test that argument.
Why 21-day moving average
Ratio wey come from one session na small sample inside noisy series, so dem normally smooth the published version. Common convention na 21-session moving average, wey roughly be one trading month: add the last 21 daily ratios, divide by 21, then move the window go one session forward. Ten-session and fifty-session versions dey too, and the length wey dem choose determine how much of one-day spike go remain.
Two details worth knowing dey. To average 21 daily ratios no be the same calculation as to divide one month put volume by one month call volume. The first one give every session equal weight. The second one give busy sessions more weight. And when a smoothed reading dey for extreme level, dem build am from one month of sessions, so e go also comot from that extreme slowly.
The exact SQL behind every number
WITH
daily AS
(
SELECT
d,
toFloat64(sumIf(volume, right_letter = 'P'))
/ toFloat64(sumIf(volume, right_letter = 'C')) AS raw_ratio
FROM
(
SELECT
date AS d,
volume,
substring(ticker, length(ticker) - 8, 1) AS right_letter
FROM global_markets.options_greeks
WHERE date >= '2026-01-02'
AND date < '2026-08-01'
AND underlying_symbol IN ('AAPL', 'MSFT', 'NVDA', 'TSLA', 'KO')
AND volume > 0
)
GROUP BY d
HAVING countIf(right_letter = 'C') > 0
)
SELECT
session_date,
day_label,
daily_ratio,
ma21_ratio
FROM
(
SELECT
d,
toString(d) AS session_date,
concat(formatDateTime(d, '%b '), toString(toDayOfMonth(d))) AS day_label,
round(raw_ratio, 2) AS daily_ratio,
round(avg(raw_ratio) OVER (ORDER BY d ROWS BETWEEN 20 PRECEDING AND CURRENT ROW), 2) AS ma21_ratio
FROM daily
)
WHERE d >= '2026-04-01'
ORDER BY dThe jagged line na daily ratio for the single stock basket. The smooth line na the 21-session average. For the first session wey show, Apr 1, daily print na 1.04, while smoothed reading na 0.81. For Jul 31, the two readings na 0.56 and 0.58. Across 84 sessions, the average cover only small part of the distance wey the raw series cover. Na the whole reason why dem dey quote the smoothed number.
How these panels dey count
Contract type come from the option symbol itself: the letter wey dey before the eight-digit strike code na C for call and P for put. Na only contracts wey get reported volume for the session enter the count, so strike wey no trade at all no add anything to either side. The first panel divide the month total put volume by the month total call volume for each name. The other panels first calculate one ratio for each session, then summarize those sessions. Na so published moving average dey build. Baskets: SPY, QQQ and IWM for the broad market side, with AAPL, MSFT, NVDA, TSLA and KO for the single stock side. Every panel carry the exact SQL wey produce am.
FAQ
How dem dey calculate put/call ratio?
Divide number of put contracts by number of call contracts for the same window. Most published versions dey use session volume, so reading of 0.65 mean say 65 puts trade for every 100 calls. Open interest version dey use contracts wey still dey outstanding instead of contracts wey trade, and e dey answer different question.
Put/call ratio wey pass 1 high?
E depend on the category. For the single stock basket wey dey the panels above, 90th percentile of daily readings dey at 0.76, so prints above that level no common. For broad market ETFs and index options, where portfolio hedging dey concentrate for put side, readings around 1 and above dey normal.
Wetin be difference between volume and open interest put/call ratio?
Volume dey count contracts wey trade during the session and e reset every morning. Open interest dey count contracts wey remain open and e carry over from one day to another. Volume version fit double inside one session, while open interest version fit shift by only few percent. So, both fit point for different directions on the same day.
Which put/call ratio financial press dey quote?
Usually na Cboe equity put/call ratio or total put/call ratio. Most times, dem dey quote am as 21 session moving average instead of raw daily print. The four Cboe categories dey trade for different levels, so you no fit measure quoted figure against any benchmark if dem no attach category.
Every panel for this page come with the SQL wey produce am, so you fit check each count line by line. If you wan run the same arithmetic for another name or longer window, ask for am in plain English on the Strasmore terminal.