Guides / Financial decisions
Financial decisions · about 12 min
Write your own rule
Write a rule about a stock's price history, read the belief it returns, combine it with forecasts, and act on it daily.
- A signed-in account. Rules need a symbol in
state.
Pick a symbol
Any of the roughly 2,000 US stocks and ETFs covered by ask-by-symbol. This guide uses NVDA; every answer below is real, for the session of 2026-10-30.
Write a simple comparison
In the Playground, set the state to the symbol and add a yes_no question with
"ask"instead of"instructions":{ "model": "ora-fin1", "state": { "symbol": "NVDA" }, "questions": { "above_50d": { "type": "yes_no", "ask": "C > sma(C,50)" } } }Open this in the Playground{ "model": "ora-fin1", "answers": { "above_50d": { "type": "yes_no", "yes_no": 0.0746, "rule": "C > sma(C,50)", "basis": "rule" } }, "usage": { "input_tokens": 291, "output_tokens": 4 }, "context": { "source": "server", "symbol": "NVDA", "as_of": "2026-10-30" }, "version": "ora-fin-0.1.1" }Read the belief
above_50dis 0.0746: NVDA closed clearly under its 50-day average. A rule answer is a belief, not true/false: 0.50 is exactly on the line, and it moves toward 0.95 or 0.05 the further the reading is past the line, measured on that quantity's normal scale. SoC > sma(C,200)at 0.5455 means "above, but only just".Combine with and / or
Question Rule Belief above_200dC > sma(C,200)0.5455 rsi_uprsi(C,14) > 500.073 bothC > sma(C,200) and rsi(C,14) > 500.073 eitherC > sma(C,200) or rsi(C,14) > 500.5455 not_abovenot (C > sma(C,200))0.4545
Open this in the Playgroundandtakes the lower part (0.073),orthe higher (0.5455),notis 1 minus (0.4545). Ask the parts as their own questions too: it shows which one held a combined rule down.Offsets and windows
C[-3]is the close three bars ago. Windows take a period:sma(C,50),highest(C,20). The trap:maxincludes today,highestdoesn't. On XLE:Question Rule Belief breakoutC > highest(C,20)0.6462 neverC > max(C,20)0.5 at_highC >= max(C,20)0.5 up_3dC > C[-3]0.8947 XLE closed at a new 20-session high, so the breakout form is true while
Open this in the PlaygroundC > max(C,20)sits exactly on the line: it can never be more than equal.Pattern functions
Candlestick patterns are functions with no arguments. An English question about a pattern compiles to the same thing:
{ "model": "ora-fin1", "state": { "symbol": "NVDA" }, "questions": { "inside": { "type": "yes_no", "ask": "inside_bar()" }, "doji": { "type": "yes_no", "ask": "doji()" }, "hammer": { "type": "yes_no", "ask": "hammer()" }, "engulf_bear": { "type": "yes_no", "ask": "engulfing_bear()" }, "inside_en": { "type": "yes_no", "instructions": "Is today an inside bar?" } } }Question Belief basis inside0.0564 rule doji0.0735 rule hammer0.1245 rule engulf_bear0.0932 rule inside_en0.0564 pattern None of these patterns is present on NVDA's last bar. The full list is in Rule language.
Open this in the PlaygroundMix a rule with a forecast
A rule says what is true now; a forecast question says what is likely next. One request can hold both, and the next step's actions can use both:
{ "model": "ora-fin1", "state": { "symbol": "NVDA" }, "questions": { "trend": { "type": "yes_no", "ask": "C > sma(C,200)" }, "up_week": { "type": "yes_no", "instructions": "Will the stock be higher in a week?" }, "drop5": { "type": "yes_no", "instructions": "Will it drop at least 5% at some point in the next month?" } }, "actions": [ { "id": "lean_long", "when": "trend >= 0.6 and up_week >= 0.55", "do": "slack", "connection": "trading-desk", "message": "{{symbol}} ({{as_of}}): in trend ({{trend|pct}}) and leaning up a week ({{up_week|pct}})." }, { "id": "no_edge", "when": "else", "do": "slack", "connection": "trading-desk", "message": "{{symbol}} ({{as_of}}): no edge. Trend {{trend|pct}}, up a week {{up_week|pct}}, 5% drawdown {{drop5|pct}}." } ], "dry_run": true }Open this in the PlaygroundAct on it (dry run)
{ "model": "ora-fin1", "answers": { "trend": { "type": "yes_no", "yes_no": 0.5455, "rule": "C > sma(C,200)", "basis": "rule" }, "up_week": { "type": "yes_no", "yes_no": 0.527 }, "drop5": { "type": "yes_no", "yes_no": 0.523 } }, "usage": { "input_tokens": 355, "output_tokens": 12 }, "context": { "source": "server", "symbol": "NVDA", "as_of": "2026-10-30" }, "version": "ora-fin-0.1.1", "actions": [ { "id": "lean_long", "fired": false, "status": "skipped" }, { "id": "no_edge", "fired": true, "status": "dry_run", "do": "slack", "connection": "trading-desk", "preview": { "text": "NVDA (2026-10-30): no edge. Trend 55%, up a week 53%, 5% drawdown 52%." } } ] }trend0.5455 misses the 0.6 line, solean_longwas skipped andno_edgefired: the preview is exactly what Slack would get. Nothing was sent, because"dry_run": true.Run it daily as a workflow
Put the same questions and actions in a workflow with a list of symbols and a time (16:45 New York after the close, or 08:30 before the open), press Test run, then untick dry run. See Run a watchlist every day and Send a pre-open digest.