[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

LayerModule
Enginesrc/pynescript/ast/evaluator/builtins/alerts.py (export_alerts / export_alerts_from_evaluator)
Package hostsrc/pynescript/runtime/host.py (clear_alerts per run, alerts on the envelope)
Pro API webhookbackend/alert_forwarder.py (backend/runtime.py is only a Runtime re-export)
Edge hostsibling pyne-worker alert_engine.py + alert_forwarder.py

Pine surface

alert(message, freq)

  • Default freq: alert.freq_once_per_bar (canonical token once_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 condition is true, also fires a host alert with source: "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 optional alert_conditions).
  • Compile path: alerts: [] today (alert side effects are interpret-only).
  • See POST /run.

pyne-worker

  • POST /run returns the same alerts array.
  • 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.

HostDefault URLPer-request / per-job
Pro APIenv ALERT_WEBHOOK_URLbody webhook_url
pyne-workersecret/var ALERT_WEBHOOK_URLscript/job webhook_url

Pro API request flags

FieldDefaultMeaning
webhook_url""Override destination
forward_alertstrueSkip POST when false
alert_last_bartrueOnly firings on the last OHLCV bar
alert_batchtrueOne 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

  1. Not strategy events — trade mesh uses events[]; alerts are independent.
  2. Per-run clear — hosts call clear_alerts() so runs do not leak firings.
  3. Last-bar default for webhooks — full-history still available in the alerts response field.
  4. Compile path — prefer mode: "interpret" (or auto fallback) when you need alerts.

See also