Most people assume a screener — a script that scans the market for candidate setups matching a pattern — works like this: pattern fires, AI scores it, done. Stocklake does something upstream of that. Three screeners check the live market regime before AI ever sees a candidate, and veto entire categories of ideas outright — because backtests proved those categories lose more often than they win, or waste effort, in specific conditions. Here's what actually gets filtered, why, and the real numbers behind each decision. One of these three gates has since been torn out and replaced with something better — we'll get to that one.
the regime-timing screener used to suppress Positive candidates outright whenever market_outlook was NEUTRAL or macro_regime was CAUTIOUS. Negative was untouched — the edge here was never symmetric. Here's what that looked like while it was still a hard gate:
This gate didn't come from one bad call — it came out of a scheduled weekly backtest job that re-checks every signal source's performance and flags anything trending negative in aggregate. And it wasn't a rare edge case: through the month it ran, "outlook is neutral" was true in 69 of 86 readings (80%), and "regime is cautious" was true in 84 of 89 readings (94%). Put together, this gate was active almost continuously — most of the Positive ideas this screener would otherwise have produced never got a chance to reach AI scoring at all.
signal_score bar — the same evidence-weighted 0-100 score covered in the signal_score deep dive — rather than being blocked before AI ever sees it. Every idea reaches scoring now; the ones that don't have the evidence to back a Positive call in a soft regime simply don't clear the higher bar once they get there. Blunt veto, retired in favor of a sharper one.the momentum-exhaustion screener suppresses Positive calls when outlook is POSITIVE or regime is AGGRESSIVE. The reasoning: stocks flagged oversold by this indicator keep falling while the index rips in a rallying tape — being "oversold" there often means correctly lagging, not due for a bounce. When the outlook read POSITIVE specifically, Positive hit rate was 22%, at -1.92% alpha at 5 days.
The honest follow-up: a later, broader test found this screener's Positive calls have no edge at all, regardless of regime — roughly 50% hit rate, negative alpha with or without the gate. The regime gate wasn't wrong, it just wasn't the real fix. The fleet moved to a strength ≥ 8 quality floor for Positive calls instead of relying on regime timing alone.
Both gates above trace back to the same day and the same audit — a routine weekly backtest run, not one bad outcome, flagged this screener's Positive ideas bleeding hardest in rallying tapes. Fifteen days later, a broader fleet-wide review re-ran the numbers and found the uncomfortable part: Positive calls from this screener showed no edge in any regime — roughly a coin-flip hit rate and negative alpha, gate on or off. The regime gate wasn't wrong exactly, it just wasn't solving the right variable: it only blocks Positive calls when the outlook reads POSITIVE or the regime reads AGGRESSIVE, but the weak signal was showing up everywhere, not just there. A strength ≥ 8 floor instead filters on the signal's own internal agreement — how many of RSI, MACD, trend, and volume actually point the same direction — so it catches a weak signal regardless of what the broader market is doing. This gate is still exactly what's live today, unchanged since it shipped.
In practice this gate rarely fires: the outlook=POSITIVE/regime=AGGRESSIVE condition it checks for has come up in only 2 of 127 runs tracked (about 1.6%) — a typical run considers around 11 raw candidates and sends roughly 3.5 through to AI scoring either way. Worth being upfront about what's actually measured here, too: hit rate and alpha against the S&P are the only two numbers tracked behind these gates — there's no Sharpe ratio, drawdown, or dollar P&L attribution yet. That's a real gap in the evidence, not just a caveat for later.
the sector-rotation screener skips generating Negative candidates when regime is AGGRESSIVE. This one isn't "this loses money" — it's "the strategy's own entry rules already block negative calls in this regime, so scoring these candidates is pure waste." No AI calls spent, nothing dead-ends in the discovery queue.
This one wasn't found by studying signal performance at all. It came out of debugging a stuck pipeline: an AI-written rule and a hardcoded regime check ended up contradicting each other and froze the system for several days. Tracing that deadlock back is what surfaced the real issue — the strategy's own entry rules already forbid a negative call in an aggressive market, so there was never a point in scoring those candidates in the first place.
This gate originally checked two conditions, RISK_ON or AGGRESSIVE. RISK_ON has since been dropped, and the reason is a good example of keeping a system honest: an audit found the downstream execution logic this gate was supposed to mirror has no RISK_ON case at all — the only real regime-based restriction on a negative call that exists downstream is an AGGRESSIVE-only conviction cap. Gating on a condition the rest of the system doesn't actually act on wasn't caution, it was just burning candidates for nothing. It's fair to ask how often the gate that's left actually fires: across the tracked runs, AGGRESSIVE regime came up zero times — 0 of 204 runs. It's never once suppressed a real candidate in production. That's not a flaw; it's a rule built for a condition the market simply hasn't produced yet. When it isn't gating anything, a typical run produces around 3.7 negative ideas and 3.7 positive ideas.
| Screener | Regime field / value | Reason class | Status today |
|---|---|---|---|
| the regime-timing screener | outlook=NEUTRAL / regime=CAUTIOUS | Edge suppression | Replaced by a signal_score floor |
| the momentum-exhaustion screener | outlook=POSITIVE / regime=AGGRESSIVE | Edge suppression + quality floor | Unchanged |
| the sector-rotation screener | regime=AGGRESSIVE | Execution alignment | Narrowed — RISK_ON dropped |
Three screeners, three different regime fields checked, two distinct classes of reason — but the same underlying architectural choice: check live regime state before scoring, not after. Contrast that against "screen everything, let the AI sort it out" — that approach wastes AI budget on proven-negative-EV candidates and forces the model to relearn the same regime caveat from scratch on every single call, instead of it being structurally true from the start.
None of these three gates were ever the whole admission story, and that's more true now than when this post first went up. All three screeners — along with most of the rest of the fleet — now also run every remaining candidate through a shared, source-agnostic admission check before AI scoring: a probabilistic pass keyed to each candidate's own technical posture, not a fixed cutoff anyone can game by nudging a number just above a line. The three cases above are the deliberate, hand-tuned exceptions layered on top of that general floor — not a replacement for it. Think of the shared check as the building's fire code, and these three regime gates as the extra locks a few specific rooms decided they needed on top of it.
If you're pulling from get_signals and notice a directional imbalance from a given source in a given week — say, zero Negative ideas from the sector-rotation screener during a hot rally — that's not randomness. It's this gating, visible from the outside as an absence rather than a signal.
These gates trust the regime classifier itself — market_outlook and macro_regime are themselves AI-generated judgments. A wrong regime call doesn't fail loudly — it silently suppresses good ideas before anyone, human or model, ever sees them. That's a real, unresolved tradeoff, not a solved problem. We're not dismissing it, and we're not oversold on it either.
A rule that blocks a candidate signal before it ever reaches AI scoring, based on the market's current regime — whether conditions read calm, choppy, or trending right now. It's a pre-filter, not a discount applied to the score after the fact.
That's usually a gate doing its job, not a coverage gap. If a screener produces zero Negative ideas during a hot rally, for example, its regime check is suppressing that whole category on purpose — it isn't failing to find anything.
Partly. One of the three — the regime-timing screener's — has been replaced with a stricter signal_score floor instead of a blanket suppression. The other two are unchanged. All three now sit on top of a shared, source-agnostic admission check that runs before AI scoring on most of the fleet.