{"slug":"mutual-fund-forward-pricing-rule","qid":"close_gap_by_time","label":"close_gap_by_time","post_title":"mutual-fund-forward-pricing-rule","post_url":"/blog/mutual-fund-forward-pricing-rule#q-close_gap_by_time","columns":["et_time","avg_move_to_close_pct","observations"],"rows":[{"et_time":"09:30","avg_move_to_close_pct":0.401,"observations":104},{"et_time":"10:00","avg_move_to_close_pct":0.366,"observations":104},{"et_time":"10:30","avg_move_to_close_pct":0.334,"observations":104},{"et_time":"11:00","avg_move_to_close_pct":0.31,"observations":104},{"et_time":"11:30","avg_move_to_close_pct":0.31,"observations":104},{"et_time":"12:00","avg_move_to_close_pct":0.277,"observations":104},{"et_time":"12:30","avg_move_to_close_pct":0.249,"observations":104},{"et_time":"13:00","avg_move_to_close_pct":0.237,"observations":104},{"et_time":"13:30","avg_move_to_close_pct":0.198,"observations":103},{"et_time":"14:00","avg_move_to_close_pct":0.179,"observations":103},{"et_time":"14:30","avg_move_to_close_pct":0.15,"observations":103},{"et_time":"15:00","avg_move_to_close_pct":0.126,"observations":103},{"et_time":"15:30","avg_move_to_close_pct":0.104,"observations":103}],"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,\n        toFloat64(close)                                       AS px\n    FROM global_markets.delayed_stocks_minute_aggs\n    WHERE ticker = 'SPY'\n      AND window_start >= today() - 150\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),\nfinal_print AS\n(\n    SELECT\n        session_date,\n        argMax(px, et) AS closing_px\n    FROM bars\n    GROUP BY session_date\n)\nSELECT\n    formatDateTime(b.et, '%H:%i')                             AS et_time,\n    round(avg(abs(f.closing_px / b.px - 1)) * 100, 3)         AS avg_move_to_close_pct,\n    count()                                                   AS observations\nFROM bars AS b\nINNER JOIN final_print AS f ON f.session_date = b.session_date\nWHERE toMinute(b.et) IN (0, 30)\nGROUP BY et_time\nORDER BY et_time","computed_at":"2026-09-24T14:48:33.389377+00:00","elapsed":0.491264037}