Skip to content

KB/alert

Screener Fresh Primed High-Conviction Digest

Last verified

Auto-generated. This article is rebuilt from app/signals/config/alert_thresholds.json by scripts/build_alerts_kb.py. Edit the alert config and re-run the script β€” do not edit this file directly.

Screener Fresh Primed High-Conviction Digest

Alert ID: SCREENER_FRESH_PRIMED_HIGH_DIGEST
Category: screener
Cross-detection: no

DAILY portfolio-level short list of every name in the screener run that is FRESH (status β€˜new’) AND has an archetype whose OWN row is at engine state β€˜primed’ AND carries conviction tier β€˜high’ β€” the operator’s daily probe list. ONE fire per ET day (720min = 12h cooldown, sentinel dedup key, not per-ticker), emitted by the screener pipeline (app/signals/screener_alerts.py), NOT by the macro alert engine. The 12h cooldown is what makes β€˜once a day’ deterministic: the screener runs at 10:30 and 17:30 ET, so the window must span the 7h intra-day gap (suppressing the second run) while clearing the ~17h gap to the next morning. A 24h cooldown measured from the last fire would instead be decided by run-time jitter β€” the next day’s 10:30 run sits fractionally under 24h from the prior 10:30 fire, so the digest would slip to the post-close run on most days. It exists because the per-ticker SCREENER_HIGH_CONVICTION fires one alert per name on one surface β€” easy to miss, and it says nothing about how today’s names sit together. CALIBRATION-GATED unlike SCREENER_EXITS_DIGEST: this is a trade-entry surface, so a name whose fresh-primed archetypes are all UNCALIBRATED is dropped from the list, and a list emptied that way fires nothing. The gate and the rendered hit-rate label are scoped to the archetypes that fired the setup, never the name’s whole fired set. Stays silent when no name qualifies (no zero-count message). Stricter than SCREENER_HIGH_CONVICTION by one leg β€” that alert fires on fresh + high conviction alone; the digest additionally requires a single row to be BOTH fresh and β€˜primed’.

Severity

INFO β€” positive signal or notable event; no action needed

Trigger condition

{
  "type": "computed",
  "computation": "screener_fresh_primed_high_digest"
}

Marker, not a rule the macro alert engine evaluates. app/signals/alerts.py:_eval_computed does not recognise screener_fresh_primed_high_digest, so the per-cycle evaluate_alerts loop returns False for it every cycle and this alert can never fire from the macro path.

The real trigger lives in app/signals/screener_alerts.py (emit_screener_alerts), which writes the alert row into the alerts table directly. It is fired from the screener run β€” emit_screener_alerts is a loud-not-fatal leg of run_screener (step 7, app/screener/pipeline.py). The definition stays in alert_thresholds.json so severity, message template, cooldown, the alerts_config admin surface, and this catalog all read from one place.

Message template

Screener: {count} fresh PRIMED high-conviction name(s) for {trade_date} β€” {ticker_summary}. Calibrated setups only; decision-support, not advice.

Rendered by app/signals/screener_alerts.py (_render_message) via Python str.format over the per-event context it builds for the fire, NOT the macro signals dict. A placeholder that fails to resolve falls back to the RAW template β€” the same posture as the macro engine’s _format_message.

Cooldown / dedup

Notifies

See also