// TRADERVIEW — WALKTHROUGH

Tutorial index Docs hub
Progress
11 / 18

11.Alerts, strategy alerts, & webhooks

Two alert layers: simple price/threshold rules, and AND/OR/NOT strategy alerts composed over them. Three delivery channels: in-app toast, Discord webhook, Slack webhook, generic JSON POST. Fires are logged, retried with backoff, and replayable.

Layer 1 — simple alerts

GET/POST /api/alerts. Each alert row is a (symbol, condition, threshold, status) tuple:

  • Price crosses above / below X.
  • % change from open / prior close / arbitrary anchor > X.
  • Volume > X / RVOL > X.
  • Indicator condition — any custom-indicator expression (step 10).
  • Time-of-day window — only fire between HH:MM and HH:MM ET.

Alerts evaluate against the live tick stream (step 06). Firing an alert pushes a row to alert_fires and dispatches the configured delivery (in-app toast at minimum; webhooks if attached). The alert row's status moves armed → fired; a manual toggle re-arms.

POST /api/alerts/{id}/toggle arms / disarms without deleting. POST /api/alerts/{id}/test sends a synthetic fire through the delivery chain so you can verify your Discord / Slack endpoint works without waiting for a real condition.

Layer 2 — strategy alerts (AND/OR/NOT)

GET/POST /api/strategy-alerts. A strategy alert is a boolean expression over base alerts:

// "AAPL gap-and-go signal"
(AAPL_price_above_premarket_high AND AAPL_rvol_above_3)
  AND NOT halt_AAPL
  AND time_window_0930_1030

The composer is a GUI tree builder — drag base alerts in, choose AND / OR / NOT at each branch. The expression compiles to stryke bytecode (same VM as backtest / custom indicators) and evaluates on every base-alert state change rather than every tick — much cheaper.

Fires are logged to strategy_alert_fires with the expression's evaluation trace (which base alerts were true, which were false, the time the eval flipped). GET /api/strategy-alerts/fires is the query endpoint; the view is a paginated list with re-fire / replay buttons.

Webhook delivery — Discord, Slack, generic

Webhooks live in their own table (webhooks) and attach to alerts / strategy alerts as delivery targets. Three preset types:

  • Discord — embeds with title / description / fields / color matching alert severity. Pings @here / @everyone configurable.
  • Slack — Block Kit payload with the same structured content. Channel routing via webhook URL.
  • Generic JSON — POST a templated JSON body to an arbitrary URL. Template variables include alert ID, symbol, price, condition, timestamp, fire ID. Custom headers supported (e.g. Authorization: Bearer … for your own backend).

Each webhook has a test buttonPOST /api/webhooks/{id}/test sends a fixed sample payload through. Use this when configuring the webhook URL the first time; you don't want to wait for a real alert to discover that you fat-fingered the URL.

Retry & dead-letter

Webhook POSTs that 5xx (or time out) are retried with exponential backoff: 5 s → 30 s → 5 min → 30 min → 2 h, capped at 5 attempts. After the cap the fire row is marked dead; the Webhooks view surfaces dead deliveries with a one-click manual-retry button.

4xx responses are not retried — a 401 from your Slack webhook means the URL is wrong; retrying makes it worse. The row is marked failed with the body of the 4xx response captured for debugging.

The Fires view

The Alerts → Fires view is a chronological log of every alert that fired in the date range. Each row shows the alert / strategy-alert that fired, the symbol, the price / value at fire time, the delivery status per channel, and a replay button that re-runs delivery (useful when you fix a webhook URL after a real fire was missed).

Right-click → Mute alert for 1 hr / today / forever when an alert is spamming. Re-arm later from the Alerts view.

What this composes with

  • TTS voice — the same in-app voice synth that reads halts / scanner spikes also reads alert fires. Per-alert toggle.
  • Browser notifications — under Tauri's custom scheme Notification.requestPermission can throw; wrapped in try/catch. In web mode notifications work normally if the user grants permission.
  • System tray — the desktop binary has an optional tray icon that flashes on alert fire (configurable).
Rate-limit your channels A custom indicator with a noisy boolean (firing on every bar) routed to Discord will get you rate-limited by Discord within minutes. Use per-channel cooldown (alert row → Min interval between fires) when you wire a custom indicator to webhook delivery.