STRASMORE/EXPLORE 2,309 QUERIES

volume_curve

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-17, from twap-vs-vwap-vs-pov-orders.

as of series 13×4read in context →
volume_curve — 13 rows by 4 columns, computed from US exchange, SIP and OPRA data.
et_timeavg_volume_millionsvwap_share_pcttwap_share_pct
09:304.6111.377.69
10:003.338.227.69
10:302.796.887.69
11:002.476.087.69
11:302.486.127.69
12:002.25.427.69
12:301.974.857.69
13:002.045.047.69
13:301.874.617.69
14:002.285.637.69
14:302.466.077.69
15:003.147.767.69
15:308.921.967.69
Rows × columns
13 × 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 volume_curve, derived from the stored result.
ColumnTypeRangeNotes
et_time text 13 distinct values (09:30, 10:00, 10:30…)
avg_volume_millions number 1.87 to 8.9 count
vwap_share_pct number 4.61 to 21.96 percent
twap_share_pct number every row is 7.69 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 bars AS
(
    SELECT
        toTimeZone(window_start, 'America/New_York')  AS et,
        toHour(et) * 60 + toMinute(et)                AS minute_of_day,
        toDate(et)                                    AS et_date,
        toFloat64(volume)                             AS shares
    FROM global_markets.delayed_stocks_minute_aggs
    WHERE ticker = 'SPY'
      AND window_start >= toDateTime('2026-06-01 00:00:00', 'UTC')
      AND window_start <  toDateTime('2026-09-01 00:00:00', 'UTC')
),
per_bucket AS
(
    SELECT
        formatDateTime(toStartOfInterval(et, INTERVAL 30 MINUTE), '%H:%i', 'America/New_York') AS et_time,
        sum(shares)                                                                            AS bucket_shares,
        countDistinct(et_date)                                                                 AS sessions
    FROM bars
    WHERE minute_of_day >= 570
      AND minute_of_day <  960
    GROUP BY et_time
)
SELECT
    b.et_time                                          AS et_time,
    round(b.bucket_shares / b.sessions / 1e6, 2)       AS avg_volume_millions,
    round(100 * b.bucket_shares / t.window_shares, 2)  AS vwap_share_pct,
    round(100 / t.bucket_count, 2)                     AS twap_share_pct
FROM per_bucket AS b
CROSS JOIN
(
    SELECT
        sum(bucket_shares) AS window_shares,
        count()            AS bucket_count
    FROM per_bucket
) AS t
ORDER BY et_time

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 analysistwap-vs-vwap-vs-pov-orders
lunch_pov series 13×4 curve_dispersion series 13×4 open_vs_lunch table 5×6 One SPY $600 LEAPS call's price over two years (expired Jan 16 2026) series 470×2 monthly series 241×4 2s10s spread, monthly average: last 20 years series 240×2 See all 2,309 queries →