{"slug":"volatility-targeting-position-sizing","qid":"lookback_cost","label":"What the lookback window costs in daily turnover (SPY, 10% target, 2x cap)","post_title":"Volatility Targeting for Position Sizing","post_url":"/blog/volatility-targeting-position-sizing#q-lookback_cost","columns":["lookback_window","avg_weight","avg_daily_turnover_pct","days_at_cap_pct"],"rows":[{"lookback_window":"10-session","avg_weight":0.81,"avg_daily_turnover_pct":6.92,"days_at_cap_pct":0.7},{"lookback_window":"21-session","avg_weight":0.75,"avg_daily_turnover_pct":2.95,"days_at_cap_pct":0},{"lookback_window":"63-session","avg_weight":0.69,"avg_daily_turnover_pct":0.85,"days_at_cap_pct":0},{"lookback_window":"126-session","avg_weight":0.66,"avg_daily_turnover_pct":0.42,"days_at_cap_pct":0}],"shape":"ranking","sql":"WITH\n    px AS\n    (\n        SELECT\n            date                  AS d,\n            toFloat64(any(close)) AS c\n        FROM global_markets.stocks_daily_aggs\n        WHERE ticker = 'SPY'\n          AND date >= subtractYears(today(), 5)\n          AND date <  today()\n        GROUP BY d\n    ),\n    px_sorted AS\n    (\n        SELECT arraySort(p -> p.1, groupArray((d, c))) AS pts\n        FROM px\n    ),\n    rets AS\n    (\n        SELECT arrayFilter(x -> abs(x) < 0.4,\n                   arrayMap((a, b) -> log(b.2 / a.2),\n                            arraySlice(pts, 1, length(pts) - 1),\n                            arraySlice(pts, 2))) AS r\n        FROM px_sorted\n    ),\n    grid AS\n    (\n        SELECT\n            r,\n            arrayJoin([10, 21, 63, 126]) AS lb\n        FROM rets\n    ),\n    weights AS\n    (\n        SELECT\n            lb,\n            arrayMap(i -> least(2.0,\n                        0.10 / (arrayReduce('stddevSamp', arraySlice(r, i - lb + 1, lb)) * sqrt(252))),\n                     range(lb, length(r) + 1)) AS w\n        FROM grid\n    )\nSELECT\n    concat(toString(lb), '-session') AS lookback_window,\n    round(arrayAvg(w), 2)            AS avg_weight,\n    round(100 * arrayAvg(arrayMap((a, b) -> abs(b - a),\n                                  arraySlice(w, 1, length(w) - 1),\n                                  arraySlice(w, 2))), 2) AS avg_daily_turnover_pct,\n    round(100.0 * arrayCount(x -> x > 1.999, w) / length(w), 1) AS days_at_cap_pct\nFROM weights\nORDER BY lb","computed_at":"2026-08-22T04:32:26.800123+00:00","elapsed":0.114236775}