{"slug":"mutual-fund-frequent-trading-limits","qid":"entry_gap_by_time","label":"How far SPY sat from its own closing print, by time of day","post_title":"Mutual Fund Frequent Trading Limits Explained","post_url":"/blog/mutual-fund-frequent-trading-limits#q-entry_gap_by_time","columns":["et_time","median_gap_pct","p90_gap_pct"],"rows":[{"et_time":"09:30","median_gap_pct":0.337,"p90_gap_pct":0.958},{"et_time":"10:00","median_gap_pct":0.297,"p90_gap_pct":0.876},{"et_time":"10:30","median_gap_pct":0.278,"p90_gap_pct":0.781},{"et_time":"11:00","median_gap_pct":0.237,"p90_gap_pct":0.754},{"et_time":"11:30","median_gap_pct":0.22,"p90_gap_pct":0.69},{"et_time":"12:00","median_gap_pct":0.192,"p90_gap_pct":0.627},{"et_time":"12:30","median_gap_pct":0.179,"p90_gap_pct":0.582},{"et_time":"13:00","median_gap_pct":0.166,"p90_gap_pct":0.531},{"et_time":"13:30","median_gap_pct":0.14,"p90_gap_pct":0.508},{"et_time":"14:00","median_gap_pct":0.13,"p90_gap_pct":0.439},{"et_time":"14:30","median_gap_pct":0.118,"p90_gap_pct":0.394},{"et_time":"15:00","median_gap_pct":0.104,"p90_gap_pct":0.324},{"et_time":"15:30","median_gap_pct":0.064,"p90_gap_pct":0.203}],"shape":"series","sql":"WITH bars AS\n(\n    SELECT\n        toDate(toTimeZone(window_start, 'America/New_York')) AS session_date,\n        toTimeZone(window_start, 'America/New_York')         AS et_ts,\n        toFloat64(close)                                     AS px\n    FROM global_markets.delayed_stocks_minute_aggs\n    WHERE ticker = 'SPY'\n      AND window_start >= today() - 370\n      AND window_start <  today() - 2\n      AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60\n           + toMinute(toTimeZone(window_start, 'America/New_York'))) >= 570\n      AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60\n           + toMinute(toTimeZone(window_start, 'America/New_York'))) < 960\n),\nsession_close AS\n(\n    SELECT\n        session_date,\n        argMax(px, et_ts) AS close_px\n    FROM bars\n    GROUP BY session_date\n)\nSELECT\n    formatDateTime(toStartOfInterval(b.et_ts, INTERVAL 30 minute), '%H:%i') AS et_time,\n    round(quantileDeterministic(0.5)(abs(b.px / c.close_px - 1) * 100, toUInt32(toUnixTimestamp(b.et_ts))), 3) AS median_gap_pct,\n    round(quantileDeterministic(0.9)(abs(b.px / c.close_px - 1) * 100, toUInt32(toUnixTimestamp(b.et_ts))), 3) AS p90_gap_pct\nFROM bars AS b\nINNER JOIN session_close AS c ON c.session_date = b.session_date\nGROUP BY et_time\nORDER BY et_time","computed_at":"2026-08-22T04:17:30.314221+00:00","elapsed":0.962857682}