Guides / Rule playground
Rule playground · about 10 min
Turning a rule into an alert or workflow
Put rules and forecasts in an action so Ora posts to Slack or your webhook when they line up, then run it over a watchlist every day.
Rules in the action's when
An action's
whencan use rule answers exactly like forecasts. Here a volatility rule and a drawdown forecast must agree before the desk is told:{ "model": "ora-fin1", "state": { "symbol": "AMD" }, "questions": { "above_50d": { "type": "yes_no", "ask": "C > sma(C, 50)" }, "wide_atr": { "type": "yes_no", "ask": "atr_pct(14) > 3" }, "drop5": { "type": "yes_no", "instructions": "Will it drop at least 5% at some point in the next month?" }, "up_week": { "type": "yes_no", "instructions": "Will the stock be higher in a week?" } }, "actions": [ { "id": "risk_alert", "when": "wide_atr >= 0.6 and drop5 >= 0.6", "do": "slack", "connection": "trading-desk", "message": "{{symbol}} ({{as_of}}): wide daily ranges ({{wide_atr|pct}}) and {{drop5|pct}} odds of a 5% drawdown within a month. Size down." }, { "id": "trend_ping", "when": "above_50d >= 0.6 and up_week >= 0.55", "do": "webhook", "connection": "my-oms", "body": { "symbol": "{{symbol}}", "signal": "trend_long_watch", "p_trend": "{{above_50d}}", "p_up_week": "{{up_week}}", "as_of": "{{as_of}}" } }, { "id": "quiet", "when": "else", "do": "slack", "connection": "trading-desk", "message": "{{symbol}} ({{as_of}}): nothing to do." } ], "dry_run": true }Open this in the PlaygroundDry run
With
"dry_run": truenothing is sent; the response shows what would be (AMD, 2026-10-30):{ "model": "ora-fin1", "answers": { "above_50d": { "type": "yes_no", "yes_no": 0.1909, "rule": "C > sma(C, 50)", "basis": "rule" }, "wide_atr": { "type": "yes_no", "yes_no": 0.9441, "rule": "atr_pct(14) > 3", "basis": "rule" }, "drop5": { "type": "yes_no", "yes_no": 0.763 }, "up_week": { "type": "yes_no", "yes_no": 0.577 } }, "usage": { "input_tokens": 389, "output_tokens": 16 }, "context": { "source": "server", "symbol": "AMD", "as_of": "2026-10-30" }, "version": "ora-fin-0.1.1", "actions": [ { "id": "risk_alert", "fired": true, "status": "dry_run", "do": "slack", "connection": "trading-desk", "preview": { "text": "AMD (2026-10-30): wide daily ranges (94%) and 76% odds of a 5% drawdown within a month. Size down." } }, { "id": "trend_ping", "fired": false, "status": "skipped" }, { "id": "quiet", "fired": false, "status": "skipped" } ] }Fired:
risk_alert. The preview is exactly the Slack text.Send it
Add a Slack or webhook connection under Settings → Connections, then send the same body with
"dry_run": false. Deliveries show under Actions. Step by step: Send a Slack alert when a rule fires.Every day, on a watchlist
A workflow runs the same questions and actions for each symbol after the close, with one digest per run. The template Rule scan: breakouts and breakdowns (Examples → Workflows) is two exact rules plus a forecast:
{ "name": "Rule scan: breakouts and breakdowns", "symbols": "AAPL MSFT NVDA AMZN META XLE XLF XLK", "days": [ 1, 2, 3, 4, 5 ], "at_time": "16:50", "model": "ora-fin1", "questions": { "breakout": { "type": "yes_no", "ask": "C > highest(C, 20) and V > 1.5 * ref(avg(V, 20), -1)" }, "breakdown": { "type": "yes_no", "ask": "C < lowest(C, 20)" }, "up_week": { "type": "yes_no", "instructions": "Will the stock be higher in a week?" } }, "actions": [ { "id": "breakout", "when": "breakout >= 0.6", "do": "slack", "connection": "trading-desk", "message": "{{symbol}} ({{as_of}}): 20-day breakout on volume ({{breakout|pct}}); higher in a week {{up_week|pct}}." }, { "id": "breakdown", "when": "breakdown >= 0.6", "do": "slack", "connection": "trading-desk", "message": "{{symbol}} ({{as_of}}): closed under its 20-day low ({{breakdown|pct}})." } ], "digest": { "do": "slack", "connection": "trading-desk", "when": "fired" } }Saving a workflow validates it with a dry run on one symbol. The same check on XLE (2026-10-30):
{ "model": "ora-fin1", "answers": { "breakout": { "type": "yes_no", "yes_no": 0.0692, "rule": "C > highest(C, 20) and V > 1.5 * ref(avg(V, 20), -1)", "basis": "rule" }, "breakdown": { "type": "yes_no", "yes_no": 0.0537, "rule": "C < lowest(C, 20)", "basis": "rule" }, "up_week": { "type": "yes_no", "yes_no": 0.592 } }, "usage": { "input_tokens": 365, "output_tokens": 12 }, "context": { "source": "server", "symbol": "XLE", "as_of": "2026-10-30" }, "version": "ora-fin-0.1.1", "actions": [ { "id": "breakout", "fired": false, "status": "skipped" }, { "id": "breakdown", "fired": false, "status": "skipped" } ] }Test, then let it run
Test run shows each symbol's answers and what would be sent; untick dry run when you are happy. Runs skip holidays and stale data, so alerts never repeat on old sessions (Workflows).
Information, not investment advice. Every number on this page is a real response for the session shown; answers change with each session.