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
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 aparamsobject (the:k=vsuffix 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 needsselector.interval. - A comparison puts an output on either side, edges included: a golden
cross between one package's own
fastandslowoutputs, 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 withwrun_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, assourceBindingsbesideparamson 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.0does.
om indicator upgrade @you/my-sma --version 0.2.0How 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; the hosts and what each
reads are the table on
Execution model.