Is 30% IV High? It Depends on the Ticker
Is 30% implied volatility high? It depends entirely on the ticker. See where 30% IV sits in each name's own percentile, and the daily move it implies.
Is 30% IV high? On its own, that number cannot be answered. Thirty percent implied volatility is high for an index ETF, high for a steady consumer staple, close to ordinary for a mega-cap technology stock, and low for a crypto-linked name. A volatility quote becomes information only once you place it inside the distribution of that same ticker's own past readings, which is what the four panels below do for eight familiar symbols.
What does 30% implied volatility actually mean?
Implied volatility, IV, is the annualized one standard deviation move that an option's price implies for the stock underneath it over the life of that contract. It is always quoted per year, even on a contract with three weeks left. That annualized framing is where the confusion starts, and converting it is the most useful habit in reading an option chain.
A US equity year holds about 252 trading sessions, and volatility scales with the square root of time. Divide the annual figure by the square root of 252, roughly 15.9, and you have a one day figure. Thirty percent annualized comes out near 1.9% a day. On the bell-curve assumption the quote rests on, about two sessions in three land inside that band, and one in three lands outside it.
The same arithmetic rescales the whole screen. Fifteen percent is close to 0.9% a day. A triple-digit 100% reading is about 6.3%, a stock that can plausibly travel a sixteenth of its value between one close and the next. For a monthly horizon, divide by the square root of 12 instead: 30% annualized is roughly an 8.7% move over a month. What implied volatility is covers where the number comes from before you rescale it.
Is 30% IV high? Where it sits in each ticker's own range
The panel below takes every near-the-money contract with 20 to 45 days left to expiry over the past two years, averages the implied volatility across those contracts on each session, then asks one question of each ticker: what share of its own sessions printed under 30%?
The exact SQL behind every number
WITH atm AS (
SELECT underlying_symbol AS symbol,
date,
avg(implied_volatility) * 100 AS iv_pct
FROM global_markets.options_greeks
WHERE underlying_symbol IN ('SPY', 'KO', 'AAPL', 'MSFT', 'NVDA', 'TSLA', 'COIN', 'MSTR')
AND date >= toDate('2024-08-01')
AND date <= toDate('2026-07-31')
AND iv_converged = 1
AND volume > 0
AND underlying_close > 0
AND days_to_expiry BETWEEN 20 AND 45
AND abs(toFloat64(strike_price) / toFloat64(underlying_close) - 1) < 0.05
GROUP BY symbol, date
)
SELECT symbol,
count() AS sample_size,
round(quantileDeterministic(0.1)(iv_pct, cityHash64(toString(date))), 1) AS p10_iv_pct,
round(quantileDeterministic(0.5)(iv_pct, cityHash64(toString(date))), 1) AS median_iv_pct,
round(quantileDeterministic(0.9)(iv_pct, cityHash64(toString(date))), 1) AS p90_iv_pct,
round(100 * countIf(iv_pct < 30) / count(), 1) AS pct_of_days_below_30
FROM atm
GROUP BY symbol
HAVING count() >= 100
ORDER BY median_iv_pctThe median session runs from 15.3% for SPY at the calm end of the panel to 75.7% for MSTR at the loud end. Between the tenth and ninetieth percentile of its own sessions, SPY covered 13% to 20.3%, while MSTR covered 53.8% to 104.6%. Two different worlds, wearing the same units.
The last column answers the title directly. SPY spent 99% of its sessions under 30%, and MSTR spent 0%. Same threshold, opposite verdict, no contradiction.
One relationship in that panel holds well beyond the sample window. An index ETF prices under the typical single stock it holds, and the mechanism is arithmetic rather than mood: the members of a basket move in different directions on any given day, their moves partially cancel whenever they are less than perfectly correlated, and what survives the cancellation is smaller than the average member's volatility. SPY implied volatility tracks that series on its own page.
What is IV rank, and what is IV percentile?
Both statistics answer the calibration question with one number, and they measure different things.
IV rank places today's reading inside the past year's high-to-low range: current IV minus the 52-week low, divided by the 52-week high minus that low, times 100. A rank of 0 matches the quietest reading of the year. A rank of 100 matches the loudest.
IV percentile counts sessions instead. It is the share of the past year's sessions that printed a lower reading than today's. A percentile of 80 means four sessions in five were quieter than this one.
The gap between them opens around single spikes. One panic week can lift the 52-week high so far above everything else that IV rank reads in the teens for months afterwards, while IV percentile, which counts only how many days were lower, sits far higher.
The exact SQL behind every number
WITH atm AS (
SELECT underlying_symbol AS symbol,
date,
avg(implied_volatility) * 100 AS iv_pct
FROM global_markets.options_greeks
WHERE underlying_symbol IN ('SPY', 'KO', 'AAPL', 'MSFT', 'NVDA', 'TSLA', 'COIN', 'MSTR')
AND date >= toDate('2025-08-01')
AND date <= toDate('2026-07-31')
AND iv_converged = 1
AND volume > 0
AND underlying_close > 0
AND days_to_expiry BETWEEN 20 AND 45
AND abs(toFloat64(strike_price) / toFloat64(underlying_close) - 1) < 0.05
GROUP BY symbol, date
),
latest AS (
SELECT symbol,
argMax(iv_pct, date) AS latest_iv
FROM atm
GROUP BY symbol
)
SELECT a.symbol AS symbol,
round(any(l.latest_iv), 1) AS latest_iv_pct,
round(min(a.iv_pct), 1) AS low_52w_iv_pct,
round(max(a.iv_pct), 1) AS high_52w_iv_pct,
round(100 * (any(l.latest_iv) - min(a.iv_pct)) / (max(a.iv_pct) - min(a.iv_pct)), 1) AS iv_rank,
round(100 * countIf(a.iv_pct < l.latest_iv) / count(), 1) AS iv_percentile
FROM atm AS a
INNER JOIN latest AS l ON a.symbol = l.symbol
GROUP BY a.symbol
HAVING max(a.iv_pct) > min(a.iv_pct) AND count() >= 100
ORDER BY iv_rank DESCAAPL tops the panel on rank. Its latest session printed 45.9% inside a 52-week range of 19% to 45.9%, an IV rank of 100 beside an IV percentile of 99.6. At the bottom of the same panel, SPY printed 14.6% inside a 12.3% to 26.3% range, for a rank of 16.7 and a percentile of 40.8.
Neither of those last two columns carries a unit, and that is their advantage: a position statistic puts a utility and a crypto proxy on one axis. The highest IV rank stocks screen ranks the whole market that way.
How far does implied volatility travel over two years?
A ticker's own normal is not fixed either. The monthly medians below cover the index ETF, a low-volatility consumer staple, and a high-beta chip name across the same window.
The exact SQL behind every number
WITH atm AS (
SELECT underlying_symbol AS symbol,
date,
avg(implied_volatility) * 100 AS iv_pct
FROM global_markets.options_greeks
WHERE underlying_symbol IN ('SPY', 'KO', 'NVDA')
AND date >= toDate('2024-08-01')
AND date <= toDate('2026-07-31')
AND iv_converged = 1
AND volume > 0
AND underlying_close > 0
AND days_to_expiry BETWEEN 20 AND 45
AND abs(toFloat64(strike_price) / toFloat64(underlying_close) - 1) < 0.05
GROUP BY symbol, date
)
SELECT formatDateTime(toStartOfMonth(date), '%Y-%m') AS month,
formatDateTimeInJodaSyntax(toStartOfMonth(date), 'MMM yyyy') AS month_label,
round(quantileDeterministicIf(0.5)(iv_pct, cityHash64(toString(date)), symbol = 'SPY'), 1) AS spy_iv_pct,
round(quantileDeterministicIf(0.5)(iv_pct, cityHash64(toString(date)), symbol = 'KO'), 1) AS ko_iv_pct,
round(quantileDeterministicIf(0.5)(iv_pct, cityHash64(toString(date)), symbol = 'NVDA'), 1) AS nvda_iv_pct
FROM atm
GROUP BY toStartOfMonth(date)
HAVING countIf(symbol = 'SPY') > 0
AND countIf(symbol = 'KO') > 0
AND countIf(symbol = 'NVDA') > 0
ORDER BY toStartOfMonth(date)SPY's monthly median opened the window at 14.6% in Aug 2024 and closed it at 14.6% in Jul 2026. KO printed 13.8% and 22.5% in those same two months, NVDA 68.4% and 41.6%.
Trace the SPY line across all 24 months. It runs under the NVDA line in every one of them, which is the basket arithmetic drawn as a picture. The single-name lines also carry a sawtooth the index line lacks. Implied volatility on one stock firms into a scheduled earnings date and drops the morning after the report, the mechanic covered in IV crush.
Does a higher reading precede a bigger move?
The conversion at the top of this page is a claim about the next session, and it is testable. The panel below groups every symbol-session in the sample by the reading it printed, converts each band's average reading to a one day figure, and sets that beside what the underlying actually did on the following session.
The exact SQL behind every number
WITH atm AS (
SELECT underlying_symbol AS symbol,
date,
avg(implied_volatility) * 100 AS iv_pct
FROM global_markets.options_greeks
WHERE underlying_symbol IN ('SPY', 'KO', 'AAPL', 'MSFT', 'NVDA', 'TSLA', 'COIN', 'MSTR')
AND date >= toDate('2024-08-01')
AND date <= toDate('2026-07-30')
AND iv_converged = 1
AND volume > 0
AND underlying_close > 0
AND days_to_expiry BETWEEN 20 AND 45
AND abs(toFloat64(strike_price) / toFloat64(underlying_close) - 1) < 0.05
GROUP BY symbol, date
),
px AS (
SELECT underlying_symbol AS symbol,
date,
any(toFloat64(underlying_close)) AS close
FROM global_markets.options_greeks
WHERE underlying_symbol IN ('SPY', 'KO', 'AAPL', 'MSFT', 'NVDA', 'TSLA', 'COIN', 'MSTR')
AND date >= toDate('2024-08-01')
AND date <= toDate('2026-07-31')
AND iv_converged = 1
AND underlying_close > 0
GROUP BY symbol, date
),
nxt AS (
SELECT symbol,
date,
close,
leadInFrame(close) OVER (PARTITION BY symbol ORDER BY date ASC
ROWS BETWEEN CURRENT ROW AND 1 FOLLOWING) AS next_close
FROM px
)
SELECT multiIf(a.iv_pct < 20, 'under 20%',
a.iv_pct < 30, '20 to 30%',
a.iv_pct < 45, '30 to 45%',
a.iv_pct < 70, '45 to 70%',
'70% and up') AS iv_band,
count() AS sample_size,
round(avg(a.iv_pct) / sqrt(252), 2) AS implied_daily_move_pct,
round(quantileDeterministic(0.5)(100 * abs(n.next_close / n.close - 1),
cityHash64(concat(a.symbol, toString(a.date)))), 2) AS median_next_move_pct,
round(quantileDeterministic(0.9)(100 * abs(n.next_close / n.close - 1),
cityHash64(concat(a.symbol, toString(a.date)))), 2) AS p90_next_move_pct
FROM atm AS a
INNER JOIN nxt AS n ON a.symbol = n.symbol AND a.date = n.date
WHERE n.next_close > 0
GROUP BY iv_band
HAVING count() >= 50
ORDER BY min(a.iv_pct)Sessions in the under 20% band carried a median next-day move of 0.53%. Sessions in the 70% and up band carried 3.3%. The implied column beside them is each band's own average reading divided by the square root of 252, and it climbs across the bands alongside the realized column.
The implied figure sits above the median realized move at most bands, and the shape of the statistic accounts for much of that gap. A median is not a standard deviation, and by construction half of all sessions land below the median. The ninetieth-percentile column shows the other tail: 9.15% in the 70% and up band, against 1.5% in the under 20% band.
What this page does not decide
Calibration and judgment are separate jobs. Knowing that a reading sits near the top of its own year tells you where the number is, and nothing about whether the option is worth its price to a buyer or a seller. That second question has its own page: is high implied volatility good handles the buy-side and sell-side reading of the same statistic. Nothing here is a recommendation about any ticker or any contract.
Implied volatility FAQ
Is 30% IV high for SPY?
For a broad index ETF, 30% is a high reading. SPY's monthly median implied volatility opened the two-year window at 14.6% and closed it at 14.6%, and index readings sit under the typical single name inside the basket by construction. Read the same threshold against whichever symbol you are looking at, never against the market in general.
What daily move does 30% implied volatility imply?
About 1.9%. Divide the annualized figure by the square root of 252 trading sessions, roughly 15.9, for a one day standard deviation. Around one session in three lands outside that band, which is the part most readers underestimate.
Is IV rank the same as IV percentile?
No. IV rank measures where today sits inside the past year's high-to-low range, and one extreme spike sets that range for a full year. IV percentile counts the share of sessions that printed lower, which makes it insensitive to a single outlier and a better description of the typical session.
Why is index implied volatility lower than single-stock implied volatility?
An index is a basket. Its members move in different directions on the same day, and those moves partially cancel whenever the members are less than perfectly correlated. What survives the cancellation is smaller than the average member's volatility. An index ETF and one of its own holdings do not belong on the same scale.
Every panel here is a stored query with its SQL attached underneath. Open one, swap the ticker list, and rerun it on the Strasmore terminal to build the same distribution for the symbol you actually follow.