DOCUMENTATION
Screener
Describe a setup in plain English, or set the bounds yourself. Either way the screen runs on live quotes and our own stored daily bars — and tells you, per query, exactly which of your criteria it enforced.
The boundary, stated once
Price, RSI, day change, ATR, distance below the 60-session high and sector are the filters it applies. Other criteria are ignored.
That sentence is not marketing copy with a caveat attached — it is derived from the filter engine itself, and a test fails the build if the two stop agreeing. Ask for something outside it and the results panel shows an Ignored chip naming what was dropped, rather than quietly returning rows that answer a narrower question than you asked.
Every filter
Ten numeric bounds and a sector list. All are optional; combining them narrows. A bound of 0 is a real bound, not an empty box.
| URL key | Meaning |
|---|---|
| min_price | Last traded price at or above this. |
| max_price | Last traded price at or below this. |
| min_rsi | RSI(14) at or above this — computed from our stored daily closes. |
| max_rsi | RSI(14) at or below this. Classic “oversold” is 30 and under. |
| min_change_pctsigned | Today’s percent change at or above this. Use a negative number for “down less than”. |
| max_change_pctsigned | Today’s percent change at or below this. “Down more than 2%” is −2. |
| min_atr_pct | ATR(14) at or above this percent of price — the wide-daily-range end. |
| max_atr_pct | ATR(14) at or below this percent of price — the calm end. |
| min_pct_from_high | At least this far below the 60-session high — the beaten-down end. |
| max_pct_from_high | No more than this far below the 60-session high. 0 means at the high. |
| sectors | One or more sectors from our universe. A symbol with no sector on record is excluded when you constrain sector — never admitted on a guess. |
Those keys are the URL, so any screen is a shareable link — and the same keys the API takes.
Where the numbers come from
Price and today’s change are live vendor quotes. RSI(14), ATR(14) and the 60-session high are computed here, from the 60 daily bars we store per symbol — not read from a vendor field, so they are reproducible and consistent across every surface.
A symbol whose history is too thin to compute a bound is excluded when you constrain that bound, and shows an em dash rather than a zero. The screener will drop a row before it will guess one.
Plain English, and when no model runs
A typed sentence is read by a language model, which extracts bounds from the list above; the response names which model did it. Setting the bounds yourself runs no model at all — the filters are already structured, so they are sent as-is and the screen is deterministic. The same filter engine applies them either way.
A model asked for “high-volume breakouts under $50” will happily invent a volume constraint. That is what the Ignored chips are for: the screen reports every bound it was handed and could not enforce.
What it deliberately cannot do
- · Not the whole market. A bounded universe of mega-caps plus the crypto majors our own feed streams. The results panel names the count it screened.
- · No fundamentals, no options flow, no float or short interest. We have no feed for them, and a filter with no data behind it would be a fabricated column.
- · No true 52-week high, and no earnings-date filter. Both are wanted; both need a deeper fetch than the bars a screen already loads, so neither is offered rather than approximated. The 60-session window is named for what it actually measures.
- · No advice. Rankings and postures describe indicator readings — see Technical Signal and Momentum Score, which publishes the formula and its scope: a description of the tape, not a forecast.
Freshness
The default ranked scan is cached and served straight from Redis for 60s, then refreshed off the request path; the page shows the real age of what you are looking at, and marks a scan served during a feed outage as stale rather than live. A custom screen always runs fresh against the snapshot.