Screener Fresh Primed High-Conviction Digest
Last verified
Auto-generated. This article is rebuilt from
app/signals/config/alert_thresholds.jsonbyscripts/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
- Cooldown: 720 minutes (~12.0 h) per dedup key, measured from the last fire. A repeat inside the window is suppressed entirely β no row is inserted and no webhook is dispatched.
- Dedup: portfolio-level β one fire per cooldown window against a fixed sentinel key, NOT per ticker (the two digests are the exceptions among the screener alerts; the other three fan out per name). A window in which nothing qualifies emits nothing rather than a zero-count message.
Notifies
- Active alert feed (
/api/v1/alerts/active,/alerts/summary). - SSE stream (
/api/v1/agents/stream) for real-time consumers. alert_firedwebhook on every genuinely-new insert (info-tier).- A duplicate suppressed by the cooldown dispatches nothing.
- The macro alert engine ignores this marker computation entirely β it neither fires, resolves, nor dispatches webhooks for this alert. The full lifecycle (fire, resolve, webhook) belongs to the owning module.
See also
- No simple field references β see
app/signals/screener_alerts.py(emit_screener_alerts) for the firing logic. - Alert reference
- Live alerts feed