Guides / Cookbooks
Cookbooks · Screening and digests · Beginner · about 10 min
Rank a watchlist by probability
Ask the same three questions about every symbol on a list, send one request per symbol in parallel, and sort the list by the answers.
When to use it
You keep a list of 5 to 100 names and want a ranking after the close or before the open: which ones lean up for the week, and which ones have the widest monthly range. Each symbol is independent, so the requests can run side by side. For the same thing on a schedule with no code, see Send a pre-open digest.
The request
One request per symbol. Only
state.symbolchanges; the server fills in that symbol's latest completed session.{ "model": "ora-fin1", "state": { "symbol": "AAPL" }, "questions": { "rally5": { "type": "yes_no", "instructions": "Will it rally at least 5% at some point in the next month?" }, "drop5": { "type": "yes_no", "instructions": "Will it drop at least 5% at some point in the next month?" }, "up_week": { "type": "yes_no", "instructions": "Will the stock be higher in a week?" } } }Open this in the PlaygroundThe real response
For AAPL:
{ "model": "ora-fin1", "answers": { "rally5": { "type": "yes_no", "yes_no": 0.446 }, "drop5": { "type": "yes_no", "yes_no": 0.365 }, "up_week": { "type": "yes_no", "yes_no": 0.59 } }, "usage": { "input_tokens": 362, "output_tokens": 12 }, "context": { "source": "server", "symbol": "AAPL", "as_of": "2026-10-30" }, "version": "ora-fin-0.1.1" }All eight symbols, ranked by
up_week(session of 2026-10-30):Symbol up_week rally5 drop5 rally5 − drop5 XLE0.592 0.491 0.491 +0.000 AAPL0.59 0.446 0.365 +0.081 AMD0.577 0.836 0.763 +0.073 MSFT0.574 0.495 0.422 +0.073 QQQ0.561 0.501 0.443 +0.058 NVDA0.527 0.616 0.523 +0.093 AMZN0.493 0.536 0.462 +0.074 TSLA0.487 0.687 0.638 +0.049 The code
The single request in your language:
Requires curl 7.76+. Save as run.sh, then: bash run.shcurl -sS https://oramodel.com/v1/systemone \ -H "Authorization: Bearer $JEV_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "ora-fin1", "state": { "symbol": "AAPL" }, "questions": { "rally5": { "type": "yes_no", "instructions": "Will it rally at least 5% at some point in the next month?" }, "drop5": { "type": "yes_no", "instructions": "Will it drop at least 5% at some point in the next month?" }, "up_week": { "type": "yes_no", "instructions": "Will the stock be higher in a week?" } } }'The whole list, four requests at a time, ranked:
import os import requests URL = "https://oramodel.com/v1/systemone" HEADERS = {"Authorization": f"Bearer {os.environ['JEV_API_KEY']}"} from concurrent.futures import ThreadPoolExecutor SYMBOLS = ["AAPL","MSFT","NVDA","TSLA","AMZN","AMD","QQQ","XLE"] QUESTIONS = { "rally5": { "type": "yes_no", "instructions": "Will it rally at least 5% at some point in the next month?" }, "drop5": { "type": "yes_no", "instructions": "Will it drop at least 5% at some point in the next month?" }, "up_week": { "type": "yes_no", "instructions": "Will the stock be higher in a week?" } } def ask(symbol): r = requests.post(URL, headers=HEADERS, timeout=30, json={"model": "ora-fin1", "state": {"symbol": symbol}, "questions": QUESTIONS}) if r.status_code == 422: # symbol not covered: skip it return symbol, None r.raise_for_status() return symbol, {k: v["yes_no"] for k, v in r.json()["answers"].items()} with ThreadPoolExecutor(max_workers=4) as pool: rows = [(s, a) for s, a in pool.map(ask, SYMBOLS) if a] for s, a in sorted(rows, key=lambda r: r[1]["up_week"], reverse=True): print(f"{s:5} up_week {a['up_week']:.3f} rally5 {a['rally5']:.3f} drop5 {a['drop5']:.3f} skew {a['rally5'] - a['drop5']:+.3f}")In JavaScript (Node 18+):
const SYMBOLS = ["AAPL","MSFT","NVDA","TSLA","AMZN","AMD","QQQ","XLE"]; const QUESTIONS = { "rally5": { "type": "yes_no", "instructions": "Will it rally at least 5% at some point in the next month?" }, "drop5": { "type": "yes_no", "instructions": "Will it drop at least 5% at some point in the next month?" }, "up_week": { "type": "yes_no", "instructions": "Will the stock be higher in a week?" } }; async function ask(symbol) { const res = await fetch("https://oramodel.com/v1/systemone", { method: "POST", headers: { Authorization: `Bearer ${process.env.JEV_API_KEY}`, "Content-Type": "application/json" }, body: JSON.stringify({ model: "ora-fin1", state: { symbol }, questions: QUESTIONS }), }); if (res.status === 422) return null; // not covered if (!res.ok) throw new Error(`${symbol}: ${res.status}`); const { answers } = await res.json(); return { symbol, ...Object.fromEntries(Object.entries(answers).map(([k, v]) => [k, v.yes_no])) }; } const rows = (await Promise.all(SYMBOLS.map(ask))).filter(Boolean); rows.sort((a, b) => b.up_week - a.up_week); console.table(rows);Keep the pool small: limits are per organization and shared with the console. On a
429, waitRetry-Afterseconds (Handle errors and retries).Act on it
A ranking is relative. On this session the top
up_weekisXLEat 0.592 and the bottom isTSLAat 0.487: nothing is far from a coin flip on the week, so a sensible screen acts on none of them and just watches the top of the list. Decide the line first (for exampleup_week >= 0.62), then rank what clears it. Read probabilities and choose thresholds shows how.The other columns tell a different story.
AMDhas the highest odds of both a 5% rally and a 5% drop (84% and 76%): a wide range rather than a direction. That case has its own recipe, Detect two-way risk.Variations
- Rank by
rally5 − drop5to see which way the month's range leans. - Add a rule such as
{"type": "yes_no", "ask": "C > sma(C,200)"}and keep only names in an uptrend (Trend filter plus entry trigger). - Put all the questions you need into the one request per symbol, not one request per question (Ask many questions in one request).
- Run it every day without code as a workflow with a digest (Send a pre-open digest).
- Rank by
Information, not investment advice. Every number on this page is a real response for the session shown; answers change with each session.