STRASMORE/EXPLORE 2,191 QUERIES

spy_put_daily_moves

Answered against 22 years of US equities and 12 years of US options data and published with the query that produced it. This result is stored as of 2026-09-11, from stop-orders-on-options.

as of ranking 4×3read in context →
spy_put_daily_moves — 4 rows by 3 columns, computed from US exchange, SIP and OPRA data.
move_bucketcontract_daysshare_pct
under 5%39616.7
5% to 10%33914.3
10% to 20%59125
20% or more103943.9
Rows × columns
4 × 3
Computed
Completeness
No missing values
Source
US exchange, SIP and OPRA market data
Licence
Strasmore terms · free, no signup
Formats
JSON · CSV · the SQL below

What each column holds

Column definitions for spy_put_daily_moves, derived from the stored result.
ColumnTypeRangeNotes
move_bucket text 4 distinct values (10% to 20%, 20% or more, 5% to 10%…)
contract_days number 339 to 1,039
share_pct number 14.3 to 43.9 percent

Computed from Strasmore's warehouse of US exchange, SIP and OPRA market data. Equity prices are delayed; options greeks and implied volatility are end-of-day. This result is stored, not recomputed on load — it is exactly the numbers that were returned on , and the query below is what returned them.

the exact SQL behind every number
WITH daily AS
(
    SELECT
        ticker,
        date,
        max(toFloat64(option_close))     AS put_close,
        max(toFloat64(underlying_close)) AS spy_close,
        max(toFloat64(strike_price))     AS strike,
        max(days_to_expiry)              AS dte
    FROM global_markets.options_greeks
    WHERE underlying_symbol = 'SPY'
      AND lower(toString(option_type)) IN ('put', 'p')
      AND date >= toDate('2026-06-29')
      AND date <  toDate('2026-08-01')
      AND days_to_expiry BETWEEN 15 AND 50
      AND volume > 0
    GROUP BY ticker, date
),
chained AS
(
    SELECT
        date,
        put_close,
        spy_close,
        strike,
        dte,
        lagInFrame(put_close, 1) OVER (PARTITION BY ticker ORDER BY date ASC ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS prev_put,
        lagInFrame(date, 1)      OVER (PARTITION BY ticker ORDER BY date ASC ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS prev_date
    FROM daily
),
moves AS
(
    SELECT abs(100 * (put_close / prev_put - 1)) AS move_pct
    FROM chained
    WHERE prev_put > 0
      AND dateDiff('day', prev_date, date) <= 4
      AND date >= toDate('2026-07-01')
      AND dte BETWEEN 20 AND 45
      AND abs(strike / spy_close - 1) < 0.02
)
SELECT
    multiIf(move_pct < 5,  'under 5%',
            move_pct < 10, '5% to 10%',
            move_pct < 20, '10% to 20%',
                           '20% or more') AS move_bucket,
    count()                                               AS contract_days,
    round(100 * count() / (SELECT count() FROM moves), 1) AS share_pct
FROM moves
GROUP BY move_bucket
ORDER BY min(move_pct)

Run your own version of this

The same 22 years of US equities and 12 years of options data are queryable in SQL or plain English. A free account runs 100 queries a day and takes no card.

More from this analysisstop-orders-on-options
aapl_contracts_by_volume ranking 5×3 spy_put_trace series 10×5 weekly_leaders ranking 25×4 Annualized volatility vs total return, 25 large caps, calmest to wildest (~2 years) ranking 25×3 SPY options median spread by expiration date, near-the-money strikes only ranking 25×4 When market headlines publish, by New York clock hour ranking 24×2 See all 2,191 queries →