---
title: "Alerts"
description: "An alert on an Indicator is a watch condition on one of its outputs: nothing in the file declares it, and every output, drawn or not, is a metric an alert can…"
order: 45
section: "functions"
---

<!-- source: docs/indicators/functions/alerts.md; generated by packages/cli/scripts/gen-indicator-docs.ts, do not edit -->

# Alerts

An alert on an Indicator is a watch condition on one of its outputs:
nothing in the file declares it, and every output, drawn or not, is a
metric an alert can watch once the package is installed on your machine (a
draft from `om indicator install`, or a published package from
`om install`). kScript (legacy) declared alerts in the script with
`alert()` and `alertcondition()` and ran them on the platform's hosted
engine; an Indicator's alert is a watch, evaluated by your daemon and
delivered to the channels you set up.

## A condition on a metric id

```bash
om watch create "SMA crossed above 100k" --condition '{"metric":"wrun/@you/my-sma/sma","params":{"period":20},"selector":{"symbol":"BTCUSDT","exchange":"BINANCE_FUTURES","interval":"HOUR"},"op":"crosses_above","value":100000}'
om watch create "Golden cross" --condition '{"left":{"metric":"wrun/@you/ma-cross/fast","params":{"fast":9,"slow":21},"selector":{"symbol":"BTCUSDT","exchange":"BINANCE_FUTURES","interval":"HOUR"}},"op":"crosses_above","right":{"metric":"wrun/@you/ma-cross/slow","params":{"fast":9,"slow":21},"selector":{"symbol":"BTCUSDT","exchange":"BINANCE_FUTURES","interval":"HOUR"}}}'
```

- The metric id is `wrun/@scope/name/<output>`, and the package's params
  travel as a `params` object (the `:k=v` suffix is the read commands'
  spelling).
- The operator is a level (`gt`, `lt`, ...) against a value, or an edge
  (`crosses_above`, `crosses_below`) read on the interval the selector
  names; an edge always needs `selector.interval`.
- A comparison puts an output on either side, edges included: a golden
  cross between one package's own `fast` and `slow` outputs, price crossing
  a package's band. Both sides name the same explicit interval, and a
  package under an edge must read its primary input on that interval: a
  package whose first input pins a coarser interval is refused at save time
  with `wrun_edge_primary_interval_mismatch`, so an alert can never arm and
  stay silent forever.
- A bindable package (an odds input declared `binding: "required"`) takes
  its market per use, as `sourceBindings` beside `params` on the operand.
- The watch pins the exact package version and module hash it was armed
  on. A newer install does not move it;
  `om indicator upgrade @you/my-sma --version 0.2.0` does.

```bash
om indicator upgrade @you/my-sma --version 0.2.0
```

## How it evaluates

Your daemon evaluates the watch on its heartbeat: closed bars once per bar,
so an edge is read at the close, and a source that reads the closed bar
takes the same cut on a package operand as on a built-in metric. After
downtime the runner re-evaluates the unseen closed bars (up to 7 days) with
the cooldown, once and edge gates applied at each bar's close; a package's
history is not replayed for that catch-up, and the gap digest names the
Indicator legs it could not verify.

The fast lane (`latency_class: "fast"`, a wake on every push-stream tick)
refuses a condition on an Indicator metric by name (`fast_lane_ineligible`):
a package computes over a window of bars, which a single tick does not
supply, so Indicator alerts ride the heartbeat lane.

Celled packages are a supported alert consumer: a `volume_profile` or `book`
input reads live at every evaluation. A `tape` input needs the running
daemon's buffer (a one-shot read refuses `wrun_tape_unavailable`), and
screens and backtests refuse celled packages by name
(`wrun_celled_metric_unsupported`). Removing a package warns when alerts
still reference its metrics.

Delivery is the watch's own setting: the channels you paired (`om setup
telegram`, Discord, Slack), the chat card, `--once` to fire a single time
and pause. The watch docs carry the rest (the send screen, cooldowns,
combining conditions).

## From the chart

An alert armed from the chart on a **published** Indicator runs on the
platform's hosted engine, beside the chart's kScript alerts, where the site
has Indicator alerts switched on (the chart says "Indicator alerts are not
enabled yet" while they are off). Today that lane reads the chart's own
candles only: a package that needs another source, a pinned market or
interval, or a celled class is refused there, and an alert on a draft is
refused with "Publish the Indicator before adding an alert". The watch on
your machine is the supported path for everything else.

Nearest form in the kScript docs: the `alert()` row of the construct table
on [From kScript](../migrations/from-kscript.md); the hosts and what each
reads are the table on
[Execution model](../core-concepts/execution-model.md).
