STRASMORE/EXPLORE 2,648 QUERIES

intraday_profile

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 us-stock-market-hours-german-time.

as of series 16×4read in context →
intraday_profile — 16 rows by 4 columns, computed from US exchange, SIP and OPRA data.
et_timegerman_timeavg_volume_millionsavg_range_pct
09:0015:000.230.019
09:3015:304.060.055
10:0016:002.940.044
10:3016:302.510.039
11:0017:002.660.035
11:3017:302.030.032
12:0018:001.840.028
12:3018:301.610.026
13:0019:001.650.025
13:3019:301.460.022
14:0020:001.880.025
14:3020:302.280.025
15:0021:002.640.026
15:3021:307.70.032
16:0022:005.060.021
16:3022:300.290.01
Rows × columns
16 × 4
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 intraday_profile, derived from the stored result.
ColumnTypeRangeNotes
et_time text 16 distinct values (09:00, 09:30, 10:00…)
german_time text 16 distinct values (15:00, 15:30, 16:00…)
avg_volume_millions number 0.23 to 7.7 count
avg_range_pct number 0.01 to 0.055 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
    (
        SELECT toHour(toTimeZone(toDateTime(concat(toString(max(date)), ' 12:00:00'), 'America/New_York'), 'Europe/Berlin')) - 12
        FROM global_markets.stocks_daily_aggs
        WHERE ticker = 'SPY'
    ) AS german_offset_hours
SELECT
    formatDateTime(toDateTime(bucket_min * 60, 'UTC'), '%H:%i')                                            AS et_time,
    formatDateTime(toDateTime(((bucket_min + german_offset_hours * 60) % 1440) * 60, 'UTC'), '%H:%i')       AS german_time,
    round(sum(volume) / countDistinct(session_date) / 1e6, 2)                                              AS avg_volume_millions,
    round(avg(bar_range_pct), 3)                                                                           AS avg_range_pct
FROM
(
    SELECT
        toDate(et)                                     AS session_date,
        intDiv(toHour(et) * 60 + toMinute(et), 30) * 30 AS bucket_min,
        volume,
        toFloat64(high - low) / toFloat64(close) * 100  AS bar_range_pct
    FROM
    (
        SELECT
            toTimeZone(window_start, 'America/New_York') AS et,
            volume,
            high,
            low,
            close
        FROM global_markets.delayed_stocks_minute_aggs
        WHERE ticker = 'SPY'
          AND window_start >= today() - 60
          AND window_start <  today() - 1
    )
    WHERE (toHour(et) * 60 + toMinute(et)) >= 540
      AND (toHour(et) * 60 + toMinute(et)) <  1020
)
GROUP BY bucket_min
ORDER BY bucket_min
⌘/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 analysisus-stock-market-hours-german-time
open_clock_by_week series 58×4 → us_closures series 12×8 → session_clock table 5×7 → mismatch_by_year table 5×6 → 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 →