Screener High-Conviction Candidate
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 High-Conviction Candidate
Alert ID: SCREENER_HIGH_CONVICTION
Category: screener
Cross-detection: no
A new single-name screener candidate appeared at conviction tier βhighβ. Fired per-ticker by the screener pipeline (app/signals/screener_alerts.py), NOT by the macro alert engine. Only fires when the candidateβs firing archetype is CALIBRATED (n>=30 matured samples) β uncalibrated archetypes never alert. The calibrated hit-rate is labeled in the message (honesty discipline).
Severity
INFO β positive signal or notable event; no action needed
Trigger condition
{
"type": "computed",
"computation": "screener_high_conviction"
}
Marker, not a rule the macro alert engine evaluates. app/signals/alerts.py:_eval_computed does not recognise screener_high_conviction, 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: {ticker} β new HIGH-conviction candidate (conviction {conviction}/100, regime {regime_tag}, {calibration_label}). Worth a look.
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: 1440 minutes (~24.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: per
(alert_id, ticker)β that pair is theidempotency_keyprefix, so two names alert independently while the same name re-flagging inside the cooldown is suppressed. The macro engineβs one-active-row-per-alert_idrule does not apply.
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