[Alerts]
alert() / alertcondition() engine, host export, and L2 HTTP webhooks (Pro API + pyne-worker).
Alerts
Abstract
Pine alert() and alertcondition() fire into a host side-channel, not strategy events. The evaluator records structured firings with TradingView-style frequency rules. Hosts (Pro API and pyne-worker) export them on evaluate responses and can POST them to HTTP webhooks (roadmap L2).
Conceptual model
| Layer | Module |
|---|---|
| Engine | src/pynescript/ast/evaluator/builtins/alerts.py (export_alerts / export_alerts_from_evaluator) |
| Package host | src/pynescript/runtime/host.py (clear_alerts per run, alerts on the envelope) |
| Pro API webhook | backend/alert_forwarder.py (backend/runtime.py is only a Runtime re-export) |
| Edge host | sibling pyne-worker alert_engine.py + alert_forwarder.py |
Pine surface
alert(message, freq)
- Default
freq:alert.freq_once_per_bar(canonical tokenonce_per_bar). - Constants (also bare strings):
alert.freq_once_per_bar,alert.freq_once_per_bar_close,alert.freq_all. - once_per_bar — first fire per bar for the same (source, title, message, freq) key.
- once_per_bar_close — only when the host marks the bar confirmed (
barstate.isconfirmed/islast; hosts without barstate treat bars as confirmed). - all — every call.
alertcondition(condition, title, message)
- Records each evaluation in
alert_conditions(debug / UI). - When
conditionis true, also fires a host alert withsource: "alertcondition"and once-per-bar semantics.
Event shape (to_dict / API)
{
"message": "cross up",
"freq": "once_per_bar",
"bar_index": 42,
"time": 1700000000000,
"title": "optional",
"source": "alert"
}
source is "alert" or "alertcondition". Hosts stamp script_id / run_id (and edge cron may add symbol / timeframe).
Host export
Pro API (POST /run)
- Interpret path: full history of firings in
alerts(and optionalalert_conditions). - Compile path:
alerts: []today (alert side effects are interpret-only). - See POST /run.
pyne-worker
POST /runreturns the samealertsarray.- Cron filters to the last closed bar before webhook delivery so historical bars do not re-fire every minute.
- Health:
features.alerts,features.alert_webhooks.
L2 webhooks
Both hosts POST JSON to an HTTPS endpoint.
| Host | Default URL | Per-request / per-job |
|---|---|---|
| Pro API | env ALERT_WEBHOOK_URL | body webhook_url |
| pyne-worker | secret/var ALERT_WEBHOOK_URL | script/job webhook_url |
Pro API request flags
| Field | Default | Meaning |
|---|---|---|
webhook_url | "" | Override destination |
forward_alerts | true | Skip POST when false |
alert_last_bar | true | Only firings on the last OHLCV bar |
alert_batch | true | One batch body vs one POST per alert |
Optional timeout: env ALERT_WEBHOOK_TIMEOUT (seconds, default 10).
Batch body
{
"type": "pine_alert_batch",
"source": "pyne-pro-api",
"count": 1,
"content": "cross up",
"alerts": [
{
"type": "pine_alert",
"source": "pyne-pro-api",
"message": "cross up",
"freq": "once_per_bar",
"alert_source": "alert",
"bar_index": 42,
"time": 1700000000000
}
]
}
Edge worker uses "source": "pyne-worker". Discord-friendly content is set when a message is present.
Response meta
Successful /run may include:
"alert_forward": {
"forwarded": 1,
"failed": 0,
"filter": "last_bar",
"url": "https://hooks.example.com/pine",
"batch": true,
"count": 1
}
Webhook failures never fail the evaluate status; inspect alert_forward / alert_forward_error.
Worked example
curl -sS -X POST http://127.0.0.1:5002/run \
-H 'Content-Type: application/json' \
-d '{
"script": "//@version=6\nindicator(\"a\")\nif bar_index == last_bar_index\n alert(\"fire\")\nplot(close)",
"mode": "interpret",
"webhook_url": "https://hooks.example.com/pine",
"data": [
{"time": 1, "open": 1, "high": 2, "low": 0.5, "close": 1.5, "volume": 10},
{"time": 2, "open": 1.5, "high": 2.5, "low": 1.0, "close": 2.0, "volume": 12}
]
}'
Invariants
- Not strategy events — trade mesh uses
events[]; alerts are independent. - Per-run clear — hosts call
clear_alerts()so runs do not leak firings. - Last-bar default for webhooks — full-history still available in the
alertsresponse field. - Compile path — prefer
mode: "interpret"(or auto fallback) when you need alerts.