{"slug":"finra-margin-debt-statistics","qid":"gap_moves","label":"How far SPY travels between month end and the third-week release window","post_title":"FINRA Margin Debt Statistics, Explained","post_url":"/blog/finra-margin-debt-statistics#q-gap_moves","columns":["move_bucket","months_count","share_pct"],"rows":[{"move_bucket":"0 to 1%","months_count":52,"share_pct":21.1},{"move_bucket":"1 to 2%","months_count":54,"share_pct":21.9},{"move_bucket":"2 to 3%","months_count":45,"share_pct":18.2},{"move_bucket":"3 to 5%","months_count":52,"share_pct":21.1},{"move_bucket":"5 to 8%","months_count":29,"share_pct":11.7},{"move_bucket":"8% or more","months_count":15,"share_pct":6.1}],"shape":"ranking","sql":"WITH daily AS\n(\n    SELECT\n        toDate(toTimeZone(window_start, 'America/New_York')) AS d,\n        argMax(close, window_start)                          AS px\n    FROM global_markets.delayed_stocks_minute_aggs\n    WHERE ticker = 'SPY'\n      AND window_start >= toDateTime('2006-01-01 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 d\n),\nreference_month AS\n(\n    SELECT\n        toStartOfMonth(d) AS m,\n        max(d)            AS as_of,\n        argMax(px, d)     AS as_of_close\n    FROM daily\n    GROUP BY m\n),\nrelease AS\n(\n    SELECT\n        m,\n        as_of,\n        as_of_close,\n        addDays(toStartOfMonth(addMonths(m, 1)), 19) AS release_day\n    FROM reference_month\n),\ngaps AS\n(\n    SELECT\n        r.m AS m,\n        abs(round(100 * (toFloat64(argMax(d.px, d.d))\n                         / toFloat64(any(r.as_of_close)) - 1), 2)) AS abs_move_pct\n    FROM release AS r\n    CROSS JOIN daily AS d\n    WHERE d.d > r.as_of\n      AND d.d <= r.release_day\n      AND r.release_day < today()\n    GROUP BY r.m\n)\nSELECT\n    multiIf(abs_move_pct < 1, '0 to 1%',\n            abs_move_pct < 2, '1 to 2%',\n            abs_move_pct < 3, '2 to 3%',\n            abs_move_pct < 5, '3 to 5%',\n            abs_move_pct < 8, '5 to 8%',\n                              '8% or more')        AS move_bucket,\n    count()                                        AS months_count,\n    round(100 * count() / (SELECT count() FROM gaps), 1) AS share_pct\nFROM gaps\nGROUP BY move_bucket\nORDER BY min(abs_move_pct)","computed_at":"2026-08-22T04:06:13.737368+00:00","elapsed":28.078645566}