Ora
All guides All guides

Getting started

Your first decision in the Playground Call the API from your code Save, share and reuse queries

Financial decisions

Decide on a stock with just its symbol Write your own rule Read probabilities and choose thresholds

Rule playground

From English to rule Combining conditions Offsets and windows Reading beliefs Rules plus forecasts in one request Turning a rule into an alert or workflow

Automation

Send a Slack alert when a rule fires Send decisions to your own system Run a watchlist every day after the close

Production

Handle errors, rate limits and retries

Cookbooks

All cookbooks Rank a watchlist by probability Send a pre-open digest Trend filter plus entry trigger Breakout confirmation with volume RSI and Bollinger mean-reversion checks Gap-fill playbook to your order system Confidence-gated actions Detect two-way risk Size positions by volatility regime Risk guardrail before an order Ask many questions in one request Self-consistency: three wordings Route support tickets Is a headline relevant to a symbol?

Use cases

Tag financial news for trading signalsGuardrails for LLM appsSupport ticket triage and routingFilter retrieved passages before your LLM answersVerify claims and citations against a source

Guides / Cookbooks

Cookbooks · Signals: rules plus forecasts · Intermediate · about 8 min

Breakout confirmation with volume

Treat a close above the prior 20-session high as a breakout only when volume confirms it, and check whether the week ahead leans up.

  1. When to use it

    Breakouts on thin volume often fail. Writing the condition as one rule gives one belief; asking its two halves as separate questions in the same request shows which half is missing.

  2. The request

    highest(C,20) is the highest close of the 20 sessions before today, so C > highest(C,20) is a new closing high. avg(V,20) includes today.

    {
      "model": "ora-fin1",
      "state": {
        "symbol": "XLE"
      },
      "questions": {
        "breakout": {
          "type": "yes_no",
          "ask": "C > highest(C,20) and V > 1.5 * avg(V,20)"
        },
        "price_break": {
          "type": "yes_no",
          "ask": "C > highest(C,20)"
        },
        "volume_ok": {
          "type": "yes_no",
          "ask": "V > 1.5 * avg(V,20)"
        },
        "up_week": {
          "type": "yes_no",
          "instructions": "Will the stock be higher in a week?"
        },
        "rally5": {
          "type": "yes_no",
          "instructions": "Will it rally at least 5% at some point in the next month?"
        }
      },
      "actions": [
        {
          "id": "confirmed",
          "when": "breakout >= 0.6 and up_week >= 0.55",
          "do": "webhook",
          "connection": "my-oms",
          "body": {
            "symbol": "{{symbol}}",
            "signal": "breakout_confirmed",
            "p_breakout": "{{breakout}}",
            "p_up_week": "{{up_week}}",
            "as_of": "{{as_of}}"
          }
        }
      ],
      "dry_run": true
    }
    Open this in the Playground
  3. The real response

    XLE:

    {
      "model": "ora-fin1",
      "answers": {
        "breakout": {
          "type": "yes_no",
          "yes_no": 0.0647,
          "rule": "C > highest(C,20) and V > 1.5 * avg(V,20)",
          "basis": "rule"
        },
        "price_break": {
          "type": "yes_no",
          "yes_no": 0.6462,
          "rule": "C > highest(C,20)",
          "basis": "rule"
        },
        "volume_ok": {
          "type": "yes_no",
          "yes_no": 0.0647,
          "rule": "V > 1.5 * avg(V,20)",
          "basis": "rule"
        },
        "up_week": {
          "type": "yes_no",
          "yes_no": 0.592
        },
        "rally5": {
          "type": "yes_no",
          "yes_no": 0.491
        }
      },
      "usage": {
        "input_tokens": 429,
        "output_tokens": 20
      },
      "context": {
        "source": "server",
        "symbol": "XLE",
        "as_of": "2026-10-30"
      },
      "version": "ora-fin-0.1.1",
      "actions": [
        {
          "id": "confirmed",
          "fired": false,
          "status": "skipped"
        }
      ]
    }

    The price half is true (price_break 0.6462) but volume is not (volume_ok 0.0647), and and takes the lower of its parts, so breakout is 0.0647. AAPL is the mirror image: volume confirms (0.7437) but the close did not clear the high (0.3146), so breakout is 0.3146. Neither fires the confirmed action.

  4. The code

    Requires curl 7.76+. Save as run.sh, then: bash run.sh
    curl -sS https://oramodel.com/v1/systemone \
      -H "Authorization: Bearer $JEV_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
      "model": "ora-fin1",
      "state": {
        "symbol": "XLE"
      },
      "questions": {
        "breakout": {
          "type": "yes_no",
          "ask": "C > highest(C,20) and V > 1.5 * avg(V,20)"
        },
        "price_break": {
          "type": "yes_no",
          "ask": "C > highest(C,20)"
        },
        "volume_ok": {
          "type": "yes_no",
          "ask": "V > 1.5 * avg(V,20)"
        },
        "up_week": {
          "type": "yes_no",
          "instructions": "Will the stock be higher in a week?"
        },
        "rally5": {
          "type": "yes_no",
          "instructions": "Will it rally at least 5% at some point in the next month?"
        }
      },
      "actions": [
        {
          "id": "confirmed",
          "when": "breakout >= 0.6 and up_week >= 0.55",
          "do": "webhook",
          "connection": "my-oms",
          "body": {
            "symbol": "{{symbol}}",
            "signal": "breakout_confirmed",
            "p_breakout": "{{breakout}}",
            "p_up_week": "{{up_week}}",
            "as_of": "{{as_of}}"
          }
        }
      ],
      "dry_run": true
    }'
  5. Act on it

    Fire on the combined rule plus the forecast (the action above does this on our side), and log the halves so you can see later why a signal did or didn't fire:

    a = data["answers"]
    log.info("%s breakout=%.2f price=%.2f volume=%.2f up_week=%.3f", symbol,
             a["breakout"]["yes_no"], a["price_break"]["yes_no"], a["volume_ok"]["yes_no"], a["up_week"]["yes_no"])
  6. Variations

    • Stricter volume: V > 2 * avg(V,20).
    • A longer base: C > highest(C,55).
    • A crossing instead of a level: crossup(C, sma(C,50)) is true only on the day it happens.
    • Add rally5 to the when if you want the month's upside odds to agree too.

Information, not investment advice. Every number on this page is a real response for the session shown; answers change with each session.

What's next

Create an account Open the Playground Everything here also lives in the console, next to your keys and usage.