Skip to content

KB/framework

The Screener System — S1 → S2 → S3 Vision

Last verified

This is the why. For the mechanics — funnel stages, gate config, refresh cadences, the demotion cost-split, the data tables — see Screener Pipeline & Lifecycle (operations). For what each pattern looks for, see the archetype pages.

What the screener is for

The screener exists to do one thing well: take a large, noisy universe of liquid names and surface a small, high-conviction shortlist of dislocated single-name setups — then collect deep data on those names so the operator can act with confidence and so the platform accumulates a permanent, labeled history of “what a real setup looked like, and what happened next.”

It is not a list of everything that twitched. A wall of 200 candidates is noise wearing the costume of thoroughness. The job is to be the filter, not the firehose.

The three stages

The system has a single spine — an automatic data tier that deepens as a name proves it deserves attention — plus one manual control the operator owns.

S1 — the universe (hidden muck)

The full screen universe: the S&P 900 (S&P 500 + S&P 400 MidCap, ~903 names), config-driven via screener_config.json → universe.tier. This is the raw material — index-curated, liquid, and otherwise undifferentiated. It is hidden by design. The operator never browses S1; the screener’s whole value is that it reads S1 so you don’t have to. Every S1 name is run through every archetype on each screener pass. S1 carries only the cheap data needed to score it (daily OHLCV); nothing deep.

S2 — the screener shortlist (auto-selected, ~20, floating)

The names that survive the archetype gates. There is no hard cap. The count floats — a calm tape yields a handful, a genuine dislocation yields more — and that is a feature, not a bug: the board should surface more when there is genuinely more to surface. The target is intense gates that naturally leave ~20, not a [:30] slice applied after the fact. The “dial” that controls quality is the gate configuration, not a truncation.

S2 names get the deep datafeed refresh (options chain, estimates, sentiment, gamma) and appear on the screener board — the discovery surface. Promotion into and demotion out of S2 is automatic, driven entirely by whether a name clears the gates on a given pass.

S3 — the watchlist (manual, permanent)

S3 splits along a second axis (see below). The visible half is the operator’s permanent watchlist — the dropdown of names you actually care about. A name enters it only when the operator clicks Promote, and it stays until the operator clicks Demote. The screener never adds or removes names from your dropdown. This keeps the interface stable and uncluttered: you are never digging through a constantly-rotating list of names you didn’t choose.

The key insight: two orthogonal axes

The design that makes this work cleanly is separating data collection (automatic) from interface visibility (manual). They never fight.

Data tier — automatic Visibility — manual
Driven by the screener gates the operator’s Promote / Demote
Controls what data we collect + how often we refresh what appears in the watchlist dropdown
Range S1 → S2 → hidden-S3 pinned / not pinned

A name can be in any combination:

So: data collection is fully automatic (S1 → S2 → hidden-S3); the dropdown is 100% operator-curated and stable. The screener feeds the data; you curate the view.

Why a floating funnel beats a hard cap

A hard “top 30” cap is a crude patch — it discards the 31st name even when it is a genuine setup, and it pads the list to 30 even when only 5 names qualify. Both are lies about the state of the market. Tuning the gates instead means the board always tells the truth: it is short when opportunity is thin and longer when a real dislocation event hits multiple names at once. The operator reads the count itself as signal.

A drift alarm guards the dial: if a pass yields 0 or more than ~50 survivors, that is the gates slipping, not the market moving — it logs loudly so the thresholds get re-tuned rather than silently degrading.

Demotion keeps everything — and keeps it smart

When a name is automatically demoted from S2, nothing is ever deleted (retention is sacred — see the operations page). But we stop spending on it:

Freezing a demoted name entirely would blind us to the very thing we’re trying to measure. The cheap-daily-bar split is the cost-vs-signal sweet spot.

Macro overlay — don’t fight the tape (context only)

Every candidate carries two macro context tags: the prevailing regime and a sector-rotation read. The rotation tag asks one question — is the sector-rotation tape with this name or against it? A name whose GICS sector is being rotated into gets a tailwind; a sector being rotated out of gets a headwind; in between reads neutral. The read is derived from the same cyclical-vs-defensive sector-breadth rotation the macro dashboard shows, so the screener and the dashboard agree.

This is context only — never a hard filter and never a conviction input. The overlay does not drop a candidate or change its conviction; it surfaces the macro weather so the operator can decide whether a setup is worth taking against the rotation. When a sector is missing from the rotation breadth (or the macro read is unavailable), the tag honestly abstains () rather than guessing a neutral.

The predictive payoff

Every screener pass writes an append-only archetype-fire event log — per (ticker, trade_date, archetype, state, score, triggers), kept forever. Joined to the S2 promotion / demotion timestamps and the retained forward price paths, this becomes a labeled dataset: “names that fired this archetype combination, at this confluence, then did X over the next N days.” That history is the raw material for backtesting the archetypes and for the Historical Analogs layer. We collect everything now precisely because we cannot know today which slice will matter later.

Where pitfalls arise