Ora
All use cases All industries

Individuals

Retail investorActive day traderSwing traderOptions traderDividend investorLong-term passive investorCrypto traderFX traderCommodities traderSocial trading communityStudents and universities

Buy side

Financial advisor / RIAWealth managerFamily officeHedge fund PMQuant researcherPortfolio manager (long-only)Risk managerPrivate equityVC / growth investorFund-of-funds allocator

Sell side

Equity research analystSell-side sales traderExecution trader / deskMarket makerProp trading firmCompliance officer

Corporates

Investor relations teamCorporate treasuryCFO officeBank credit analystFinancial journalist / media

Builders

Quant developerFintech app builderRobo-advisorBroker appAlgo / bot developerData vendor / platformTrading educator / newsletter

Institutions

ETF issuerIndex providerInsurance investment officePension fundEndowmentSovereign wealth fund

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.

Answers were captured on 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.

ora-fin-0.1.1SPY4 questions2 actionsworkflow · Mon–Fri at 16:10 ET
  1. ScheduleMon–Fri at 16:10 ET
  2. StateSPY
  3. Questions4 asked
  4. Answersreal, captured
  5. Actions2 rules · dry run

State

{"symbol":"SPY"} The server fills in the latest completed session.

Questions

shockrulezscore(C / C[-1] - 1, 20) < -2
A two-sigma down day
fell3English → ruleDid the stock fall more than 3% today?
wideEnglish → ruleWas today's range more than 1.5 ATR?
vol_riseforecastWill volatility rise over the next 5 days?
Volatility rising over 5 days

Answers

QuestionAnswerReading
shock
A two-sigma down day
0.6995true
fell3
Did the stock fall more than 3% today
compiled to C / C[-1] - 1 < -0.03
0.0709false
wide
Was today's range more than 1.5 ATR
compiled to (H - L) > 1.5 * atr(14)
0.3689false
vol_rise
Volatility rising over 5 days
0.55856% · close to even

Actions

Rules on the answers decide what to send.

shock >= 0.6 or fell3 >= 0.6→Webhookbot-controller
else→Webhookbot-controller
What each action would send 1 of 2 fired · dry run, nothing sent
pausewould send (dry run)Webhook → bot-controller
{
  "command": "pause_all",
  "reason": "market_shock",
  "p_shock": 0.6995,
  "p_fell3": 0.0709,
  "as_of": "2026-10-30"
}
runrule false: skipped

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"
    }
  ]
}

atr offset zscore

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.

ora-fin-0.1.13 symbols, one request each4 questions
  1. State3 symbols
  2. Questions4 asked
  3. Answersreal, captured
  4. Actionsnone

State

{"symbol":"PG"} then KO, PEP, one request each. The server fills in the latest completed session.

Questions

exruledays_to_ex_div <= 30
Goes ex-dividend within 30 days
calmEnglish → ruleIs the 14-day ATR less than 2% of the price?
yieldEnglish → ruleIs the dividend yield above 3%?
drop5forecastWill it drop at least 5% at some point in the next month?
A 5% drawdown within a month

Answers

Symbolexrulecalmruleyieldruledrop5forecast
PG0.05370.78180.20910.357
KO0.20490.92020.05370.361
PEP0.05370.23670.94630.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"
  }
}

atr days_to_ex_div div_yield_ttm

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.

ora-fin-0.1.1AAPL4 questions1 action
  1. StateAAPL
  2. Questions4 asked
  3. Answersreal, captured
  4. Actions1 rule · dry run

State

{"symbol":"AAPL"} The server fills in the latest completed session.

Questions

soonruledays_to_earnings <= 5
earnings within 5 days
bigruleabs(last_earnings_move) > 3
last earnings reaction bigger than 3%
gapruleabs(last_earnings_gap) > 2
last earnings gap bigger than 2%
moveforecastWill there be a big move in either direction in the next 5 days?
A big move either way in 5 days

Answers

QuestionAnswerReading
soon
earnings within 5 days
0.7951true
big
last earnings reaction bigger than 3%
0.9463true
gap
last earnings gap bigger than 2%
0.9463true
move
A big move either way in 5 days
0.40941% · close to even

Actions

Rules on the answers decide what to send.

soon >= 0.6 and big >= 0.6→Webhookoptions-bot
What each action would send 1 of 1 fired · dry run, nothing sent
armwould send (dry run)Webhook → options-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"
        }
      }
    }
  ]
}

abs days_to_earnings last_earnings_gap last_earnings_move

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.

ora-fin-0.1.12 symbols, one request each4 questions
  1. State2 symbols
  2. Questions4 asked
  3. Answersreal, captured
  4. Actionsnone

State

{"symbol":"HON"} then GE, one request each. The server fills in the latest completed session.

Questions

cci_xrulecrossup(cci(20), 100)
CCI crossed above 100 today
trendruleC > sma(C, 50)
Above the 50-day average
adxruleadx(14) > 20 and diplus(14) > diminus(14)
Trending up (ADX over 20 and +DI over −DI)
up_weekforecastWill the stock be higher in a week?
Higher in a week

Answers

Symbolcci_xruletrendruleadxruleup_weekforecast
HON0.050.78990.1290.546
GE0.050.14310.55610.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"
  }
}

adx cci crossup diminus diplus sma

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.

ora-fin-0.1.13 symbols, one request each4 questions1 actionworkflow · Fri at 17:30 ET
  1. ScheduleFri at 17:30 ET
  2. State3 symbols
  3. Questions4 asked
  4. Answersreal, captured
  5. Actions1 rule · dry run

State

{"symbol":"SPY"} then QQQ, IWM, one request each. The server fills in the latest completed session.

Questions

trendEnglish → ruleIs the stock above its 200-day moving average?
hvEnglish → ruleIs 20-day historical volatility below 20%?
drop5forecastWill it drop at least 5% at some point in the next month?
A 5% drawdown within a month
vol_upforecastWill volatility be higher over the next month?
Higher volatility next month

Answers

Symboltrendrulehvruledrop5forecastvol_upforecastFired
SPY0.94510.94630.2030.69digest
QQQ0.79870.19560.4430.523digest
IWM0.55640.93870.2340.508digest

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
SPY 1 of 1 fired · dry run, nothing sent
digestwould send (dry run)Email → me
{
  "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%."
}
QQQ 1 of 1 fired · dry run, nothing sent
digestwould send (dry run)Email → me
{
  "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%."
}
IWM 1 of 1 fired · dry run, nothing sent
digestwould send (dry run)Email → me
{
  "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%."
      }
    }
  ]
}

log offset sma sqrt std

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.

ora-fin-0.1.1DE4 questions
  1. StateDE
  2. Questions4 asked
  3. Answersreal, captured
  4. Actionsnone

State

{"symbol":"DE"} The server fills in the latest completed session.

Questions

price_lowruleL < lowest(L, 20)
new 20-day low in price
obv_not_lowruleobv() > lowest(obv(), 20)
on-balance volume above its prior 20-day low
obv_upruleobv() > sma(obv(), 20)
On-balance volume above its 20-day average
up_weekforecastWill the stock be higher in a week?
Higher in a week

Answers

QuestionAnswerReading
price_low
new 20-day low in price
0.1204false
obv_not_low
on-balance volume above its prior 20-day low
0.9389true
obv_up
On-balance volume above its 20-day average
0.9015true
up_week
Higher in a week
0.53954% · 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"
  }
}

lowest obv sma

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.

ora-fin-0.1.1GS4 questions
  1. StateGS
  2. Questions4 asked
  3. Answersreal, captured
  4. Actionsnone

State

{"symbol":"GS"} The server fills in the latest completed session.

Questions

dojiruledoji()
doji candle: Body at most 10% of the day's range.
tinyrule(H - L) < 0.3 * atr(14)
today's range under a third of the ATR
toprule(C - L) / (H - L) > 0.75
Closed in the top quarter of the day's range
bottomrule(C - L) / (H - L) < 0.25
Closed in the bottom quarter of the day's range

Answers

QuestionAnswerReading
doji
doji candle: Body at most 10% of the day's range.
0.1397false
tiny
today's range under a third of the ATR
0.0608false
top
Closed in the top quarter of the day's range
0.1961false
bottom
Closed in the bottom quarter of the day's range
0.1339false

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"
  }
}

atr doji

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.

ora-fin-0.1.16 symbols, one request each3 questions
  1. State6 symbols
  2. Questions3 asked
  3. Answersreal, captured
  4. Actionsnone

State

{"symbol":"XLK"} then XLF, XLE, XLV, XLI, XLY, one request each. The server fills in the latest completed session.

Questions

rankrulepercentrank(roc(C, 20), 100) > 80
20-day return in the top fifth of its last 100 sessions
trendruleC > sma(C, 50)
Above the 50-day average
beat_spyforecastWill it beat SPY over the next month?
Beating SPY over a month

Answers

Symbolrankruletrendrulebeat_spyforecast
XLK0.05370.07760.498
XLF0.6270.66920.448
XLE0.76220.94320.55
XLV0.77680.94470.534
XLI0.07270.19750.441
XLY0.68660.81560.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"
  }
}

percentrank roc sma

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.

ora-fin-0.1.1DIA4 questions2 actions
  1. StateDIA
  2. Questions4 asked
  3. Answersreal, captured
  4. Actions2 rules · dry run

State

{"symbol":"DIA"} The server fills in the latest completed session.

Questions

cumrulecum(C > C[-1]) > cum(C < C[-1])
more up days than down days over the full history
long_trendruleC > mean(C, 200)
close above its 200-day mean
choppyrulesum(sign(C - C[-1]), 20) < 2
net up days over 20 sessions under 2
big_moveforecastWill there be a big move in either direction in the next 5 days?
A big move either way in 5 days

Answers

QuestionAnswerReading
cum
more up days than down days over the full history
0.9463true
long_trend
close above its 200-day mean
0.8778true
choppy
net up days over 20 sessions under 2
0.2573false
big_move
A big move either way in 5 days
0.41241% · close to even

Actions

Rules on the answers decide what to send.

long_trend >= 0.6 and choppy < 0.4→Webhookbot-controller
else→Webhookbot-controller
What each action would send 1 of 2 fired · dry run, nothing sent
mode_trendwould send (dry run)Webhook → bot-controller
{
  "symbol": "DIA",
  "mode": "trend_following",
  "as_of": "2026-10-30"
}
mode_revertrule false: skipped

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"
    }
  ]
}

cum mean offset sign sum

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.

ora-fin-0.1.1BAC4 questions
  1. StateBAC
  2. Questions4 asked
  3. Answersreal, captured
  4. Actionsnone

State

{"symbol":"BAC"} The server fills in the latest completed session.

Questions

outsideEnglish → ruleIs today an outside day?
tweezer_topruletweezer_top()
tweezer top candle: Green then red, with highs within 0.1%.
tweezer_bottomEnglish → ruleIs there a tweezer bottom on the last two candles?
key_revruleL < lowest(L, 10) and C > C[-1]
New 10-day low, but closed up on the day

Answers

QuestionAnswerReading
outside
Is today an outside day
compiled to outside_bar()
0.1566false
tweezer_top
tweezer top candle: Green then red, with highs within 0.1%.
0.1253false
tweezer_bottom
Is there a tweezer bottom on the last two candles
compiled to tweezer_bottom()
0.0806false
key_rev
New 10-day low, but closed up on the day
0.0952false

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"
  }
}

lowest offset outside_bar tweezer_bottom tweezer_top

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.

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