Strasmore Research
Deep Dives · Matt ConnorBy Matt Connor · · Updated 2026-07-23

2026年6月29日市场微观结构分析

深入剖析2026年6月29日逐笔成交与报价数据,涵盖成交量修正及FINRA文件细节,助您洞察市场底层逻辑。

本文是 2026年6月29日市场回顾 的深度解析:展示了分钟线背后的原始数据 —— 在一个普通的周一交易日内,包含 156.1 百万笔逐笔成交505.38 百万次 NBBO 报价更新。所有数据均为存储查询结果(点击任何面板可查看具体的 SQL 语句)。本文还将详细阐述当日的两项深度发现:一项是交易记录代码库要求的成交量修正,另一项是仅包含至字母 S 结尾的供应商文件。

逐笔交易行情

首先核对交易时段,不预设任何前提:交易所假期日历显示 2026 年 6 月 29 日共有 0 行交易记录。SPY 在常规交易时段内恰好产生了 390 根分钟 K 线,涵盖了纽约时间上午 9:30 至下午 4:00 的完整交易时段。在盘后及盘前交易时段,综合行情记录了 156.1 百万笔 独立交易。

查询单日交易量:交易时段及每笔成交规模
每个数字背后的完整 SQL
WITH
    (SELECT count() FROM global_markets.stocks_market_holidays WHERE date = '2026-06-29') AS holiday_rows,
    (
        SELECT countIf(window_start >= '2026-06-29 13:30:00' AND window_start < '2026-06-29 20:00:00')
        FROM global_markets.delayed_stocks_minute_aggs
        WHERE ticker = 'SPY' AND window_start >= '2026-06-29 00:00:00' AND window_start < '2026-06-30 00:00:00'
    ) AS spy_bars
SELECT
    holiday_rows AS holiday_rows_jun29,
    spy_bars AS spy_regular_session_bars,
    round(count() / 1e6, 1) AS trades_m,
    round(100.0 * countIf(size < 100) / count(), 2) AS odd_lot_pct_of_trades,
    round(100.0 * toFloat64(sumIf(size, size < 100)) / toFloat64(sum(size)), 2) AS odd_lot_pct_of_shares,
    multiIf(
        countIf(size <= 19) >= 0.5 * count(), 19,
        countIf(size <= 20) >= 0.5 * count(), 20,
        countIf(size <= 21) >= 0.5 * count(), 21,
        countIf(size <= 22) >= 0.5 * count(), 22,
        countIf(size <= 23) >= 0.5 * count(), 23,
        0) AS median_print_shares,
    round(countIf(size = 1) / 1e6, 1) AS one_share_trades_m,
    round(100.0 * countIf(size != round(size)) / count(), 2) AS fractional_pct_of_trades
FROM global_markets.stocks_trades
WHERE sip_timestamp >= '2026-06-29 00:00:00' AND sip_timestamp < '2026-06-30 00:00:00'

所有成交记录中,72.61% 为碎股交易(即成交量少于 100 股的交易),但其成交股数仅占总量的 8.79% —— 下文的成交量分析部分会对未修正的总量进行剔除。中位数成交量为 21,该数值通过自我验证的括号探测法得出——即累计计数在 19 至 23 股之间——若探测失败则返回 0,且其范围受到限制以确保错误时保留原值。17.9 百万笔交易仅为 1 股,4.73% 的交易包含碎股——这种模式符合零售交易应用逐笔下单的特征,而 做市商则在另一端承接这些订单

成交量取证:从字典中推导“匹配成交量”

将每笔成交的规模字段相加,6月29日的成交量显示为 24.79 十亿股。该数据是错误的,行情本身也证明了这一点。每笔成交都带有条件代码。SIP(证券信息处理器)将所有交易场所整合为单一数据流,并发布一份字典,逐一说明每个代码是否更新合并成交量。部分消息是已计入成交量的行政重播。本文并非硬编码“已知”代码列表,而是直接从字典中推导排除集:

查询排除集:基于交易代码字典(单行)
每个数字背后的完整 SQL
SELECT
    count() AS excluded_codes,
    sum(id) AS excluded_id_checksum,
    arrayStringConcat(arraySort(groupArray(concat(toString(id), ' ', name))), ' · ') AS codes
FROM global_markets.stocks_condition_codes
WHERE asset_class = 'stocks'
  AND type = 'sale_condition'
  AND JSONExtractBool(update_rules, 'consolidated', 'updates_volume') = 0

3 销售条件在合并数据流中显示 updates_volume = false:15 Market Center Official Close · 16 Market Center Official Open · 38 Corrected Consolidated Close (per listing market)。以下是推导过程:在每日回顾的早期草案中,我们硬编码了代码 15 和 16(所有数据指南都会提到的官方开盘/收盘消息),却完全遗漏了代码 38。字典才是唯一的事实来源,而非记忆中的代码列表。

此处分为两个代码块:在 156.1 百万行扫描中对字典进行标量子查询会超过 30 秒的限制。因此,上方代码块将结果推导为单行——并通过代码数量和 ID 校验和 (69) 进行合理性校验;下方代码块则应用推导出的字面量。如果字典发生变化,校验和将触发本文复审;字面量不会在无感知的情况下失效。

查询原始成交量 vs SIP统计成交量(应用排除集)
每个数字背后的完整 SQL
SELECT
    round(toFloat64(sum(size)) / 1e9, 2) AS raw_shares_bn,
    round(toFloat64(sumIf(size, NOT hasAny(conditions, [15, 16, 38]))) / 1e9, 2) AS matched_shares_bn,
    round(toFloat64(sumIf(size, hasAny(conditions, [15, 16, 38]))) / 1e9, 2) AS excluded_shares_bn,
    countIf(hasAny(conditions, [15, 16, 38])) AS excluded_prints
FROM global_markets.stocks_trades
WHERE sip_timestamp >= '2026-06-29 00:00:00' AND sip_timestamp < '2026-06-30 00:00:00'

修正后的统计数据:原始成交量为 24.79 十亿股,20.66 十亿股为 SIP 统计量,另有 4.13 十亿股因 91175 笔行政打印而被排除。一个精确的定义:“匹配成交量”是指 SIP 根据其自身的条件规则计入合并总量的成交量——仅此而已。我们并非在判断哪些交易具有经济意义,而是在应用行情本身的会计准则。

大额成交解析

当成交代码不再只是琐碎信息时,当日最大的成交量便具有了参考意义:

查询6月29日最大单笔成交(已剔除字典排除代码)
每个数字背后的完整 SQL
SELECT
    ticker,
    formatDateTime(toTimeZone(sip_timestamp, 'America/New_York'), '%H:%i:%S') AS et_time,
    round(toFloat64(size) / 1e6, 2) AS shares_m,
    toFloat64(price) AS price,
    round(toFloat64(size) * toFloat64(price) / 1e6, 1) AS notional_usd_m,
    round(100 * (toFloat64(size) * toFloat64(price)) / max(toFloat64(size) * toFloat64(price)) OVER (), 1) AS pct_of_biggest_dollar_print,
    arrayStringConcat(arrayMap(c -> toString(c), conditions), ', ') AS condition_id
FROM global_markets.stocks_trades
WHERE sip_timestamp >= '2026-06-29 00:00:00' AND sip_timestamp < '2026-06-30 00:00:00'
  AND size >= 10000000
  AND NOT hasAny(conditions, [15, 16, 38])
ORDER BY size DESC
LIMIT 10

请将前几行视为示例。当日最大的一笔成交——61.69 百万股 CAG (Conagra),价格为 $13.98,总额约 $862.5 百万,成交时间为 16:04:53 ET,代码为 8, 41 (8 Closing Prints, 41 Trade Thru Exempt) —— 这是 NYSE 在下午 4:00 后公布的收盘竞价结果。该笔成交在计算成交量时仅计入一次。随后,这 61.69 百万股会以代码 15(市场中心官方收盘)再次出现:这属于重新报告,在我们的计算中已被剔除,即上述已减去的 4.13 十亿股的一部分。由于设计原因,代码 15 的行未包含在上述表格中,因此其接收记录单独列在下方:

查询成交明细:CAG收盘竞价及其代码15重报对比
每个数字背后的完整 SQL
SELECT
    round(toFloat64(maxIf(size, has(conditions, 8))) / 1e6, 2) AS auction_print_shares_m,
    round(toFloat64(maxIf(size, has(conditions, 15))) / 1e6, 2) AS official_close_reprint_shares_m,
    round(toFloat64(maxIf(size, has(conditions, 8))) - toFloat64(maxIf(size, has(conditions, 15))), 2) AS share_difference,
    formatDateTime(toTimeZone(argMaxIf(sip_timestamp, size, has(conditions, 15)), 'America/New_York'), '%H:%i:%S') AS reprint_et,
    argMaxIf(exchange, size, has(conditions, 15)) AS reprint_exchange_id,
    countIf(has(conditions, 15)) AS cag_code15_prints
FROM global_markets.stocks_trades
WHERE ticker = 'CAG'
  AND sip_timestamp >= '2026-06-29 00:00:00' AND sip_timestamp < '2026-06-30 00:00:00'

6 条 CAG 官方收盘消息中的最大一笔包含 61.69 百万股 —— 即竞价成交的 61.69 百万股(差额:0)—— 成交时间为 16:04:53 ET,交易所 ID 为 10(股票目录中的 NYSE):即上市交易所对其自身竞价结果的重新陈述。

其余的 CAG 行属于不同类型 —— 代码为 12, 2 (12 Form T / extended hours, 2 Average Price Trade) 的 15.17 百万股成交,以及另外两笔代码为 12 的成交,均为通过 FINRA 报告的竞价后成交,其条件包含 updates_volume = true。SIP 和我们的匹配数据均将其视为真实成交。

在其他部分,代码 9 代表 Nasdaq 收盘交叉盘 —— NVDA 的 $3389.5 百万交叉盘是表中金额最大的成交 —— 而 SNAP (53, 41) 的代码包含 53,即合格或约定的交易 (Qualified Contingent Trade)。

时间:十分钟主导全天

若以分钟为单位观察,交易量几乎全部集中在交易时段的边缘:

查询交易最活跃的十分钟(成交笔数以百万计)
每个数字背后的完整 SQL
SELECT
    formatDateTime(toTimeZone(toStartOfMinute(sip_timestamp), 'America/New_York'), '%H:%i') AS et_minute,
    round(count() / 1e6, 2) AS trades_m
FROM global_markets.stocks_trades
WHERE sip_timestamp >= '2026-06-29 00:00:00' AND sip_timestamp < '2026-06-30 00:00:00'
GROUP BY et_minute
ORDER BY trades_m DESC
LIMIT 10

15:59 ET 时间内成交了 3.98 百万笔交易 —— 每秒超过六万笔。其余前十名交易量是否也集中在开盘和收盘阶段,可通过以下数据验证:

查询最活跃的十分钟中有多少不在开盘与收盘时段
每个数字背后的完整 SQL
SELECT
    countIf(NOT (et_minute BETWEEN '09:30' AND '09:39' OR et_minute BETWEEN '15:50' AND '16:00')) AS entries_outside_open_close,
    countIf(et_minute BETWEEN '09:30' AND '09:39' OR et_minute BETWEEN '15:50' AND '16:00') AS entries_in_open_close,
    maxIf(et_minute, NOT (et_minute BETWEEN '09:30' AND '09:39' OR et_minute BETWEEN '15:50' AND '16:00')) AS outside_entry_minute,
    maxIf(trades_m, NOT (et_minute BETWEEN '09:30' AND '09:39' OR et_minute BETWEEN '15:50' AND '16:00')) AS outside_entry_trades_m
FROM (
    SELECT
        formatDateTime(toTimeZone(toStartOfMinute(sip_timestamp), 'America/New_York'), '%H:%i') AS et_minute,
        round(count() / 1e6, 2) AS trades_m
    FROM global_markets.stocks_trades
    WHERE sip_timestamp >= '2026-06-29 00:00:00' AND sip_timestamp < '2026-06-30 00:00:00'
    GROUP BY et_minute
    ORDER BY trades_m DESC
    LIMIT 10
)

前十名中有 9 笔发生在开盘后的前十分钟,或收盘前的最后十分钟。唯一的例外是 10:15 ET 时段,成交量激增至 0.88 百万笔;这属于典型的上午交易异常;从现有数据无法判断其原因,我们不作推测。下文将再次提及该时间点。

报价流:数亿次更新

全美最佳买卖报价(NBBO)是指各交易所的最佳买入与卖出价。每当价格变动,该数据就会重新发布。6月29日,NBBO 更新了 505.38 million times,而成交量为 156.1 million 次。

查询全量NBBO流——锁定 QQQ 与 NVDA
每个数字背后的完整 SQL
WITH
    (
        SELECT (round(countIf(ticker = 'QQQ') / 1e6, 2), round(countIf(ticker = 'NVDA') / 1e6, 2),
                round(countIf(ticker = 'AAPL') / 1e6, 2), round(countIf(ticker = 'TSLA') / 1e6, 2))
        FROM global_markets.cache_stocks_quotes
        WHERE ticker IN ('QQQ', 'NVDA', 'AAPL', 'TSLA')
          AND sip_timestamp >= '2026-06-29 00:00:00' AND sip_timestamp < '2026-06-30 00:00:00'
    ) AS pinned
SELECT
    round(count() / 1e6, 2) AS updates_m,
    pinned.1 AS qqq_updates_m,
    pinned.2 AS nvda_updates_m,
    round(pinned.1 - pinned.2, 2) AS qqq_minus_nvda_updates_m,
    round(pinned.2 - greatest(pinned.3, pinned.4), 2) AS nvda_minus_next_single_m
FROM global_markets.cache_stocks_quotes
WHERE sip_timestamp >= '2026-06-29 00:00:00' AND sip_timestamp < '2026-06-30 00:00:00'

指数产品在报价中占主导地位:仅 QQQ 就记录了 5.23 million 次更新,而我们查询的报价最频繁的个股 NVDA 为 1.8 million 次——两者相差 0.67 million 次。由于无法在30秒内完成对所有上市证券的逐一统计,下方的排行榜仅为抽样结果,而非完整排名:

查询八个高频报价股票的NBBO报价更新(百万级)
每个数字背后的完整 SQL
SELECT ticker, round(count() / 1e6, 2) AS updates_m
FROM global_markets.cache_stocks_quotes
WHERE ticker IN ('QQQ', 'SPY', 'TQQQ', 'IWM', 'SQQQ', 'NVDA', 'AAPL', 'TSLA')
  AND sip_timestamp >= '2026-06-29 00:00:00' AND sip_timestamp < '2026-06-30 00:00:00'
GROUP BY ticker
ORDER BY updates_m DESC

QQQ5.23 million 次更新位居抽样名单首位;榜单顶端主要是指数基金及其杠杆衍生品,而非大众熟知的个股。

深度解析 SPY:纳秒级行情与买卖价差

查询SPY微观分析:纳秒级间隔、双向价差、报价质量
每个数字背后的完整 SQL
WITH
    (
        SELECT (formatDateTime(toTimeZone(toStartOfSecond(sip_timestamp), 'America/New_York'), '%H:%i:%S'), count())
        FROM global_markets.cache_stocks_quotes
        WHERE ticker = 'SPY' AND sip_timestamp >= '2026-06-29 13:30:00' AND sip_timestamp < '2026-06-29 20:00:00'
        GROUP BY toStartOfSecond(sip_timestamp)
        ORDER BY count() DESC, toStartOfSecond(sip_timestamp) ASC
        LIMIT 1
    ) AS busiest_sec,
    ordered AS (
        SELECT
            toFloat64(ask_price - bid_price) AS spread,
            bid_price,
            ask_price,
            toFloat64(sip_timestamp - lagInFrame(sip_timestamp) OVER (ORDER BY sip_timestamp, sequence_number)) AS gap_s,
            greatest(toFloat64(least(leadInFrame(sip_timestamp, 1, toDateTime64('2026-06-29 20:00:00', 9)) OVER (ORDER BY sip_timestamp, sequence_number ROWS BETWEEN CURRENT ROW AND 1 FOLLOWING), toDateTime64('2026-06-29 20:00:00', 9)) - sip_timestamp), 0) AS dwell_s,
            rowNumberInAllBlocks() AS rn
        FROM global_markets.cache_stocks_quotes
        WHERE ticker = 'SPY' AND sip_timestamp >= '2026-06-29 13:30:00' AND sip_timestamp < '2026-06-29 20:00:00'
    )
SELECT
    round(count() / 1e6, 2) AS spy_updates_m,
    busiest_sec.1 AS busiest_second_et,
    toUInt8(startsWith(busiest_sec.1, '10:15')) AS busiest_second_in_1015,
    busiest_sec.2 AS busiest_second_updates,
    round(minIf(gap_s, rn > 0 AND gap_s > 0) * 1e9) AS min_gap_between_updates_ns,
    round(quantileExactIf(0.5)(gap_s, rn > 0) * 1e6, 1) AS median_gap_us,
    countIf(rn > 0 AND gap_s = 0) AS identical_timestamp_pairs,
    round(sumIf(spread * dwell_s, bid_price > 0 AND ask_price >= bid_price) / sumIf(dwell_s, bid_price > 0 AND ask_price >= bid_price) * 100, 2) AS time_weighted_avg_spread_cents,
    round(avgIf(spread, bid_price > 0 AND ask_price >= bid_price) * 100, 2) AS per_update_avg_spread_cents,
    round((avgIf(spread, bid_price > 0 AND ask_price >= bid_price) - sumIf(spread * dwell_s, bid_price > 0 AND ask_price >= bid_price) / sumIf(dwell_s, bid_price > 0 AND ask_price >= bid_price)) * 100, 2) AS per_update_premium_cents,
    countIf(bid_price > 0 AND ask_price > 0 AND ask_price < bid_price) AS crossed_updates,
    countIf(bid_price <= 0 OR ask_price <= 0) AS zero_bid_or_ask_updates
FROM ordered

仅在常规交易时段,SPY 的报价变动就达到了 3.98 百万次。最繁忙的一秒出现在 10:15:43 ET,即上述 10:15 分钟内,该秒内共有 1461 次更新。相邻更新之间的最小间隔为 1375 纳秒,中位数为 245.6 微秒;此外,有 75138 对连续更新的纳秒时间戳完全相同——即便达到纳秒级精度,也无法完全对现代行情进行排序。

这些纳秒级数据主要用于衡量 买卖价差。若对每次更新进行等权重计算,SPY 的平均价差为 2.72 美分;若按报价持续时间进行加权计算,则为 2.34 美分。从机械角度看,按单次更新计算的数值要宽 0.38 美分:因为报价更新往往集中在价差较宽且剧烈波动的时刻,而挂单的持续时间则以时钟时间计算。在查看价差统计数据时,请务必确认其使用的计量标准。统计数据是透明的:1544 次常规时段更新出现了价格交叉(卖价低于买价,即来自不同交易场所的报价交织),0 次更新的买价或卖价为零;价差统计已排除上述两种情况,并将其纳入计算。

价差具有时间规律

将 SPY 的报价价差按半小时进行分组,可以将其微观结构转化为任何交易者都能利用的曲线:

查询SPY每半小时中值报价价差(美东4:00 am - 8:00 pm)
每个数字背后的完整 SQL
SELECT
    formatDateTime(toTimeZone(toStartOfInterval(sip_timestamp, INTERVAL 30 MINUTE), 'America/New_York'), '%H:%i') AS et_time,
    round(quantileExactIf(0.5)(toFloat64(ask_price - bid_price), bid_price > 0 AND ask_price >= bid_price) * 100, 1) AS median_spread_cents,
    count() AS quote_updates
FROM global_markets.cache_stocks_quotes
WHERE ticker = 'SPY' AND sip_timestamp >= '2026-06-29 08:00:00' AND sip_timestamp < '2026-06-30 00:00:00'
GROUP BY et_time
ORDER BY et_time

04:00 时段的 ET 盘前中位数为 8 美分,09:30 时段为 3 美分,到 14:00 时则为 2 美分。在盘前开盘时交易同一股股票的成本,大约是午后订单价差的四倍。价差并非恒定不变,而是一套时间表。

数据异常分析:在 S 开头的代码处中断的文件

在发布每日供应商文件的数据前,我们会进行完整性校验:统计代码数量、检查字母范围并对比相邻日期。6 月 29 日的 FINRA 场外做空成交量文件就是一个典型案例:

查询完整性检测:FINRA卖空成交文件覆盖率,6月26-30日
每个数字背后的完整 SQL
SELECT
    date,
    uniqExact(ticker) AS tickers,
    min(ticker) AS first_ticker,
    max(ticker) AS last_ticker,
    countIf(ticker = 'TSLA') AS tsla_rows,
    round(100 * sum(short_volume) / sum(total_volume), 2) AS short_pct_of_reported
FROM global_markets.stocks_short_volume
WHERE date BETWEEN '2026-06-26' AND '2026-06-30'
GROUP BY date
ORDER BY date

6 月 26 日的文件包含 15052 个代码,范围从 AZYME。6 月 29 日的文件仅包含 5489 个代码,范围从 ASSUS —— 数据在 S 开头的代码中途停止。此后所有字母顺序靠后的代码均缺失,包括 TSLA(6 月 29 日为 0 行,6 月 26 日为 1 行);到 6 月 30 日,文件恢复至 15362 个代码。完整性校验本质上就是这种每日单行数据的核对——这决定了发布的是统计数据还是错误样本。

基于上述说明,以下是计算出的比例:6 月 29 日的标记做空成交量占报告的场外成交量的 45.85,而 6 月 26 日和 6 月 30 日分别为 46.8948.82。由于 6 月 29 日的数据仅涵盖 A 到 S 的部分,请将其视为部分读数。相邻交易日的做空占比通常接近 50%,且每日做空成交量并不等同于 卖空头寸

数据说明

完整数据说明
  • 下午 5 点至 6 点的报价停滞期。 SPY 的报价流在东部时间 17:00 时段(233 更新)几乎停止,并在 18:0040608)恢复。这是跨代码的行情/交易时段模式,并非数据缺失。
  • 存在大量碎股交易。 4.73% 的成交记录为非整数规模;计算成交量时必须按小数进行累加。
  • 代码字典在不同类型间复用 ID。 ID 15 既是销售条件(市场中心官方收盘),也是报价条件(已收盘);此处每次字典查询都会过滤 asset_class = 'stocks'type = 'sale_condition'。仅通过 ID 进行查询会导致代码误标。
  • 报价质量排除项已包含在内。 集合报价(crossed)和零买卖价差(zero-bid-or-ask)的计数已包含在上方 SPY 微观面板中;价差统计不会掩盖这些跌落。
  • 全市场扫描仅限批处理面板。 此处的市场范围区块在冷缓存下测量时间约为 30 秒(超时区块会重试一次;热缓存扫描则不受此限制);它们在编写时通过受限的只读路径运行一次,不会为读者提供实时数据,存储的结果即为记录。

方法论

  • 时间戳以 UTC 格式存储,并使用原始 UTC 范围进行过滤(6 月 29 日的常规交易时间为 13:30 至 20:00 UTC);toTimeZone 仅出现在 SELECT 列表中。
  • 会话类型通过节假日日历和观测到的 390 根 K 线常规窗口进行验证,而非直接假设。
  • “SIP 统计(匹配)成交量”是指 SIP 根据其自身条件规则计入合并总额的成交量;排除集源自字典并受校验和限制,而非硬编码。
  • 每笔更新的价差统计对每次 NBBO 更新赋予相同权重;时间加权统计则根据报价持续时间赋予权重。两者均会说明排除项。
  • 小数价格/规模列在进行任何比例或价格乘以规模的运算前,先进行原生求和并转换为 64 位浮点数。
  • Tick 表保留完整历史记录,不设滚动过期;无论如何,这些存储且版本化的结果即为持久记录。数据仓库状态截至 2026 年 7 月 3 日。

上述每个面板均为一个存储对象——包含图表、表格和 SQL。您可以打开其中任何一个,复制查询,并在 Strasmore 终端中进行进一步分析。