{"slug":"microstructure-2026-06-29","qid":"spy_quote_micro","label":"SPY under the microscope: nanosecond gaps, the spread two ways, quote quality","post_title":"Microstructure Deep-Dive: June 29, 2026","post_url":"/blog/microstructure-2026-06-29#q-spy_quote_micro","columns":["spy_updates_m","busiest_second_et","busiest_second_in_1015","busiest_second_updates","min_gap_between_updates_ns","median_gap_us","identical_timestamp_pairs","time_weighted_avg_spread_cents","per_update_avg_spread_cents","per_update_premium_cents","crossed_updates","zero_bid_or_ask_updates"],"rows":[{"spy_updates_m":3.98,"busiest_second_et":"10:15:43","busiest_second_in_1015":1,"busiest_second_updates":1461,"min_gap_between_updates_ns":1375,"median_gap_us":245.6,"identical_timestamp_pairs":75138,"time_weighted_avg_spread_cents":2.34,"per_update_avg_spread_cents":2.72,"per_update_premium_cents":0.38,"crossed_updates":1544,"zero_bid_or_ask_updates":0}],"shape":"scalar","sql":"WITH\n    (\n        SELECT (formatDateTime(toTimeZone(toStartOfSecond(sip_timestamp), 'America/New_York'), '%H:%i:%S'), count())\n        FROM global_markets.cache_stocks_quotes\n        WHERE ticker = 'SPY' AND sip_timestamp >= '2026-06-29 13:30:00' AND sip_timestamp < '2026-06-29 20:00:00'\n        GROUP BY toStartOfSecond(sip_timestamp)\n        ORDER BY count() DESC, toStartOfSecond(sip_timestamp) ASC\n        LIMIT 1\n    ) AS busiest_sec,\n    ordered AS (\n        SELECT\n            toFloat64(ask_price - bid_price) AS spread,\n            bid_price,\n            ask_price,\n            toFloat64(sip_timestamp - lagInFrame(sip_timestamp) OVER (ORDER BY sip_timestamp, sequence_number)) AS gap_s,\n            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,\n            rowNumberInAllBlocks() AS rn\n        FROM global_markets.cache_stocks_quotes\n        WHERE ticker = 'SPY' AND sip_timestamp >= '2026-06-29 13:30:00' AND sip_timestamp < '2026-06-29 20:00:00'\n    )\nSELECT\n    round(count() / 1e6, 2) AS spy_updates_m,\n    busiest_sec.1 AS busiest_second_et,\n    toUInt8(startsWith(busiest_sec.1, '10:15')) AS busiest_second_in_1015,\n    busiest_sec.2 AS busiest_second_updates,\n    round(minIf(gap_s, rn > 0 AND gap_s > 0) * 1e9) AS min_gap_between_updates_ns,\n    round(quantileExactIf(0.5)(gap_s, rn > 0) * 1e6, 1) AS median_gap_us,\n    countIf(rn > 0 AND gap_s = 0) AS identical_timestamp_pairs,\n    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,\n    round(avgIf(spread, bid_price > 0 AND ask_price >= bid_price) * 100, 2) AS per_update_avg_spread_cents,\n    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,\n    countIf(bid_price > 0 AND ask_price > 0 AND ask_price < bid_price) AS crossed_updates,\n    countIf(bid_price <= 0 OR ask_price <= 0) AS zero_bid_or_ask_updates\nFROM ordered","computed_at":"2026-07-26T06:09:00.129964+00:00","elapsed":2.332627366}