STRASMORE/EXPLORE 2,648 QUERIES

session_shape

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-26, from the-10-am-rule-in-stocks.

as of series 13×3read in context →
session_shape — 13 rows by 3 columns, computed from US exchange, SIP and OPRA data.
et_timevolume_share_pctrange_share_pct
09:3015.554.5
10:009.838.1
10:30831.5
11:00727.6
11:30624.7
12:005.422.6
12:304.921.3
13:00521.6
13:304.920.8
14:005.421.7
14:305.520.6
15:006.521
15:3015.929.1
Rows × columns
13 × 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 session_shape, derived from the stored result.
ColumnTypeRangeNotes
et_time text 13 distinct values (09:30, 10:00, 10:30…)
volume_share_pct number 4.9 to 15.9 percent
range_share_pct number 20.6 to 54.5 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.

Run it yourself

This is the exact query behind the result above. Change a ticker, a date or a column and run it against the warehouse — no account, no key. The no-signup tier is smaller than the one this page was computed on; a query that reaches past it comes back saying which plan runs it.

WITH bars AS (
    SELECT
        ticker,
        toDate(toTimeZone(window_start, 'America/New_York'))            AS trade_day,
        toHour(toTimeZone(window_start, 'America/New_York')) * 60
            + toMinute(toTimeZone(window_start, 'America/New_York'))    AS et_minute,
        high,
        low,
        volume
    FROM global_markets.delayed_stocks_minute_aggs
    WHERE ticker IN ('SPY', 'QQQ', 'AAPL', 'MSFT', 'NVDA', 'KO')
      AND window_start >= '2023-01-01'
      AND window_start <  '2026-01-01'
),
regular AS (
    SELECT *
    FROM bars
    WHERE et_minute >= 570 AND et_minute < 960
),
day_totals AS (
    SELECT
        ticker,
        trade_day,
        max(high)   AS day_high,
        min(low)    AS day_low,
        sum(volume) AS day_volume,
        count()     AS bar_count
    FROM regular
    GROUP BY ticker, trade_day
    HAVING bar_count >= 300
       AND day_high > day_low
       AND day_volume > 0
),
half_hours AS (
    SELECT
        ticker,
        trade_day,
        intDiv(et_minute - 570, 30) AS bucket,
        max(high)                   AS bucket_high,
        min(low)                    AS bucket_low,
        sum(volume)                 AS bucket_volume
    FROM regular
    GROUP BY ticker, trade_day, bucket
)
SELECT
    formatDateTime(toDateTime((570 + h.bucket * 30) * 60, 'UTC'), '%H:%i') AS et_time,
    round(avg(100 * toFloat64(h.bucket_volume) / toFloat64(d.day_volume)), 1) AS volume_share_pct,
    round(avg(100 * toFloat64(h.bucket_high - h.bucket_low)
                  / toFloat64(d.day_high - d.day_low)), 1)                   AS range_share_pct
FROM half_hours AS h
INNER JOIN day_totals AS d
    ON d.ticker = h.ticker AND d.trade_day = h.trade_day
GROUP BY h.bucket
ORDER BY h.bucket
⌘/Ctrl + Enter

Work with this data in your AI assistant

Opens ready to query, with this page's data. Free, no account.

More from this analysisthe-10-am-rule-in-stocks
first_hour_decay series 90×3 → open_spread_trace series 12×3 → open_share ranking 6×3 → coverage ranking 6×4 → The 2s10s spread by month, full history series 604×5 → One SPY $600 LEAPS call's price over two years (expired Jan 16 2026) series 470×2 → See all 2,648 queries →