Docs / Rule language
Rule language
Values and = formulas
The rule language is not only for yes/no rules. Ask for the number any expression produces with a value question, and put = formulas straight into state so the model sees computed numbers instead of ones you had to fetch.
{"type": "value", "ask": "sma(C, 50)"}answers{"type": "value", "value": …, "rule": …, "as_of": …}. Any expression works: a function, arithmetic such as(C - sma(C, 20)) / atr(14), a named fact such asdays_to_earnings.- A
valueof a rule (a comparison,and/or) is 1 when it holds and 0 when it does not, and also carries itsbelief. - Any string in
statethat starts with=is a formula:"close": "=C","rsi": "=rsi(C, 14)","up": "=C > sma(C, 50)". It is evaluated for the request's symbol (or your own bars) before the model reads the state: a number stays a number, a rule becomes its belief. - Plain numbers you put in
statecan be read by name in rules:"stop": 410and"ask": "C < stop". - A formula or value that cannot be evaluated is a 422 naming it. Value questions, formulas and rules all need a symbol or your own bars.
Value questions
One request can mix value questions, rules and English questions. Each value answer is the expression's number on the latest completed session; the as_of says which.
Request
{
"model": "ora-fin-0.1.1",
"state": {
"symbol": "NVDA"
},
"questions": {
"sma50": {
"type": "value",
"ask": "sma(C, 50)"
},
"rsi": {
"type": "value",
"ask": "rsi(C, 14)"
},
"stretch": {
"type": "value",
"ask": "(C - sma(C, 20)) / atr(14)"
},
"beta": {
"type": "value",
"ask": "beta(60, 'SPY')"
},
"trend": {
"type": "value",
"ask": "C > sma(C, 50)"
},
"above200": {
"type": "yes_no",
"ask": "C > sma(C, 200)"
}
}
}Response (HTTP 200, session 2026-10-30)
{
"model": "ora-fin-0.1.1",
"answers": {
"sma50": {
"type": "value",
"value": 221.6848,
"rule": "sma(C, 50)",
"as_of": "2026-10-30"
},
"rsi": {
"type": "value",
"value": 35.0656112288,
"rule": "rsi(C, 14)",
"as_of": "2026-10-30"
},
"stretch": {
"type": "value",
"value": -2.7161849863,
"rule": "(C - sma(C, 20)) / atr(14)",
"as_of": "2026-10-30"
},
"beta": {
"type": "value",
"value": 2.1459234891,
"rule": "beta(60, 'SPY')",
"as_of": "2026-10-30"
},
"trend": {
"type": "value",
"value": 0,
"rule": "C > sma(C, 50)",
"belief": 0.0746,
"as_of": "2026-10-30"
},
"above200": {
"type": "yes_no",
"yes_no": 0.5455,
"rule": "C > sma(C, 200)",
"basis": "rule"
}
},
"usage": {
"input_tokens": 423,
"output_tokens": 24
},
"context": {
"source": "server",
"symbol": "NVDA",
"as_of": "2026-10-30"
},
"version": "ora-fin-0.1.1"
}
A value cannot be read while an indicator is still warming up (for example sma(C, 2000) on 1,500 sessions): that is a 422, not a guess. Use nz(x, default) if you want a fallback.
= formulas in state
Write the numbers you want the model to weigh as formulas instead of computing them yourself. Each one runs in the same engine call as the rules, so a request with ten formulas costs one round trip.
Request
{
"model": "ora-fin-0.1.1",
"state": {
"symbol": "TSLA",
"close": "=C",
"rsi": "=rsi(C, 14)",
"hv20": "=hv(C, 20)",
"up": "=C > sma(C, 50)",
"dd": "=drawdown(C, 252)"
},
"questions": {
"drop": {
"type": "yes_no",
"instructions": "Will it drop at least 5% at some point in the next month?"
},
"squeeze": {
"type": "yes_no",
"ask": "squeeze(20)"
}
}
}Response (HTTP 200, session 2026-10-30)
{
"model": "ora-fin-0.1.1",
"answers": {
"drop": {
"type": "yes_no",
"yes_no": 0.611
},
"squeeze": {
"type": "yes_no",
"yes_no": 0.05,
"rule": "squeeze(20)",
"basis": "rule"
}
},
"usage": {
"input_tokens": 390,
"output_tokens": 8
},
"context": {
"source": "server",
"symbol": "TSLA",
"as_of": "2026-10-30"
},
"version": "ora-fin-0.1.1"
}
The model sees the state with the results in place: "close": 512.3, "up": 0.88. Formulas are read from the top level of state; symbol, context, bars and interval are never formulas.
Your numbers inside rules
Numbers in state are readable by name, so a rule can compare the market with your own levels: a stop, an entry, a target.
Request
{
"model": "ora-fin-0.1.1",
"state": {
"symbol": "SPY",
"stop": 640,
"target": 720
},
"questions": {
"stopped": {
"type": "yes_no",
"ask": "L < stop"
},
"room": {
"type": "value",
"ask": "(target - C) / atr(14)"
}
}
}Response (HTTP 200, session 2026-10-30)
{
"model": "ora-fin-0.1.1",
"answers": {
"stopped": {
"type": "yes_no",
"yes_no": 0.0537,
"rule": "L < stop",
"basis": "rule",
"facts": {
"stop": 640
}
},
"room": {
"type": "value",
"value": -4.6180013849,
"rule": "(target - C) / atr(14)",
"as_of": "2026-10-30",
"facts": {
"target": 720
}
}
},
"usage": {
"input_tokens": 321,
"output_tokens": 8
},
"context": {
"source": "server",
"symbol": "SPY",
"as_of": "2026-10-30"
},
"version": "ora-fin-0.1.1"
}
When it goes wrong
A bad formula is a 422 whose loc is the state key:
Request
{
"model": "ora-fin-0.1.1",
"state": {
"symbol": "SPY",
"rsi": "=rsii(C, 14)"
},
"questions": {
"q": {
"type": "yes_no",
"ask": "C > O"
}
}
}Response (HTTP 422)
{
"detail": [
{
"loc": [
"body",
"state",
"rsi"
],
"msg": "Formula `=rsii(C, 14)`: Unknown function 'rsii()'. Did you mean rsi()?",
"type": "formula_error"
}
]
}
Every function you can use is in the Function reference.
Information, not investment advice. Beliefs and probabilities on this page are real responses for the session shown and change with every session.