Use cases · Builders
Algo / bot developer: 20 ways to use Ora
Bots that read a signal, check risk and post an order, a message or nothing. Each example is a complete, runnable request with the real answers it returned (38 requests, captured 2026-10-31), what they mean and, where it fits, the action it would send.
ora-fin-0.1.1. Another model changes the request JSON and the Playground link; run it there to see its answers.Rule functions and facts used by this player (50)
sma 8offset 5atr 4rsi 3highest 3lowest 3roc 3avg 2crossup 2stochk 2abs 2max 2ref 2adx 2min 2std 2zscore 2crossdown 1willr 1swinglow 1engulfing_bull 1morning_star 1bblower 1bbmid 1bbupper 1linreg 1ema 1macd 1macdsignal 1stochd 1days_to_ex_div 1div_yield_ttm 1days_to_earnings 1last_earnings_gap 1last_earnings_move 1cci 1diminus 1diplus 1log 1sqrt 1obv 1doji 1percentrank 1cum 1mean 1sign 1sum 1outside_bar 1tweezer_bottom 1tweezer_top 1
Examples 11–20 of 20 · page 2 of 2
Algo / bot developer · example 11
Firm-wide kill switch for all bots when SPY has a shock day
Pause every bot when the market has a return shock or a very wide day, and resume when it is calm.
- ScheduleMon–Fri at 16:10 ET
- StateSPY
- Questions4 asked
- Answersreal, captured
- Actions2 rules · dry run
State
{"symbol":"SPY"} The server fills in the latest completed session.
Questions
shock | rule | zscore(C / C[-1] - 1, 20) < -2A two-sigma down day |
fell3 | English → rule | Did the stock fall more than 3% today? |
wide | English → rule | Was today's range more than 1.5 ATR? |
vol_rise | forecast | Will volatility rise over the next 5 days? Volatility rising over 5 days |
Answers
| Question | Answer | Reading |
|---|---|---|
shockA two-sigma down day | 0.6995 | true |
fell3Did the stock fall more than 3% today compiled to C / C[-1] - 1 < -0.03 | 0.0709 | false |
wideWas today's range more than 1.5 ATR compiled to (H - L) > 1.5 * atr(14) | 0.3689 | false |
vol_riseVolatility rising over 5 days | 0.558 | 56% · close to even |
Actions
Rules on the answers decide what to send.
shock >= 0.6 or fell3 >= 0.6→Webhookbot-controllerelse→Webhookbot-controller{
"command": "pause_all",
"reason": "market_shock",
"p_shock": 0.6995,
"p_fell3": 0.0709,
"as_of": "2026-10-30"
}What it means
For SPY on the session of 2026-10-30: True now: A two-sigma down day. Not true: Did the stock fall more than 3% today; Was today's range more than 1.5 ATR. Forecasts: Volatility rising over 5 days 56%. Fired: pause (Webhook → bot-controller).
The controller hears pause or run every session; bots never trade on a day the market-wide shock rule was true.
As a scheduled workflow (Mon–Fri at 16:10 ET)
Create it under Workflows in the console: it runs these questions for every symbol on the schedule and fires the actions per symbol. The answers above are what one run returned.
{
"name": "Firm-wide kill switch for all bots when SPY has a shock day",
"symbols": "SPY",
"days": [
1,
2,
3,
4,
5
],
"at_time": "16:10",
"model": "ora-fin-0.1.1",
"questions": {
"shock": {
"type": "yes_no",
"ask": "zscore(C / C[-1] - 1, 20) < -2"
},
"fell3": {
"type": "yes_no",
"instructions": "Did the stock fall more than 3% today?"
},
"wide": {
"type": "yes_no",
"instructions": "Was today's range more than 1.5 ATR?"
},
"vol_rise": {
"type": "yes_no",
"instructions": "Will volatility rise over the next 5 days?"
}
},
"actions": [
{
"id": "pause",
"when": "shock >= 0.6 or fell3 >= 0.6",
"do": "webhook",
"connection": "bot-controller",
"body": {
"command": "pause_all",
"reason": "market_shock",
"p_shock": "{{shock}}",
"p_fell3": "{{fell3}}",
"as_of": "{{as_of}}"
}
},
{
"id": "run",
"when": "else",
"do": "webhook",
"connection": "bot-controller",
"body": {
"command": "run",
"as_of": "{{as_of}}"
}
}
]
}Request JSON
{
"model": "ora-fin-0.1.1",
"state": {
"symbol": "SPY"
},
"questions": {
"shock": {
"type": "yes_no",
"ask": "zscore(C / C[-1] - 1, 20) < -2"
},
"fell3": {
"type": "yes_no",
"instructions": "Did the stock fall more than 3% today?"
},
"wide": {
"type": "yes_no",
"instructions": "Was today's range more than 1.5 ATR?"
},
"vol_rise": {
"type": "yes_no",
"instructions": "Will volatility rise over the next 5 days?"
}
},
"actions": [
{
"id": "pause",
"when": "shock >= 0.6 or fell3 >= 0.6",
"do": "webhook",
"connection": "bot-controller",
"body": {
"command": "pause_all",
"reason": "market_shock",
"p_shock": "{{shock}}",
"p_fell3": "{{fell3}}",
"as_of": "{{as_of}}"
}
},
{
"id": "run",
"when": "else",
"do": "webhook",
"connection": "bot-controller",
"body": {
"command": "run",
"as_of": "{{as_of}}"
}
}
],
"dry_run": true
}Response JSON (SPY, real)
{
"model": "ora-fin-0.1.1",
"answers": {
"shock": {
"yes_no": 0.6995,
"rule": "zscore(C / C[-1] - 1, 20) < -2",
"basis": "rule"
},
"fell3": {
"yes_no": 0.0709,
"rule": "C / C[-1] - 1 < -0.03",
"basis": "pattern"
},
"wide": {
"yes_no": 0.3689,
"rule": "(H - L) > 1.5 * atr(14)",
"basis": "pattern"
},
"vol_rise": {
"yes_no": 0.558
}
},
"context": {
"symbol": "SPY",
"as_of": "2026-10-30"
},
"actions": [
{
"id": "pause",
"fired": true,
"status": "dry_run",
"do": "webhook",
"connection": "bot-controller",
"preview": {
"body": {
"command": "pause_all",
"reason": "market_shock",
"p_shock": 0.6995,
"p_fell3": 0.0709,
"as_of": "2026-10-30"
}
}
},
{
"id": "run",
"fired": false,
"status": "skipped"
}
]
}Algo / bot developer · example 12
Dividend-capture screen for a bot: PG, KO and PEP
Find payers going ex-dividend soon with a calm price, the setup a dividend-capture bot needs.
- State3 symbols
- Questions4 asked
- Answersreal, captured
- Actionsnone
State
{"symbol":"PG"} then KO, PEP, one request each. The server fills in the latest completed session.
Questions
ex | rule | days_to_ex_div <= 30Goes ex-dividend within 30 days |
calm | English → rule | Is the 14-day ATR less than 2% of the price? |
yield | English → rule | Is the dividend yield above 3%? |
drop5 | forecast | Will it drop at least 5% at some point in the next month? A 5% drawdown within a month |
Answers
| Symbol | exrule | calmrule | yieldrule | drop5forecast |
|---|---|---|---|---|
PG | 0.0537 | 0.7818 | 0.2091 | 0.357 |
KO | 0.2049 | 0.9202 | 0.0537 | 0.361 |
PEP | 0.0537 | 0.2367 | 0.9463 | 0.418 |
true false not known for rules; forecasts are odds. Hover a column for its question.
What it means
Session of 2026-10-30, 3 symbols: Goes ex-dividend within 30 days: true for none of 3. Is the 14-day ATR less than 2% of the price: true for PG, KO of 3. Is the dividend yield above 3%: true for PEP of 3. Highest odds for “A 5% drawdown within a month”: PEP at 42%.
Capture only works when the price drop after the ex-date is small relative to the dividend; calm and low drawdown odds are the filters.
Request JSON (PG; the others differ only in the symbol)
{
"model": "ora-fin-0.1.1",
"state": {
"symbol": "PG"
},
"questions": {
"ex": {
"type": "yes_no",
"ask": "days_to_ex_div <= 30"
},
"calm": {
"type": "yes_no",
"instructions": "Is the 14-day ATR less than 2% of the price?"
},
"yield": {
"type": "yes_no",
"instructions": "Is the dividend yield above 3%?"
},
"drop5": {
"type": "yes_no",
"instructions": "Will it drop at least 5% at some point in the next month?"
}
}
}Response JSON (PG, real)
{
"model": "ora-fin-0.1.1",
"answers": {
"ex": {
"yes_no": 0.0537,
"rule": "days_to_ex_div <= 30",
"basis": "rule"
},
"calm": {
"yes_no": 0.7818,
"rule": "atr(14) / C < 0.02",
"basis": "pattern"
},
"yield": {
"yes_no": 0.2091,
"rule": "div_yield_ttm > 3",
"basis": "pattern"
},
"drop5": {
"yes_no": 0.357
}
},
"context": {
"symbol": "PG",
"as_of": "2026-10-30"
}
}Algo / bot developer · example 13
Gate for an earnings options bot on AAPL
Only arm an earnings-volatility bot when the report is close and the stock historically moves a lot on reports.
- StateAAPL
- Questions4 asked
- Answersreal, captured
- Actions1 rule · dry run
State
{"symbol":"AAPL"} The server fills in the latest completed session.
Questions
soon | rule | days_to_earnings <= 5earnings within 5 days |
big | rule | abs(last_earnings_move) > 3last earnings reaction bigger than 3% |
gap | rule | abs(last_earnings_gap) > 2last earnings gap bigger than 2% |
move | forecast | Will there be a big move in either direction in the next 5 days? A big move either way in 5 days |
Answers
| Question | Answer | Reading |
|---|---|---|
soonearnings within 5 days | 0.7951 | true |
biglast earnings reaction bigger than 3% | 0.9463 | true |
gaplast earnings gap bigger than 2% | 0.9463 | true |
moveA big move either way in 5 days | 0.409 | 41% · close to even |
Actions
Rules on the answers decide what to send.
soon >= 0.6 and big >= 0.6→Webhookoptions-bot{
"symbol": "AAPL",
"command": "arm_earnings",
"p_big_move5": 0.409,
"as_of": "2026-10-30"
}What it means
For AAPL on the session of 2026-10-30: True now: earnings within 5 days; last earnings reaction bigger than 3%; last earnings gap bigger than 2%. Forecasts: A big move either way in 5 days 41%. Fired: arm (Webhook → options-bot).
Facts about the calendar and past reactions arm the bot; the forecast is passed through so the bot can choose its size.
Request JSON
{
"model": "ora-fin-0.1.1",
"state": {
"symbol": "AAPL"
},
"questions": {
"soon": {
"type": "yes_no",
"ask": "days_to_earnings <= 5"
},
"big": {
"type": "yes_no",
"ask": "abs(last_earnings_move) > 3"
},
"gap": {
"type": "yes_no",
"ask": "abs(last_earnings_gap) > 2"
},
"move": {
"type": "yes_no",
"instructions": "Will there be a big move in either direction in the next 5 days?"
}
},
"actions": [
{
"id": "arm",
"when": "soon >= 0.6 and big >= 0.6",
"do": "webhook",
"connection": "options-bot",
"body": {
"symbol": "{{symbol}}",
"command": "arm_earnings",
"p_big_move5": "{{move}}",
"as_of": "{{as_of}}"
}
}
],
"dry_run": true
}Response JSON (AAPL, real)
{
"model": "ora-fin-0.1.1",
"answers": {
"soon": {
"yes_no": 0.7951,
"rule": "days_to_earnings <= 5",
"basis": "rule"
},
"big": {
"yes_no": 0.9463,
"rule": "abs(last_earnings_move) > 3",
"basis": "rule"
},
"gap": {
"yes_no": 0.9463,
"rule": "abs(last_earnings_gap) > 2",
"basis": "rule"
},
"move": {
"yes_no": 0.409
}
},
"context": {
"symbol": "AAPL",
"as_of": "2026-10-30"
},
"actions": [
{
"id": "arm",
"fired": true,
"status": "dry_run",
"do": "webhook",
"connection": "options-bot",
"preview": {
"body": {
"symbol": "AAPL",
"command": "arm_earnings",
"p_big_move5": 0.409,
"as_of": "2026-10-30"
}
}
}
]
}Algo / bot developer · example 14
CCI trend-entry bot on industrials: HON and GE
Enter industrial names when CCI crosses above 100 inside an uptrend.
- State2 symbols
- Questions4 asked
- Answersreal, captured
- Actionsnone
State
{"symbol":"HON"} then GE, one request each. The server fills in the latest completed session.
Questions
cci_x | rule | crossup(cci(20), 100)CCI crossed above 100 today |
trend | rule | C > sma(C, 50)Above the 50-day average |
adx | rule | adx(14) > 20 and diplus(14) > diminus(14)Trending up (ADX over 20 and +DI over −DI) |
up_week | forecast | Will the stock be higher in a week? Higher in a week |
Answers
| Symbol | cci_xrule | trendrule | adxrule | up_weekforecast |
|---|---|---|---|---|
HON | 0.05 | 0.7899 | 0.129 | 0.546 |
GE | 0.05 | 0.1431 | 0.5561 | 0.496 |
true false not known for rules; forecasts are odds. Hover a column for its question.
What it means
Session of 2026-10-30, 2 symbols: CCI crossed above 100 today: true for none of 2. Above the 50-day average: true for HON of 2. Trending up (ADX over 20 and +DI over −DI): true for none of 2. Highest odds for “Higher in a week”: HON at 55%.
The cross is the trigger and the trend rules are filters; the bot only trades symbols where all three line up.
Request JSON (HON; the others differ only in the symbol)
{
"model": "ora-fin-0.1.1",
"state": {
"symbol": "HON"
},
"questions": {
"cci_x": {
"type": "yes_no",
"ask": "crossup(cci(20), 100)"
},
"trend": {
"type": "yes_no",
"ask": "C > sma(C, 50)"
},
"adx": {
"type": "yes_no",
"ask": "adx(14) > 20 and diplus(14) > diminus(14)"
},
"up_week": {
"type": "yes_no",
"instructions": "Will the stock be higher in a week?"
}
}
}Response JSON (HON, real)
{
"model": "ora-fin-0.1.1",
"answers": {
"cci_x": {
"yes_no": 0.05,
"rule": "crossup(cci(20), 100)",
"basis": "rule"
},
"trend": {
"yes_no": 0.7899,
"rule": "C > sma(C, 50)",
"basis": "rule"
},
"adx": {
"yes_no": 0.129,
"rule": "adx(14) > 20 and diplus(14) > diminus(14)",
"basis": "rule"
},
"up_week": {
"yes_no": 0.546
}
},
"context": {
"symbol": "HON",
"as_of": "2026-10-30"
}
}Algo / bot developer · example 15
Weekly bot health digest by email
Every Friday, email the bot owner the state of each traded symbol: trend, volatility and drawdown odds.
- ScheduleFri at 17:30 ET
- State3 symbols
- Questions4 asked
- Answersreal, captured
- Actions1 rule · dry run
State
{"symbol":"SPY"} then QQQ, IWM, one request each. The server fills in the latest completed session.
Questions
trend | English → rule | Is the stock above its 200-day moving average? |
hv | English → rule | Is 20-day historical volatility below 20%? |
drop5 | forecast | Will it drop at least 5% at some point in the next month? A 5% drawdown within a month |
vol_up | forecast | Will volatility be higher over the next month? Higher volatility next month |
Answers
| Symbol | trendrule | hvrule | drop5forecast | vol_upforecast | Fired |
|---|---|---|---|---|---|
SPY | 0.9451 | 0.9463 | 0.203 | 0.69 | digest |
QQQ | 0.7987 | 0.1956 | 0.443 | 0.523 | digest |
IWM | 0.5564 | 0.9387 | 0.234 | 0.508 | digest |
true false not known for rules; forecasts are odds. Hover a column for its question.
Actions
Rules on the answers decide what to send. Each symbol runs its own request, so each one can fire.
trend >= 0→Emailme{
"subject": "Bot universe: SPY (2026-10-30)",
"text": "SPY: above 200-day 95%, calm volatility 95%, 5% drawdown odds 20%, higher volatility next month 69%."
}{
"subject": "Bot universe: QQQ (2026-10-30)",
"text": "QQQ: above 200-day 80%, calm volatility 20%, 5% drawdown odds 44%, higher volatility next month 52%."
}{
"subject": "Bot universe: IWM (2026-10-30)",
"text": "IWM: above 200-day 56%, calm volatility 94%, 5% drawdown odds 23%, higher volatility next month 51%."
}What it means
Session of 2026-10-30, 3 symbols: Is the stock above its 200-day moving average: true for SPY, QQQ of 3. Is 20-day historical volatility below 20%: true for SPY, IWM of 3. Highest odds for “A 5% drawdown within a month”: QQQ at 44%. digest fired for SPY, QQQ, IWM.
A weekly look at the regime each bot trades in helps decide which bots to leave running next week.
As a scheduled workflow (Fri at 17:30 ET)
Create it under Workflows in the console: it runs these questions for every symbol on the schedule and fires the actions per symbol. The answers above are what one run returned.
{
"name": "Weekly bot health digest by email",
"symbols": "SPY QQQ IWM",
"days": [
5
],
"at_time": "17:30",
"model": "ora-fin-0.1.1",
"questions": {
"trend": {
"type": "yes_no",
"instructions": "Is the stock above its 200-day moving average?"
},
"hv": {
"type": "yes_no",
"instructions": "Is 20-day historical volatility below 20%?"
},
"drop5": {
"type": "yes_no",
"instructions": "Will it drop at least 5% at some point in the next month?"
},
"vol_up": {
"type": "yes_no",
"instructions": "Will volatility be higher over the next month?"
}
},
"actions": [
{
"id": "digest",
"when": "trend >= 0",
"do": "email",
"connection": "me",
"subject": "Bot universe: {{symbol}} ({{as_of}})",
"message": "{{symbol}}: above 200-day {{trend|pct}}, calm volatility {{hv|pct}}, 5% drawdown odds {{drop5|pct}}, higher volatility next month {{vol_up|pct}}."
}
]
}Request JSON (SPY; the others differ only in the symbol)
{
"model": "ora-fin-0.1.1",
"state": {
"symbol": "SPY"
},
"questions": {
"trend": {
"type": "yes_no",
"instructions": "Is the stock above its 200-day moving average?"
},
"hv": {
"type": "yes_no",
"instructions": "Is 20-day historical volatility below 20%?"
},
"drop5": {
"type": "yes_no",
"instructions": "Will it drop at least 5% at some point in the next month?"
},
"vol_up": {
"type": "yes_no",
"instructions": "Will volatility be higher over the next month?"
}
},
"actions": [
{
"id": "digest",
"when": "trend >= 0",
"do": "email",
"connection": "me",
"subject": "Bot universe: {{symbol}} ({{as_of}})",
"message": "{{symbol}}: above 200-day {{trend|pct}}, calm volatility {{hv|pct}}, 5% drawdown odds {{drop5|pct}}, higher volatility next month {{vol_up|pct}}."
}
],
"dry_run": true
}Response JSON (SPY, real)
{
"model": "ora-fin-0.1.1",
"answers": {
"trend": {
"yes_no": 0.9451,
"rule": "C > sma(C, 200)",
"basis": "comparison"
},
"hv": {
"yes_no": 0.9463,
"rule": "std(log(C / C[-1]), 20) * sqrt(20 / 19) * sqrt(252) < 0.2",
"basis": "pattern"
},
"drop5": {
"yes_no": 0.203
},
"vol_up": {
"yes_no": 0.69
}
},
"context": {
"symbol": "SPY",
"as_of": "2026-10-30"
},
"actions": [
{
"id": "digest",
"fired": true,
"status": "dry_run",
"do": "email",
"connection": "me",
"preview": {
"subject": "Bot universe: SPY (2026-10-30)",
"text": "SPY: above 200-day 95%, calm volatility 95%, 5% drawdown odds 20%, higher volatility next month 69%."
}
}
]
}Algo / bot developer · example 16
OBV divergence detector for DE
Flag when price makes a 20-day low but on-balance volume does not, a bullish divergence some bots trade.
- StateDE
- Questions4 asked
- Answersreal, captured
- Actionsnone
State
{"symbol":"DE"} The server fills in the latest completed session.
Questions
price_low | rule | L < lowest(L, 20)new 20-day low in price |
obv_not_low | rule | obv() > lowest(obv(), 20)on-balance volume above its prior 20-day low |
obv_up | rule | obv() > sma(obv(), 20)On-balance volume above its 20-day average |
up_week | forecast | Will the stock be higher in a week? Higher in a week |
Answers
| Question | Answer | Reading |
|---|---|---|
price_lownew 20-day low in price | 0.1204 | false |
obv_not_lowon-balance volume above its prior 20-day low | 0.9389 | true |
obv_upOn-balance volume above its 20-day average | 0.9015 | true |
up_weekHigher in a week | 0.539 | 54% · close to even |
What it means
For DE on the session of 2026-10-30: True now: on-balance volume above its prior 20-day low; On-balance volume above its 20-day average. Not true: new 20-day low in price. Forecasts: Higher in a week 54%.
Divergence needs both rules true on the same bar; the forecast is a sanity check, not the trigger.
Request JSON
{
"model": "ora-fin-0.1.1",
"state": {
"symbol": "DE"
},
"questions": {
"price_low": {
"type": "yes_no",
"ask": "L < lowest(L, 20)"
},
"obv_not_low": {
"type": "yes_no",
"ask": "obv() > lowest(obv(), 20)"
},
"obv_up": {
"type": "yes_no",
"ask": "obv() > sma(obv(), 20)"
},
"up_week": {
"type": "yes_no",
"instructions": "Will the stock be higher in a week?"
}
}
}Response JSON (DE, real)
{
"model": "ora-fin-0.1.1",
"answers": {
"price_low": {
"yes_no": 0.1204,
"rule": "L < lowest(L, 20)",
"basis": "rule"
},
"obv_not_low": {
"yes_no": 0.9389,
"rule": "obv() > lowest(obv(), 20)",
"basis": "rule"
},
"obv_up": {
"yes_no": 0.9015,
"rule": "obv() > sma(obv(), 20)",
"basis": "rule"
},
"up_week": {
"yes_no": 0.539
}
},
"context": {
"symbol": "DE",
"as_of": "2026-10-30"
}
}Algo / bot developer · example 17
Bar-quality checks before a bot trades GS
Skip trading on odd bars: a doji, a tiny range or an extreme close, using the raw bar functions.
- StateGS
- Questions4 asked
- Answersreal, captured
- Actionsnone
State
{"symbol":"GS"} The server fills in the latest completed session.
Questions
doji | rule | doji()doji candle: Body at most 10% of the day's range. |
tiny | rule | (H - L) < 0.3 * atr(14)today's range under a third of the ATR |
top | rule | (C - L) / (H - L) > 0.75Closed in the top quarter of the day's range |
bottom | rule | (C - L) / (H - L) < 0.25Closed in the bottom quarter of the day's range |
Answers
| Question | Answer | Reading |
|---|---|---|
dojidoji candle: Body at most 10% of the day's range. | 0.1397 | false |
tinytoday's range under a third of the ATR | 0.0608 | false |
topClosed in the top quarter of the day's range | 0.1961 | false |
bottomClosed in the bottom quarter of the day's range | 0.1339 | false |
What it means
For GS on the session of 2026-10-30: Not true: doji candle: Body at most 10% of the day's range.; today's range under a third of the ATR; Closed in the top quarter of the day's range; Closed in the bottom quarter of the day's range.
Indecisive bars make poor signals; the bot can require none of these to be true before acting on any setup.
Request JSON
{
"model": "ora-fin-0.1.1",
"state": {
"symbol": "GS"
},
"questions": {
"doji": {
"type": "yes_no",
"ask": "doji()"
},
"tiny": {
"type": "yes_no",
"ask": "(H - L) < 0.3 * atr(14)"
},
"top": {
"type": "yes_no",
"ask": "(C - L) / (H - L) > 0.75"
},
"bottom": {
"type": "yes_no",
"ask": "(C - L) / (H - L) < 0.25"
}
}
}Response JSON (GS, real)
{
"model": "ora-fin-0.1.1",
"answers": {
"doji": {
"yes_no": 0.1397,
"rule": "doji()",
"basis": "rule"
},
"tiny": {
"yes_no": 0.0608,
"rule": "(H - L) < 0.3 * atr(14)",
"basis": "rule"
},
"top": {
"yes_no": 0.1961,
"rule": "(C - L) / (H - L) > 0.75",
"basis": "rule"
},
"bottom": {
"yes_no": 0.1339,
"rule": "(C - L) / (H - L) < 0.25",
"basis": "rule"
}
},
"context": {
"symbol": "GS",
"as_of": "2026-10-30"
}
}Algo / bot developer · example 18
Percentile momentum rotation bot across sector ETFs
Rank sectors by where their 20-day return sits in its own history, and rotate into the strongest.
- State6 symbols
- Questions3 asked
- Answersreal, captured
- Actionsnone
State
{"symbol":"XLK"} then XLF, XLE, XLV, XLI, XLY, one request each. The server fills in the latest completed session.
Questions
rank | rule | percentrank(roc(C, 20), 100) > 8020-day return in the top fifth of its last 100 sessions |
trend | rule | C > sma(C, 50)Above the 50-day average |
beat_spy | forecast | Will it beat SPY over the next month? Beating SPY over a month |
Answers
| Symbol | rankrule | trendrule | beat_spyforecast |
|---|---|---|---|
XLK | 0.0537 | 0.0776 | 0.498 |
XLF | 0.627 | 0.6692 | 0.448 |
XLE | 0.7622 | 0.9432 | 0.55 |
XLV | 0.7768 | 0.9447 | 0.534 |
XLI | 0.0727 | 0.1975 | 0.441 |
XLY | 0.6866 | 0.8156 | 0.41 |
true false not known for rules; forecasts are odds. Hover a column for its question.
What it means
Session of 2026-10-30, 6 symbols: 20-day return in the top fifth of its last 100 sessions: true for XLF, XLE, XLV, XLY of 6. Above the 50-day average: true for XLF, XLE, XLV, XLY of 6. Highest odds for “Beating SPY over a month”: XLE at 55%.
The bot holds the sectors whose rank rule is true and whose trend holds; the SPY forecast breaks ties.
Request JSON (XLK; the others differ only in the symbol)
{
"model": "ora-fin-0.1.1",
"state": {
"symbol": "XLK"
},
"questions": {
"rank": {
"type": "yes_no",
"ask": "percentrank(roc(C, 20), 100) > 80"
},
"trend": {
"type": "yes_no",
"ask": "C > sma(C, 50)"
},
"beat_spy": {
"type": "yes_no",
"instructions": "Will it beat SPY over the next month?"
}
}
}Response JSON (XLK, real)
{
"model": "ora-fin-0.1.1",
"answers": {
"rank": {
"yes_no": 0.0537,
"rule": "percentrank(roc(C, 20), 100) > 80",
"basis": "rule"
},
"trend": {
"yes_no": 0.0776,
"rule": "C > sma(C, 50)",
"basis": "rule"
},
"beat_spy": {
"yes_no": 0.498
}
},
"context": {
"symbol": "XLK",
"as_of": "2026-10-30"
}
}Algo / bot developer · example 19
A long-horizon regime switch for a bot: cumulative up days on DIA
Use cumulative counts and long averages to switch a bot between trend-following and mean-reversion modes.
- StateDIA
- Questions4 asked
- Answersreal, captured
- Actions2 rules · dry run
State
{"symbol":"DIA"} The server fills in the latest completed session.
Questions
cum | rule | cum(C > C[-1]) > cum(C < C[-1])more up days than down days over the full history |
long_trend | rule | C > mean(C, 200)close above its 200-day mean |
choppy | rule | sum(sign(C - C[-1]), 20) < 2net up days over 20 sessions under 2 |
big_move | forecast | Will there be a big move in either direction in the next 5 days? A big move either way in 5 days |
Answers
| Question | Answer | Reading |
|---|---|---|
cummore up days than down days over the full history | 0.9463 | true |
long_trendclose above its 200-day mean | 0.8778 | true |
choppynet up days over 20 sessions under 2 | 0.2573 | false |
big_moveA big move either way in 5 days | 0.412 | 41% · close to even |
Actions
Rules on the answers decide what to send.
long_trend >= 0.6 and choppy < 0.4→Webhookbot-controllerelse→Webhookbot-controller{
"symbol": "DIA",
"mode": "trend_following",
"as_of": "2026-10-30"
}What it means
For DIA on the session of 2026-10-30: True now: more up days than down days over the full history; close above its 200-day mean. Not true: net up days over 20 sessions under 2. Forecasts: A big move either way in 5 days 41%. Fired: mode_trend (Webhook → bot-controller).
Exactly one mode is sent per run, so the bot's behavior on any day can be traced to the rule state that chose it.
Request JSON
{
"model": "ora-fin-0.1.1",
"state": {
"symbol": "DIA"
},
"questions": {
"cum": {
"type": "yes_no",
"ask": "cum(C > C[-1]) > cum(C < C[-1])"
},
"long_trend": {
"type": "yes_no",
"ask": "C > mean(C, 200)"
},
"choppy": {
"type": "yes_no",
"ask": "sum(sign(C - C[-1]), 20) < 2"
},
"big_move": {
"type": "yes_no",
"instructions": "Will there be a big move in either direction in the next 5 days?"
}
},
"actions": [
{
"id": "mode_trend",
"when": "long_trend >= 0.6 and choppy < 0.4",
"do": "webhook",
"connection": "bot-controller",
"body": {
"symbol": "{{symbol}}",
"mode": "trend_following",
"as_of": "{{as_of}}"
}
},
{
"id": "mode_revert",
"when": "else",
"do": "webhook",
"connection": "bot-controller",
"body": {
"symbol": "{{symbol}}",
"mode": "mean_reversion",
"p_choppy": "{{choppy}}",
"as_of": "{{as_of}}"
}
}
],
"dry_run": true
}Response JSON (DIA, real)
{
"model": "ora-fin-0.1.1",
"answers": {
"cum": {
"yes_no": 0.9463,
"rule": "cum(C > C[-1]) > cum(C < C[-1])",
"basis": "rule"
},
"long_trend": {
"yes_no": 0.8778,
"rule": "C > mean(C, 200)",
"basis": "rule"
},
"choppy": {
"yes_no": 0.2573,
"rule": "sum(sign(C - C[-1]), 20) < 2",
"basis": "rule"
},
"big_move": {
"yes_no": 0.412
}
},
"context": {
"symbol": "DIA",
"as_of": "2026-10-30"
},
"actions": [
{
"id": "mode_trend",
"fired": true,
"status": "dry_run",
"do": "webhook",
"connection": "bot-controller",
"preview": {
"body": {
"symbol": "DIA",
"mode": "trend_following",
"as_of": "2026-10-30"
}
}
},
{
"id": "mode_revert",
"fired": false,
"status": "skipped"
}
]
}Algo / bot developer · example 20
Outside-bar and tweezer filter for a BAC swing bot
Flag reversal bars at extremes (outside bars, tweezers) that a bot uses to tighten stops.
- StateBAC
- Questions4 asked
- Answersreal, captured
- Actionsnone
State
{"symbol":"BAC"} The server fills in the latest completed session.
Questions
outside | English → rule | Is today an outside day? |
tweezer_top | rule | tweezer_top()tweezer top candle: Green then red, with highs within 0.1%. |
tweezer_bottom | English → rule | Is there a tweezer bottom on the last two candles? |
key_rev | rule | L < lowest(L, 10) and C > C[-1]New 10-day low, but closed up on the day |
Answers
| Question | Answer | Reading |
|---|---|---|
outsideIs today an outside day compiled to outside_bar() | 0.1566 | false |
tweezer_toptweezer top candle: Green then red, with highs within 0.1%. | 0.1253 | false |
tweezer_bottomIs there a tweezer bottom on the last two candles compiled to tweezer_bottom() | 0.0806 | false |
key_revNew 10-day low, but closed up on the day | 0.0952 | false |
What it means
For BAC on the session of 2026-10-30: Not true: Is today an outside day; tweezer top candle: Green then red, with highs within 0.1%.; Is there a tweezer bottom on the last two candles; New 10-day low, but closed up on the day.
These bars mark where the market changed its mind; the bot tightens stops on a true answer rather than opening new trades.
Request JSON
{
"model": "ora-fin-0.1.1",
"state": {
"symbol": "BAC"
},
"questions": {
"outside": {
"type": "yes_no",
"instructions": "Is today an outside day?"
},
"tweezer_top": {
"type": "yes_no",
"ask": "tweezer_top()"
},
"tweezer_bottom": {
"type": "yes_no",
"instructions": "Is there a tweezer bottom on the last two candles?"
},
"key_rev": {
"type": "yes_no",
"ask": "L < lowest(L, 10) and C > C[-1]"
}
}
}Response JSON (BAC, real)
{
"model": "ora-fin-0.1.1",
"answers": {
"outside": {
"yes_no": 0.1566,
"rule": "outside_bar()",
"basis": "pattern"
},
"tweezer_top": {
"yes_no": 0.1253,
"rule": "tweezer_top()",
"basis": "rule"
},
"tweezer_bottom": {
"yes_no": 0.0806,
"rule": "tweezer_bottom()",
"basis": "pattern"
},
"key_rev": {
"yes_no": 0.0952,
"rule": "L < lowest(L, 10) and C > C[-1]",
"basis": "rule"
}
},
"context": {
"symbol": "BAC",
"as_of": "2026-10-30"
}
}Information, not investment advice. Rules answer from the latest completed daily session; forecasts are probabilities. Actions ran as dry runs: nothing was sent. More in Builders: Quant developer, Fintech app builder, Robo-advisor, Broker app, Data vendor / platform, Trading educator / newsletter.