{"slug":"event-driven-vs-vectorized-backtesting","qid":"latency_slip","label":"How far SPY travels after the minute your signal fired (June 2024)","post_title":"Event-Driven vs Vectorized Backtesting","post_url":"/blog/event-driven-vs-vectorized-backtesting#q-latency_slip","columns":["delay_minutes","median_move_bps","p95_move_bps"],"rows":[{"delay_minutes":1,"median_move_bps":1.47,"p95_move_bps":4.99},{"delay_minutes":2,"median_move_bps":2.02,"p95_move_bps":7.18},{"delay_minutes":5,"median_move_bps":3.11,"p95_move_bps":11.49},{"delay_minutes":15,"median_move_bps":5.24,"p95_move_bps":19.64},{"delay_minutes":30,"median_move_bps":7.66,"p95_move_bps":26.73}],"shape":"ranking","sql":"WITH minute_px AS\n(\n    SELECT\n        toStartOfMinute(toTimeZone(window_start, 'America/New_York')) AS et_minute,\n        toFloat64(any(close))                                         AS close\n    FROM global_markets.delayed_stocks_minute_aggs\n    WHERE ticker = 'SPY'\n      AND window_start >= '2024-06-03 00:00:00'\n      AND window_start <  '2024-06-29 00:00:00'\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    GROUP BY et_minute\n),\nfills AS\n(\n    SELECT\n        et_minute,\n        close,\n        arrayZip([1, 2, 5, 15, 30],\n                 [leadInFrame(close, 1)  OVER w,\n                  leadInFrame(close, 2)  OVER w,\n                  leadInFrame(close, 5)  OVER w,\n                  leadInFrame(close, 15) OVER w,\n                  leadInFrame(close, 30) OVER w]) AS fill_prices\n    FROM minute_px\n    WINDOW w AS (PARTITION BY toDate(et_minute) ORDER BY et_minute ASC ROWS BETWEEN CURRENT ROW AND 30 FOLLOWING)\n),\npairs AS\n(\n    SELECT\n        et_minute,\n        close,\n        arrayJoin(fill_prices) AS fill\n    FROM fills\n)\nSELECT\n    toUInt16(fill.1)                                                                                            AS delay_minutes,\n    round(quantileDeterministic(0.5)(abs(fill.2 / close - 1) * 10000, toUInt32(toUnixTimestamp(et_minute))), 2)  AS median_move_bps,\n    round(quantileDeterministic(0.95)(abs(fill.2 / close - 1) * 10000, toUInt32(toUnixTimestamp(et_minute))), 2) AS p95_move_bps\nFROM pairs\nWHERE fill.2 > 0\nGROUP BY delay_minutes\nORDER BY delay_minutes","computed_at":"2026-10-04T15:20:29.444108+00:00","elapsed":0.378616062}