A rolling z-score asks "how unusual is the current value vs its own recent history" instead of hardcoding a magic number. It fixes drifting thresholds — but it is not trend-immune, and we can prove it.
z = (x − rolling_mean(x, W)) / rolling_std(x, W). z > 1.5 means "unusually high vs the last W bars". The threshold adapts as the series drifts, which absolute cutoffs cannot do.
We use W=200 by default. Symmetry check on real BTC retail long/short data: z>1.5 fired 11.5% of bars, z<−1.5 fired 9.8% — both tails alive. The absolute thresholds they replaced had one side firing exactly 0.0%.
Engine operators z_gt/z_lt use the rolling-200 z-score. Story of why we switched: three bugs, found honestly.
Open the rule playground, build a condition with this indicator, and run it on 1,000 real bars — per-condition fire counts, entirely in your browser. Or lint it in Python with rulelint (MIT).
Research and education. Not investment advice. No indicator makes money by itself — our own arenas' honest records (losses included) are on the scoreboard.