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 · Advanced · about 12 min

Gap-fill playbook to your order system

Send your own opening-gap numbers, ask whether the gap fills today or within five sessions, and route the answer to one of three playbooks in your order system.

You'll need
  1. When to use it

    You trade opening gaps and want one decision per gap: fade it intraday, hold for a fill over a few sessions, or stand aside. The gap numbers come from your own feed at the open, so they go in state.context; the server does not fill them.

  2. The request

    A real gap: AAPL gaps with the whole market: AAPL 2026-07-23 -1.3%. The three actions are exclusive: swing_fill requires that today's fill is unlikely, and else fires only when nothing else did.

    {
      "model": "ora-fin1",
      "state": {
        "symbol": "AAPL",
        "as_of": "2026-07-23",
        "context": {
          "gap_pct": -0.01278,
          "gap_dir": -1,
          "gap_atr": -0.51892,
          "gap_vs_typical": 3.66191,
          "gap_outside_range_atr": 0.20111,
          "earnings_day": 0,
          "earnings_next_5d": 0,
          "market_gap_pct": -0.01076,
          "gap_vs_market": -0.00202,
          "prior_return_1d": -0.00565,
          "prior_return_5d": -0.00492,
          "prior_return_20d": 0.10733,
          "prior_rsi_14": 62.55,
          "prior_dist_sma_20": 0.05104,
          "prior_dist_sma_50": 0.06889,
          "prior_dist_high_20": -0.02716,
          "prior_dist_low_20": 0.19048,
          "prior_close_location": 0.45053,
          "prior_volume_ratio": 0.59052,
          "volatility_20d": 0.37453,
          "atr_pct": 0.02462,
          "dollar_volume_log": 10.295,
          "beta_1y": 0.84395,
          "market_volatility_20d": 0.10645,
          "sym_gap_fill_rate": 0.24,
          "sym_gap_fill_rate_dir": 0.26,
          "sym_gap_fill_5d_rate": 0.58,
          "sym_gap_go_rate": 0.48,
          "sym_gaps_1y": 34
        }
      },
      "questions": {
        "fill_today": {
          "type": "yes_no",
          "instructions": "Will the gap fill today?"
        },
        "fill_5d": {
          "type": "yes_no",
          "instructions": "Will the gap fill within 5 sessions?"
        }
      },
      "actions": [
        {
          "id": "fade_today",
          "when": "fill_today >= 0.6",
          "do": "webhook",
          "connection": "my-oms",
          "body": {
            "symbol": "{{symbol}}",
            "playbook": "gap_fade_intraday",
            "p_fill_today": "{{fill_today}}",
            "gap_pct": "{{state.context.gap_pct}}",
            "as_of": "{{as_of}}"
          }
        },
        {
          "id": "swing_fill",
          "when": "fill_today < 0.6 and fill_5d >= 0.6",
          "do": "webhook",
          "connection": "my-oms",
          "body": {
            "symbol": "{{symbol}}",
            "playbook": "gap_fill_swing",
            "p_fill_5d": "{{fill_5d}}",
            "gap_pct": "{{state.context.gap_pct}}",
            "as_of": "{{as_of}}"
          }
        },
        {
          "id": "stand_aside",
          "when": "else",
          "do": "slack",
          "connection": "trading-desk",
          "message": "{{symbol}} gap {{as_of}}: no fill edge (today {{fill_today|pct}}, 5 sessions {{fill_5d|pct}}). Standing aside."
        }
      ],
      "dry_run": true
    }
    Open this in the Playground
  3. The real response

    {
      "model": "ora-fin1",
      "answers": {
        "fill_today": {
          "type": "yes_no",
          "yes_no": 0.431
        },
        "fill_5d": {
          "type": "yes_no",
          "yes_no": 0.801
        }
      },
      "usage": {
        "input_tokens": 734,
        "output_tokens": 8
      },
      "version": "ora-fin-0.1.1",
      "actions": [
        {
          "id": "fade_today",
          "fired": false,
          "status": "skipped"
        },
        {
          "id": "swing_fill",
          "fired": true,
          "status": "dry_run",
          "do": "webhook",
          "connection": "my-oms",
          "preview": {
            "body": {
              "symbol": "AAPL",
              "playbook": "gap_fill_swing",
              "p_fill_5d": 0.801,
              "gap_pct": -0.01278,
              "as_of": "2026-07-23"
            }
          }
        },
        {
          "id": "stand_aside",
          "fired": false,
          "status": "skipped"
        }
      ]
    }

    fill_today 0.431 is under the line, fill_5d 0.801 is well over it, so swing_fill fired and the preview is the exact body your system would receive. Numbers stay numbers: "{{fill_5d}}" arrives as 0.801.

    What happened afterwards, from the example's recorded outcome: the gap did not fill that day, and did fill within five sessions. One case is an illustration, not evidence; the Gap fill examples carry several more with outcomes.

  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": "AAPL",
        "as_of": "2026-07-23",
        "context": {
          "gap_pct": -0.01278,
          "gap_dir": -1,
          "gap_atr": -0.51892,
          "gap_vs_typical": 3.66191,
          "gap_outside_range_atr": 0.20111,
          "earnings_day": 0,
          "earnings_next_5d": 0,
          "market_gap_pct": -0.01076,
          "gap_vs_market": -0.00202,
          "prior_return_1d": -0.00565,
          "prior_return_5d": -0.00492,
          "prior_return_20d": 0.10733,
          "prior_rsi_14": 62.55,
          "prior_dist_sma_20": 0.05104,
          "prior_dist_sma_50": 0.06889,
          "prior_dist_high_20": -0.02716,
          "prior_dist_low_20": 0.19048,
          "prior_close_location": 0.45053,
          "prior_volume_ratio": 0.59052,
          "volatility_20d": 0.37453,
          "atr_pct": 0.02462,
          "dollar_volume_log": 10.295,
          "beta_1y": 0.84395,
          "market_volatility_20d": 0.10645,
          "sym_gap_fill_rate": 0.24,
          "sym_gap_fill_rate_dir": 0.26,
          "sym_gap_fill_5d_rate": 0.58,
          "sym_gap_go_rate": 0.48,
          "sym_gaps_1y": 34
        }
      },
      "questions": {
        "fill_today": {
          "type": "yes_no",
          "instructions": "Will the gap fill today?"
        },
        "fill_5d": {
          "type": "yes_no",
          "instructions": "Will the gap fill within 5 sessions?"
        }
      },
      "actions": [
        {
          "id": "fade_today",
          "when": "fill_today >= 0.6",
          "do": "webhook",
          "connection": "my-oms",
          "body": {
            "symbol": "{{symbol}}",
            "playbook": "gap_fade_intraday",
            "p_fill_today": "{{fill_today}}",
            "gap_pct": "{{state.context.gap_pct}}",
            "as_of": "{{as_of}}"
          }
        },
        {
          "id": "swing_fill",
          "when": "fill_today < 0.6 and fill_5d >= 0.6",
          "do": "webhook",
          "connection": "my-oms",
          "body": {
            "symbol": "{{symbol}}",
            "playbook": "gap_fill_swing",
            "p_fill_5d": "{{fill_5d}}",
            "gap_pct": "{{state.context.gap_pct}}",
            "as_of": "{{as_of}}"
          }
        },
        {
          "id": "stand_aside",
          "when": "else",
          "do": "slack",
          "connection": "trading-desk",
          "message": "{{symbol}} gap {{as_of}}: no fill edge (today {{fill_today|pct}}, 5 sessions {{fill_5d|pct}}). Standing aside."
        }
      ],
      "dry_run": true
    }'
  5. Act on it

    On the receiving side, verify X-Jev-Signature, ignore repeated X-Jev-Delivery ids, reply 2xx within 5 seconds, then map the playbook to an order template:

    PLAYBOOKS = {
        "gap_fade_intraday": lambda m: stage_order(m["symbol"], tif="day", note="fade"),
        "gap_fill_swing":   lambda m: stage_order(m["symbol"], tif="gtc", target="prior_close", max_days=5),
    }
    
    def on_delivery(msg):            # after the signature check
        PLAYBOOKS[msg["playbook"]](msg)   # staged for a person or your risk checks, not sent blind

    Test with "dry_run": true until the bodies look right, then send false.

  6. Variations

    • Different lines per gap size: put gap_pct in the rule, e.g. fill_today >= 0.55 for small gaps in a separate action.
    • Add Is this a gap-and-go day rather than a fade? as a third question and skip fades when it is high.
    • Send the stand-aside branch to Slack so the desk sees every gap, traded or not (it does in this request).

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.