I think your insights echo mine. I exported ~5 years of realized trades from Schwab and matched them up on exported transactions from P123 simulated runs with next open, next close, previous close on the portfolio models that drove transactions (this would have been unbelievably tedious and time consuming before LLMs). Did the same thing on another ~3 years of realized trades from Vanguard with a different P123 live portfolio that drives my wife's retirement account (no OTC/ADR and higher liquidity floor universe).
I have to also qualify this with the fact that I'm temperamentally a terrible trader and it annoys me to no end leaving things unresolved. I'm probably more prone than the average person to chase a gapping stock to get a fill before the end of the trading session. All the more reason why it's important to me to find some of data sound way to find a systematic approach to getting the fills (the same way I turned to P123 to help develop a systematic way to pick stocks to avoid my behavioral biases).
Here is basically what I found .... there is an overnight gap median +14 bps, mean +59, and 54% of trades adverse across 1,242 matched pairs. Intraday movement it's worse — on Buys the median +36, mean +142.
You're right that the mean is what we pay. But one wrinkle worth knowing: part of why my medians look so tame is that 15–20% of my matched trades have a nearly identical open and close prices. My hunch is these are stale foreign ADRs. Also illiquid smaller microcaps that barely trade and or move when there is no news. Once you strip those out the median conservatively doubles, perhaps triples, so the median is perhaps flattering me twice over.
I've just started implemeting a cap for Monday limit orders that caps at ~2.5% on above Friday's close. Your 4–5% rule and mine do the same job but perhaps measure from different places. I've just measured something that makes me think yours may be the better construction. I lagged my signal by two weeks per Yuval's suggestion and re-ran everything. About two-thirds of the overnight gap vanished. Which means most of what I've been treating as "the stock got away from me" was actually market repricing on the same information my ranking used. That's really not something I can do anything about. The previous close price just isn't available to me in the real world, and I'm not sure that is definitionally a "chase" ... that's just the market setting the new fair price. My rule ~2.5% cap blocks me from paying it — disproportionately on the strongest names -- so perhaps I need to raise the cap.
On my book, buying at the close instead of the open costs +142 bps, and +58 bps even on a two-week-stale ranking signal, so it isn't just fresh news running away. Something slower keeps pushing my buys up through the session.
The sell side is another story. My lagged sell drift is −0.9 bps intraday and +5.8 bps overnight, neither statistically significant. Sells really don't have much timing urgency for me. So sell Friday before close, buy Monday at the open is what I've settled on. Since sells dont penalize that's the leg that probably tolerates a phone and a work commute approach that fits around your work life.
Whether a name that plummets out of the rank gets pulled back in by the price drop itself is the one I most want to know and haven't measured.