Ora
All documentation Overview

Get started

IntroductionQuickstartHow ora-fin decidesHow to build with OraUse-case map

Rule language

OverviewGrammarOperators and beliefsPrices and offsetsWindowsIndicatorsSignals and eventsPattern functionsFunction referenceValues and = formulasBring your own barsRule libraryCommon mistakesError messagesEarnings, dividends and splits

Questions & answers

Questionsyes_no (noul)choicescoreConfidenceThresholds and calibrationStateAsk by symbol

Patterns

Patterns

Actions & workflows

OverviewRules and templatesDestinationsWebhooks and signaturesWorkflows

AI agents & SDKs

Use Ora from AI agents (MCP)SDKs: Python and JavaScriptOra Rules v1 (open spec)

API reference

POST /v1/systemonePOST /v1/automateGET /v1/models

Errors & limits

ErrorsRate limitsKnown limitations

Pricing

Pricing

Resources

FAQWhat's newModels & versionsCode in 8 languages

Docs / Rule language

Rule language

Bring your own bars

Rules, value questions and formulas normally run on a symbol's daily history from Ora's market data. Send state.bars instead and they run on your bars: a private instrument, a backtest slice, a custom index, intraday data, anything with a close.

In short
  • state.bars: an array of {"date", "open", "high", "low", "close", "volume"} (also o h l c v), oldest first, or {"columns": [...], "rows": [[...], ...]}.
  • Only close is required: open, high and low default to it, volume to 0. Up to 5,000 bars a request.
  • Dates are optional for daily bars (calendar functions and reading another symbol need them) and must strictly increase.
  • Intraday bars: add "interval": "5m" (1m, 5m, 15m, 30m, 1h) and a date with a time on every bar, such as "2026-10-30T09:35:00". Then vwap(), opening_range_high(), minutes_since_open() and time_of_day() work.
  • No symbol is needed. Earnings, dividend and split facts are not available on your bars; another symbol is: beta(60, 'SPY') lines SPY's daily bars up with yours by date.

Daily bars, no symbol

Request (state.bars shortened here: the request sent 60 bars (2 oldest and the newest shown).)

{
  "model": "ora-fin-0.1.1",
  "state": {
    "bars": [
      {
        "date": "2026-08-07",
        "open": 311.18,
        "high": 314.54,
        "low": 310.47,
        "close": 313.06,
        "volume": 34437191
      },
      {
        "date": "2026-08-10",
        "open": 306.83,
        "high": 308.26,
        "low": 304.63,
        "close": 308.26,
        "volume": 43391681
      },
      {
        "date": "2026-10-30",
        "open": 346.72,
        "high": 349.19,
        "low": 334.35,
        "close": 344.63,
        "volume": 67362573
      }
    ]
  },
  "questions": {
    "above20": {
      "type": "yes_no",
      "ask": "C > sma(C, 20)"
    },
    "rsi": {
      "type": "value",
      "ask": "rsi(C, 14)"
    },
    "stretch": {
      "type": "value",
      "ask": "zscore(C, 20)"
    },
    "monday": {
      "type": "value",
      "ask": "dayofweek()"
    },
    "beta": {
      "type": "value",
      "ask": "beta(40, 'SPY')"
    }
  }
}

Response (HTTP 200, session 2026-10-30)

{
  "model": "ora-fin-0.1.1",
  "answers": {
    "above20": {
      "type": "yes_no",
      "yes_no": 0.7481,
      "rule": "C > sma(C, 20)",
      "basis": "rule"
    },
    "rsi": {
      "type": "value",
      "value": 55.348664518,
      "rule": "rsi(C, 14)",
      "as_of": "2026-10-30"
    },
    "stretch": {
      "type": "value",
      "value": 0.5785420081,
      "rule": "zscore(C, 20)",
      "as_of": "2026-10-30"
    },
    "monday": {
      "type": "value",
      "value": 5,
      "rule": "dayofweek()",
      "as_of": "2026-10-30"
    },
    "beta": {
      "type": "value",
      "value": 0.2569830887,
      "rule": "beta(40, 'SPY')",
      "as_of": "2026-10-30"
    }
  },
  "usage": {
    "input_tokens": 3681,
    "output_tokens": 20
  },
  "version": "ora-text-0.2.0"
}

Columns and rows

The compact form: one array of column names and one array per bar.

Request (rows shortened here: the request sent 30 rows.)

{
  "model": "ora-fin-0.1.1",
  "state": {
    "bars": {
      "columns": [
        "date",
        "close"
      ],
      "rows": [
        [
          "2026-09-21",
          338.98
        ],
        [
          "2026-09-22",
          339.75
        ],
        [
          "2026-10-30",
          344.63
        ]
      ]
    }
  },
  "questions": {
    "ema10": {
      "type": "value",
      "ask": "ema(C, 10)"
    },
    "up5": {
      "type": "yes_no",
      "ask": "C > C[-5]"
    }
  }
}

Response (HTTP 200, session 2026-10-30)

{
  "model": "ora-fin-0.1.1",
  "answers": {
    "ema10": {
      "type": "value",
      "value": 344.8874451231,
      "rule": "ema(C, 10)",
      "as_of": "2026-10-30"
    },
    "up5": {
      "type": "yes_no",
      "yes_no": 0.2268,
      "rule": "C > C[-5]",
      "basis": "rule"
    }
  },
  "usage": {
    "input_tokens": 780,
    "output_tokens": 8
  },
  "version": "ora-text-0.2.0"
}

Intraday bars

Session functions reset on each new date in the timestamps; the clock is the timestamps' own time zone.

Request (state.bars shortened here: the request sent 78 bars (2 oldest and the newest shown).)

{
  "model": "ora-fin-0.1.1",
  "state": {
    "bars": [
      {
        "date": "2026-10-30T09:30:00",
        "open": 250,
        "high": 250.2,
        "low": 249.85,
        "close": 250.05,
        "volume": 20000
      },
      {
        "date": "2026-10-30T09:35:00",
        "open": 250.05,
        "high": 250.35,
        "low": 249.9,
        "close": 250.2,
        "volume": 20300
      },
      {
        "date": "2026-10-30T15:55:00",
        "open": 253.83,
        "high": 254.19,
        "low": 253.68,
        "close": 254.04,
        "volume": 20000
      }
    ],
    "interval": "5m"
  },
  "questions": {
    "above_vwap": {
      "type": "yes_no",
      "ask": "C > vwap()"
    },
    "vwap": {
      "type": "value",
      "ask": "vwap()"
    },
    "orh": {
      "type": "value",
      "ask": "opening_range_high(30)"
    },
    "broke_orh": {
      "type": "yes_no",
      "ask": "C > opening_range_high(30) and minutes_since_open() >= 30"
    },
    "clock": {
      "type": "value",
      "ask": "time_of_day()"
    }
  }
}

Response (HTTP 200, session 2026-10-30)

{
  "model": "ora-fin-0.1.1",
  "answers": {
    "above_vwap": {
      "type": "yes_no",
      "yes_no": 0.2421,
      "rule": "C > vwap()",
      "basis": "rule"
    },
    "vwap": {
      "type": "value",
      "value": 255.4062546288,
      "rule": "vwap()",
      "as_of": "2026-10-30"
    },
    "orh": {
      "type": "value",
      "value": 251.85,
      "rule": "opening_range_high(30)",
      "as_of": "2026-10-30"
    },
    "broke_orh": {
      "type": "yes_no",
      "yes_no": 0.8345,
      "rule": "C > opening_range_high(30) and minutes_since_open() >= 30",
      "basis": "rule"
    },
    "clock": {
      "type": "value",
      "value": 1555,
      "rule": "time_of_day()",
      "as_of": "2026-10-30"
    }
  },
  "usage": {
    "input_tokens": 5089,
    "output_tokens": 20
  },
  "version": "ora-text-0.2.0"
}

Validation

Bars are checked before anything runs; a problem is a 422 on state.bars naming the bar.

Request

{
  "model": "ora-fin-0.1.1",
  "state": {
    "bars": [
      {
        "date": "2026-10-29",
        "close": 101.2
      },
      {
        "date": "2026-10-28",
        "close": 100.4
      }
    ]
  },
  "questions": {
    "v": {
      "type": "value",
      "ask": "C"
    }
  }
}

Response (HTTP 422)

{
  "detail": [
    {
      "loc": [
        "body",
        "state",
        "bars"
      ],
      "type": "value_error",
      "msg": "bars[1]: dates must be strictly increasing (oldest first, no duplicates)"
    }
  ]
}

The bars are taken out of the state before the model reads it (the rules have already used them). Like everything else in a request, they count toward its input tokens.

Information, not investment advice. Beliefs and probabilities on this page are real responses for the session shown and change with every session.

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