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

Robo-advisor: 20 ways to use Ora

Automated portfolios: rebalancing triggers, tax-loss harvesting candidates and risk dials. Each example is a complete, runnable request with the real answers it returned (43 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 (25)

sma 16offset 9max 7atr 6ref 5log 4sqrt 4std 4pays_dividend 3div_yield_ttm 2lowest 2macd 1macdsignal 1zscore 1div_count_ttm 1roc 1min 1adx 1diminus 1diplus 1avg 1bblower 1cci 1ema 1rsi 1

Examples 1–10 of 20 · page 1 of 2

Robo-advisor · example 1

Rebalancing trigger for a stock/bond model: VTI and BND

Decide whether the nightly rebalancer should run for a sleeve, using drawdown and trend states instead of a fixed calendar.

ora-fin-0.1.12 symbols, one request each4 questions2 actions
  1. State2 symbols
  2. Questions4 asked
  3. Answersreal, captured
  4. Actions2 rules · dry run

State

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

Questions

ddruleC < 0.8 * max(H, 252)
More than 20% off the 52-week high
down_monthEnglish → ruleIs the stock down more than 5% over the last month?
up_10_3mEnglish → ruleIs the stock up more than 10% over the last three months?
trendEnglish → ruleIs the stock above its 200-day moving average?

Answers

Symbolddruledown_monthruleup_10_3mruletrendruleFired
VTI0.05370.06620.05370.9415skip
BND0.05370.05370.05370.2013skip

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.

dd >= 0.6 or down_month >= 0.6 or up_10_3m >= 0.6→Webhookrebalancer
else→Webhookrebalancer
VTI 1 of 2 fired · dry run, nothing sent
rebalancerule false: skipped
skipwould send (dry run)Webhook → rebalancer
{
  "sleeve": "VTI",
  "action": "skip",
  "as_of": "2026-10-30"
}
BND 1 of 2 fired · dry run, nothing sent
rebalancerule false: skipped
skipwould send (dry run)Webhook → rebalancer
{
  "sleeve": "BND",
  "action": "skip",
  "as_of": "2026-10-30"
}

What it means

Session of 2026-10-30, 2 symbols: More than 20% off the 52-week high: true for none of 2. Is the stock down more than 5% over the last month: true for none of 2. Is the stock up more than 10% over the last three months: true for none of 2. Is the stock above its 200-day moving average: true for VTI of 2. rebalance fired for none. skip fired for VTI, BND.

A big move in either direction asks the rebalancer to check its bands; a quiet sleeve is skipped, which saves trades and taxes.

Request JSON (VTI; the others differ only in the symbol)
{
  "model": "ora-fin-0.1.1",
  "state": {
    "symbol": "VTI"
  },
  "questions": {
    "dd": {
      "type": "yes_no",
      "ask": "C < 0.8 * max(H, 252)"
    },
    "down_month": {
      "type": "yes_no",
      "instructions": "Is the stock down more than 5% over the last month?"
    },
    "up_10_3m": {
      "type": "yes_no",
      "instructions": "Is the stock up more than 10% over the last three months?"
    },
    "trend": {
      "type": "yes_no",
      "instructions": "Is the stock above its 200-day moving average?"
    }
  },
  "actions": [
    {
      "id": "rebalance",
      "when": "dd >= 0.6 or down_month >= 0.6 or up_10_3m >= 0.6",
      "do": "webhook",
      "connection": "rebalancer",
      "body": {
        "sleeve": "{{symbol}}",
        "action": "check_bands",
        "p_drawdown20": "{{dd}}",
        "p_down5_month": "{{down_month}}",
        "p_up10_3m": "{{up_10_3m}}",
        "as_of": "{{as_of}}"
      }
    },
    {
      "id": "skip",
      "when": "else",
      "do": "webhook",
      "connection": "rebalancer",
      "body": {
        "sleeve": "{{symbol}}",
        "action": "skip",
        "as_of": "{{as_of}}"
      }
    }
  ],
  "dry_run": true
}
Response JSON (VTI, real)
{
  "model": "ora-fin-0.1.1",
  "answers": {
    "dd": {
      "yes_no": 0.0537,
      "rule": "C < 0.8 * max(H, 252)",
      "basis": "rule"
    },
    "down_month": {
      "yes_no": 0.0662,
      "rule": "C / C[-21] - 1 < -0.05",
      "basis": "pattern"
    },
    "up_10_3m": {
      "yes_no": 0.0537,
      "rule": "C / C[-63] - 1 > 0.1",
      "basis": "pattern"
    },
    "trend": {
      "yes_no": 0.9415,
      "rule": "C > sma(C, 200)",
      "basis": "comparison"
    }
  },
  "context": {
    "symbol": "VTI",
    "as_of": "2026-10-30"
  },
  "actions": [
    {
      "id": "rebalance",
      "fired": false,
      "status": "skipped"
    },
    {
      "id": "skip",
      "fired": true,
      "status": "dry_run",
      "do": "webhook",
      "connection": "rebalancer",
      "preview": {
        "body": {
          "sleeve": "VTI",
          "action": "skip",
          "as_of": "2026-10-30"
        }
      }
    }
  ]
}

max offset sma

Robo-advisor · example 2

Tax-loss harvesting candidates among international funds

Flag funds trading well below where clients likely bought them, so the harvester can evaluate a swap into a similar fund.

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

State

{"symbol":"VEA"} then VWO, EFA, EEM, VXUS, one request each. The server fills in the latest completed session.

Questions

down_3mruleC < C[-63] * 0.93
down more than 7% from three months ago
below_200English → ruleIs the stock below its 200-day moving average?
ddruleC < 0.8 * max(H, 252)
More than 20% off the 52-week high
rally5forecastWill it rally at least 5% at some point in the next month?
A 5% rally within a month

Answers

Symboldown_3mrulebelow_200ruleddrulerally5forecast
VEA0.06440.41230.05370.261
VWO0.23070.91130.05370.283
EFA0.08610.32910.05370.181
EEM0.20330.85510.07180.49
VXUS0.07470.67450.05370.269

true false not known for rules; forecasts are odds. Hover a column for its question.

What it means

Session of 2026-10-30, 5 symbols: down more than 7% from three months ago: true for none of 5. Is the stock below its 200-day moving average: true for VWO, EEM, VXUS of 5. More than 20% off the 52-week high: true for none of 5. Highest odds for “A 5% rally within a month”: EEM at 49%.

Price rules only find candidates; the harvester still checks each client's lots and wash-sale windows before acting.

Request JSON (VEA; the others differ only in the symbol)
{
  "model": "ora-fin-0.1.1",
  "state": {
    "symbol": "VEA"
  },
  "questions": {
    "down_3m": {
      "type": "yes_no",
      "ask": "C < C[-63] * 0.93"
    },
    "below_200": {
      "type": "yes_no",
      "instructions": "Is the stock below its 200-day moving average?"
    },
    "dd": {
      "type": "yes_no",
      "ask": "C < 0.8 * max(H, 252)"
    },
    "rally5": {
      "type": "yes_no",
      "instructions": "Will it rally at least 5% at some point in the next month?"
    }
  }
}
Response JSON (VEA, real)
{
  "model": "ora-fin-0.1.1",
  "answers": {
    "down_3m": {
      "yes_no": 0.0644,
      "rule": "C < C[-63] * 0.93",
      "basis": "rule"
    },
    "below_200": {
      "yes_no": 0.4123,
      "rule": "C < sma(C, 200)",
      "basis": "comparison"
    },
    "dd": {
      "yes_no": 0.0537,
      "rule": "C < 0.8 * max(H, 252)",
      "basis": "rule"
    },
    "rally5": {
      "yes_no": 0.261
    }
  },
  "context": {
    "symbol": "VEA",
    "as_of": "2026-10-30"
  }
}

max offset sma

Robo-advisor · example 3

Nightly risk dial for the equity sleeve (SPY)

Move a three-position risk dial (normal, cautious, defensive) from trend and volatility rules plus the drawdown forecast.

ora-fin-0.1.1SPY5 questions3 actionsworkflow · Mon–Fri at 17:00 ET
  1. ScheduleMon–Fri at 17:00 ET
  2. StateSPY
  3. Questions5 asked
  4. Answersreal, captured
  5. Actions3 rules · dry run

State

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

Questions

trendEnglish → ruleIs the stock above its 200-day moving average?
sma_uprulesma(C, 200) > ref(sma(C, 200), -20)
The 200-day average is rising
hvEnglish → ruleIs 20-day historical volatility above 25%?
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

QuestionAnswerReading
trend
Is the stock above its 200-day moving average
compiled to C > sma(C, 200)
0.9451true
sma_up
The 200-day average is rising
0.9463true
hv
Is 20-day historical volatility above 25%
compiled to std(log(C / C[-1]), 20) * sqrt(20 / 19) * sqrt(252) > 0.25
0.0537false
drop5
A 5% drawdown within a month
0.20320% · unlikely
vol_up
Higher volatility next month
0.6969% · likely

Actions

Rules on the answers decide what to send.

trend < 0.4 and drop5 >= 0.5→Webhookrisk-dial
hv >= 0.6 or vol_up >= 0.7→Webhookrisk-dial
else→Webhookrisk-dial
What each action would send 1 of 3 fired · dry run, nothing sent
defensiverule false: skipped
cautiousrule false: skipped
normalwould send (dry run)Webhook → risk-dial
{
  "sleeve": "us_equity",
  "dial": "normal",
  "as_of": "2026-10-30"
}

What it means

For SPY on the session of 2026-10-30: True now: Is the stock above its 200-day moving average; The 200-day average is rising. Not true: Is 20-day historical volatility above 25%. Forecasts: A 5% drawdown within a month 20%; Higher volatility next month 69%. Fired: normal (Webhook → risk-dial).

Branches are checked in order, so defensive wins over cautious; the dial changes the target mix only within limits the investment committee set.

As a scheduled workflow (Mon–Fri at 17:00 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": "Nightly risk dial for the equity sleeve (SPY)",
  "symbols": "SPY",
  "days": [
    1,
    2,
    3,
    4,
    5
  ],
  "at_time": "17:00",
  "model": "ora-fin-0.1.1",
  "questions": {
    "trend": {
      "type": "yes_no",
      "instructions": "Is the stock above its 200-day moving average?"
    },
    "sma_up": {
      "type": "yes_no",
      "ask": "sma(C, 200) > ref(sma(C, 200), -20)"
    },
    "hv": {
      "type": "yes_no",
      "instructions": "Is 20-day historical volatility above 25%?"
    },
    "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": "defensive",
      "when": "trend < 0.4 and drop5 >= 0.5",
      "do": "webhook",
      "connection": "risk-dial",
      "body": {
        "sleeve": "us_equity",
        "dial": "defensive",
        "p_trend": "{{trend}}",
        "p_drop5": "{{drop5}}",
        "as_of": "{{as_of}}"
      }
    },
    {
      "id": "cautious",
      "when": "hv >= 0.6 or vol_up >= 0.7",
      "do": "webhook",
      "connection": "risk-dial",
      "body": {
        "sleeve": "us_equity",
        "dial": "cautious",
        "p_hv25": "{{hv}}",
        "p_vol_up": "{{vol_up}}",
        "as_of": "{{as_of}}"
      }
    },
    {
      "id": "normal",
      "when": "else",
      "do": "webhook",
      "connection": "risk-dial",
      "body": {
        "sleeve": "us_equity",
        "dial": "normal",
        "as_of": "{{as_of}}"
      }
    }
  ]
}
Request JSON
{
  "model": "ora-fin-0.1.1",
  "state": {
    "symbol": "SPY"
  },
  "questions": {
    "trend": {
      "type": "yes_no",
      "instructions": "Is the stock above its 200-day moving average?"
    },
    "sma_up": {
      "type": "yes_no",
      "ask": "sma(C, 200) > ref(sma(C, 200), -20)"
    },
    "hv": {
      "type": "yes_no",
      "instructions": "Is 20-day historical volatility above 25%?"
    },
    "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": "defensive",
      "when": "trend < 0.4 and drop5 >= 0.5",
      "do": "webhook",
      "connection": "risk-dial",
      "body": {
        "sleeve": "us_equity",
        "dial": "defensive",
        "p_trend": "{{trend}}",
        "p_drop5": "{{drop5}}",
        "as_of": "{{as_of}}"
      }
    },
    {
      "id": "cautious",
      "when": "hv >= 0.6 or vol_up >= 0.7",
      "do": "webhook",
      "connection": "risk-dial",
      "body": {
        "sleeve": "us_equity",
        "dial": "cautious",
        "p_hv25": "{{hv}}",
        "p_vol_up": "{{vol_up}}",
        "as_of": "{{as_of}}"
      }
    },
    {
      "id": "normal",
      "when": "else",
      "do": "webhook",
      "connection": "risk-dial",
      "body": {
        "sleeve": "us_equity",
        "dial": "normal",
        "as_of": "{{as_of}}"
      }
    }
  ],
  "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"
    },
    "sma_up": {
      "yes_no": 0.9463,
      "rule": "sma(C, 200) > ref(sma(C, 200), -20)",
      "basis": "rule"
    },
    "hv": {
      "yes_no": 0.0537,
      "rule": "std(log(C / C[-1]), 20) * sqrt(20 / 19) * sqrt(252) > 0.25",
      "basis": "pattern"
    },
    "drop5": {
      "yes_no": 0.203
    },
    "vol_up": {
      "yes_no": 0.69
    }
  },
  "context": {
    "symbol": "SPY",
    "as_of": "2026-10-30"
  },
  "actions": [
    {
      "id": "defensive",
      "fired": false,
      "status": "skipped"
    },
    {
      "id": "cautious",
      "fired": false,
      "status": "skipped"
    },
    {
      "id": "normal",
      "fired": true,
      "status": "dry_run",
      "do": "webhook",
      "connection": "risk-dial",
      "preview": {
        "body": {
          "sleeve": "us_equity",
          "dial": "normal",
          "as_of": "2026-10-30"
        }
      }
    }
  ]
}

log offset ref sma sqrt std

Robo-advisor · example 4

Duration check for the bond sleeve: TLT, IEF and SHY

See whether long, intermediate and short Treasuries are trending, to decide which duration bucket gets new cash.

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

State

{"symbol":"TLT"} then IEF, SHY, one request each. The server fills in the latest completed session.

Questions

trendruleC > sma(C, 50)
Above the 50-day average
ma_uprulesma(C, 50) > ref(sma(C, 50), -10)
The 50-day average is rising
macdEnglish → ruleIs the MACD line above its signal line?
up_weekforecastWill the stock be higher in a week?
Higher in a week

Answers

Symboltrendrulema_uprulemacdruleup_weekforecast
TLT0.84820.15840.90840.561
IEF0.85140.08820.92230.483
SHY0.89710.16240.92250.594

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: Above the 50-day average: true for TLT, IEF, SHY of 3. The 50-day average is rising: true for none of 3. Is the MACD line above its signal line: true for TLT, IEF, SHY of 3. Highest odds for “Higher in a week”: SHY at 59%.

The same questions across durations show where the trend is; cash goes to the policy weight first and the tilt is small.

Request JSON (TLT; the others differ only in the symbol)
{
  "model": "ora-fin-0.1.1",
  "state": {
    "symbol": "TLT"
  },
  "questions": {
    "trend": {
      "type": "yes_no",
      "ask": "C > sma(C, 50)"
    },
    "ma_up": {
      "type": "yes_no",
      "ask": "sma(C, 50) > ref(sma(C, 50), -10)"
    },
    "macd": {
      "type": "yes_no",
      "instructions": "Is the MACD line above its signal line?"
    },
    "up_week": {
      "type": "yes_no",
      "instructions": "Will the stock be higher in a week?"
    }
  }
}
Response JSON (TLT, real)
{
  "model": "ora-fin-0.1.1",
  "answers": {
    "trend": {
      "yes_no": 0.8482,
      "rule": "C > sma(C, 50)",
      "basis": "rule"
    },
    "ma_up": {
      "yes_no": 0.1584,
      "rule": "sma(C, 50) > ref(sma(C, 50), -10)",
      "basis": "rule"
    },
    "macd": {
      "yes_no": 0.9084,
      "rule": "macd(C) > macdsignal(C)",
      "basis": "comparison"
    },
    "up_week": {
      "yes_no": 0.561
    }
  },
  "context": {
    "symbol": "TLT",
    "as_of": "2026-10-30"
  }
}

macd macdsignal ref sma

Robo-advisor · example 5

Dividend sleeve health check: SCHD, VIG and VYM

Confirm the income funds still pay, are not in a deep drawdown, and keep their trend, before topping them up.

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

State

{"symbol":"SCHD"} then VIG, VYM, one request each. The server fills in the latest completed session.

Questions

paysEnglish → ruleDoes the stock pay a dividend?
yield2English → ruleIs the dividend yield above 2%?
trendEnglish → ruleIs the stock above its 200-day moving average?
ddruleC < 0.8 * max(H, 252)
More than 20% off the 52-week high

Answers

Symbolpaysruleyield2ruletrendruleddrule
SCHD0.85910.94630.94630.0537
VIG0.85910.05370.94630.0537
VYM0.85910.94630.92740.0537

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: Does the stock pay a dividend: true for SCHD, VIG, VYM of 3. Is the dividend yield above 2%: true for SCHD, VYM of 3. Is the stock above its 200-day moving average: true for SCHD, VIG, VYM of 3. More than 20% off the 52-week high: true for none of 3.

Fund-level dividend facts come from the fund's own distributions; the top-up only proceeds when trend and drawdown are clean.

Request JSON (SCHD; the others differ only in the symbol)
{
  "model": "ora-fin-0.1.1",
  "state": {
    "symbol": "SCHD"
  },
  "questions": {
    "pays": {
      "type": "yes_no",
      "instructions": "Does the stock pay a dividend?"
    },
    "yield2": {
      "type": "yes_no",
      "instructions": "Is the dividend yield above 2%?"
    },
    "trend": {
      "type": "yes_no",
      "instructions": "Is the stock above its 200-day moving average?"
    },
    "dd": {
      "type": "yes_no",
      "ask": "C < 0.8 * max(H, 252)"
    }
  }
}
Response JSON (SCHD, real)
{
  "model": "ora-fin-0.1.1",
  "answers": {
    "pays": {
      "yes_no": 0.8591,
      "rule": "pays_dividend > 0.5",
      "basis": "pattern"
    },
    "yield2": {
      "yes_no": 0.9463,
      "rule": "div_yield_ttm > 2",
      "basis": "pattern"
    },
    "trend": {
      "yes_no": 0.9463,
      "rule": "C > sma(C, 200)",
      "basis": "comparison"
    },
    "dd": {
      "yes_no": 0.0537,
      "rule": "C < 0.8 * max(H, 252)",
      "basis": "rule"
    }
  },
  "context": {
    "symbol": "SCHD",
    "as_of": "2026-10-30"
  }
}

div_yield_ttm max pays_dividend sma

Robo-advisor · example 6

Target-date glide path: is the equity step-down safe this month (VOO)?

Before the scheduled step-down from stocks to bonds, check whether stocks are in a sharp selloff that would sell at a bad moment.

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

State

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

Questions

selloffEnglish → ruleIs the stock down more than 5% over the last month?
shockrulezscore(C / C[-1] - 1, 20) < -2
A two-sigma down day
bearEnglish → ruleIs the stock in bear-market territory, more than 20% below its 52-week high?
rally5forecastWill it rally at least 5% at some point in the next month?
A 5% rally within a month

Answers

QuestionAnswerReading
selloff
Is the stock down more than 5% over the last month
compiled to C / C[-21] - 1 < -0.05
0.0649false
shock
A two-sigma down day
0.6966true
bear
Is the stock in bear-market territory, more than 20% below its 52-week high
compiled to C < 0.8 * max(H, 252)
0.0537false
rally5
A 5% rally within a month
0.2222% · unlikely

Actions

Rules on the answers decide what to send.

selloff >= 0.6 or shock >= 0.6→Slackportfolio-ops
What each action would send 1 of 1 fired · dry run, nothing sent
defer_notewould send (dry run)Slack → portfolio-ops
{
  "text": "VOO (2026-10-30): selloff during the glide-path step (down 5% this month 6%, return shock 70%). Ops to review whether the step runs as scheduled."
}

What it means

For VOO on the session of 2026-10-30: True now: A two-sigma down day. Not true: Is the stock down more than 5% over the last month; Is the stock in bear-market territory, more than 20% below its 52-week high. Forecasts: A 5% rally within a month 22%. Fired: defer_note (Slack → portfolio-ops).

The glide path is policy; the note only asks a human to review timing within the allowed window.

Request JSON
{
  "model": "ora-fin-0.1.1",
  "state": {
    "symbol": "VOO"
  },
  "questions": {
    "selloff": {
      "type": "yes_no",
      "instructions": "Is the stock down more than 5% over the last month?"
    },
    "shock": {
      "type": "yes_no",
      "ask": "zscore(C / C[-1] - 1, 20) < -2"
    },
    "bear": {
      "type": "yes_no",
      "instructions": "Is the stock in bear-market territory, more than 20% below its 52-week high?"
    },
    "rally5": {
      "type": "yes_no",
      "instructions": "Will it rally at least 5% at some point in the next month?"
    }
  },
  "actions": [
    {
      "id": "defer_note",
      "when": "selloff >= 0.6 or shock >= 0.6",
      "do": "slack",
      "connection": "portfolio-ops",
      "message": "{{symbol}} ({{as_of}}): selloff during the glide-path step (down 5% this month {{selloff|pct}}, return shock {{shock|pct}}). Ops to review whether the step runs as scheduled."
    }
  ],
  "dry_run": true
}
Response JSON (VOO, real)
{
  "model": "ora-fin-0.1.1",
  "answers": {
    "selloff": {
      "yes_no": 0.0649,
      "rule": "C / C[-21] - 1 < -0.05",
      "basis": "pattern"
    },
    "shock": {
      "yes_no": 0.6966,
      "rule": "zscore(C / C[-1] - 1, 20) < -2",
      "basis": "rule"
    },
    "bear": {
      "yes_no": 0.0537,
      "rule": "C < 0.8 * max(H, 252)",
      "basis": "pattern"
    },
    "rally5": {
      "yes_no": 0.22
    }
  },
  "context": {
    "symbol": "VOO",
    "as_of": "2026-10-30"
  },
  "actions": [
    {
      "id": "defer_note",
      "fired": true,
      "status": "dry_run",
      "do": "slack",
      "connection": "portfolio-ops",
      "preview": {
        "text": "VOO (2026-10-30): selloff during the glide-path step (down 5% this month 6%, return shock 70%). Ops to review whether the step runs as scheduled."
      }
    }
  ]
}

max offset zscore

Robo-advisor · example 7

Cash sleeve: are T-bill funds (SGOV, BIL) behaving like cash?

Check that the cash-equivalent funds are calm and paying, as a sanity test before sweeping idle cash into them.

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

State

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

Questions

calmEnglish → ruleIs the 14-day ATR less than 2% of the price?
paysrulepays_dividend > 0.5
Pays a dividend
monthlyEnglish → ruleDoes the stock pay a monthly dividend?
hv_lowEnglish → ruleIs 20-day historical volatility below 20%?

Answers

Symbolcalmrulepaysrulemonthlyrulehv_lowrule
SGOV0.94630.85910.85910.9463
BIL0.94630.85910.85910.9463

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: Is the 14-day ATR less than 2% of the price: true for SGOV, BIL of 2. Pays a dividend: true for SGOV, BIL of 2. Does the stock pay a monthly dividend: true for SGOV, BIL of 2. Is 20-day historical volatility below 20%: true for SGOV, BIL of 2.

A T-bill fund that is not calm would be a data or market anomaly; the sweep waits for a human if any check fails.

Request JSON (SGOV; the others differ only in the symbol)
{
  "model": "ora-fin-0.1.1",
  "state": {
    "symbol": "SGOV"
  },
  "questions": {
    "calm": {
      "type": "yes_no",
      "instructions": "Is the 14-day ATR less than 2% of the price?"
    },
    "pays": {
      "type": "yes_no",
      "ask": "pays_dividend > 0.5"
    },
    "monthly": {
      "type": "yes_no",
      "instructions": "Does the stock pay a monthly dividend?"
    },
    "hv_low": {
      "type": "yes_no",
      "instructions": "Is 20-day historical volatility below 20%?"
    }
  }
}
Response JSON (SGOV, real)
{
  "model": "ora-fin-0.1.1",
  "answers": {
    "calm": {
      "yes_no": 0.9463,
      "rule": "atr(14) / C < 0.02",
      "basis": "pattern"
    },
    "pays": {
      "yes_no": 0.8591,
      "rule": "pays_dividend > 0.5",
      "basis": "rule"
    },
    "monthly": {
      "yes_no": 0.8591,
      "rule": "div_count_ttm >= 11",
      "basis": "pattern"
    },
    "hv_low": {
      "yes_no": 0.9463,
      "rule": "std(log(C / C[-1]), 20) * sqrt(20 / 19) * sqrt(252) < 0.2",
      "basis": "pattern"
    }
  },
  "context": {
    "symbol": "SGOV",
    "as_of": "2026-10-30"
  }
}

atr div_count_ttm log offset pays_dividend sqrt std

Robo-advisor · example 8

Factor sleeve tilt: momentum, quality, value and low volatility

Read trend and relative strength across factor ETFs to size a small tilt inside policy limits.

ora-fin-0.1.14 symbols, one request each4 questions2 actions
  1. State4 symbols
  2. Questions4 asked
  3. Answersreal, captured
  4. Actions2 rules · dry run

State

{"symbol":"MTUM"} then QUAL, VLUE, USMV, one request each. The server fills in the latest completed session.

Questions

trendEnglish → ruleIs the stock above its 200-day moving average?
momentumruleroc(C, 20) > 5
Up more than 5% in 20 sessions
beat_spyforecastWill it beat SPY over the next month?
Beating SPY over a month
up_weekforecastWill the stock be higher in a week?
Higher in a week

Answers

Symboltrendrulemomentumrulebeat_spyforecastup_weekforecastFired
MTUM0.26910.05370.4860.543neutral
QUAL0.94630.05540.4950.618neutral
VLUE0.92910.0580.5120.606neutral
USMV0.94630.45680.4270.616neutral

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.6 and beat_spy >= 0.55→Webhookrebalancer
else→Webhookrebalancer
MTUM 1 of 2 fired · dry run, nothing sent
tiltrule false: skipped
neutralwould send (dry run)Webhook → rebalancer
{
  "sleeve": "factor_MTUM",
  "action": "policy_weight",
  "as_of": "2026-10-30"
}
QUAL 1 of 2 fired · dry run, nothing sent
tiltrule false: skipped
neutralwould send (dry run)Webhook → rebalancer
{
  "sleeve": "factor_QUAL",
  "action": "policy_weight",
  "as_of": "2026-10-30"
}
VLUE 1 of 2 fired · dry run, nothing sent
tiltrule false: skipped
neutralwould send (dry run)Webhook → rebalancer
{
  "sleeve": "factor_VLUE",
  "action": "policy_weight",
  "as_of": "2026-10-30"
}
USMV 1 of 2 fired · dry run, nothing sent
tiltrule false: skipped
neutralwould send (dry run)Webhook → rebalancer
{
  "sleeve": "factor_USMV",
  "action": "policy_weight",
  "as_of": "2026-10-30"
}

What it means

Session of 2026-10-30, 4 symbols: Is the stock above its 200-day moving average: true for QUAL, VLUE, USMV of 4. Up more than 5% in 20 sessions: true for none of 4. Highest odds for “Beating SPY over a month”: VLUE at 51%. tilt fired for none. neutral fired for MTUM, QUAL, VLUE, USMV.

Factors with a true trend rule and better odds against SPY get the tilt; the tilt is capped so no factor dominates.

Request JSON (MTUM; the others differ only in the symbol)
{
  "model": "ora-fin-0.1.1",
  "state": {
    "symbol": "MTUM"
  },
  "questions": {
    "trend": {
      "type": "yes_no",
      "instructions": "Is the stock above its 200-day moving average?"
    },
    "momentum": {
      "type": "yes_no",
      "ask": "roc(C, 20) > 5"
    },
    "beat_spy": {
      "type": "yes_no",
      "instructions": "Will it beat SPY over the next month?"
    },
    "up_week": {
      "type": "yes_no",
      "instructions": "Will the stock be higher in a week?"
    }
  },
  "actions": [
    {
      "id": "tilt",
      "when": "trend >= 0.6 and beat_spy >= 0.55",
      "do": "webhook",
      "connection": "rebalancer",
      "body": {
        "sleeve": "factor_{{symbol}}",
        "action": "tilt_up",
        "max_tilt_pct": 2,
        "p_beat_spy": "{{beat_spy}}",
        "as_of": "{{as_of}}"
      }
    },
    {
      "id": "neutral",
      "when": "else",
      "do": "webhook",
      "connection": "rebalancer",
      "body": {
        "sleeve": "factor_{{symbol}}",
        "action": "policy_weight",
        "as_of": "{{as_of}}"
      }
    }
  ],
  "dry_run": true
}
Response JSON (MTUM, real)
{
  "model": "ora-fin-0.1.1",
  "answers": {
    "trend": {
      "yes_no": 0.2691,
      "rule": "C > sma(C, 200)",
      "basis": "comparison"
    },
    "momentum": {
      "yes_no": 0.0537,
      "rule": "roc(C, 20) > 5",
      "basis": "rule"
    },
    "beat_spy": {
      "yes_no": 0.486
    },
    "up_week": {
      "yes_no": 0.543
    }
  },
  "context": {
    "symbol": "MTUM",
    "as_of": "2026-10-30"
  },
  "actions": [
    {
      "id": "tilt",
      "fired": false,
      "status": "skipped"
    },
    {
      "id": "neutral",
      "fired": true,
      "status": "dry_run",
      "do": "webhook",
      "connection": "rebalancer",
      "preview": {
        "body": {
          "sleeve": "factor_MTUM",
          "action": "policy_weight",
          "as_of": "2026-10-30"
        }
      }
    }
  ]
}

roc sma

Robo-advisor · example 9

Client email when the aggressive model's core fund (QQQ) drops sharply

Send a calm, pre-approved explainer to clients in the aggressive model when its core fund falls hard.

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

State

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

Questions

fell3English → ruleDid the stock fall more than 3% today?
worstEnglish → ruleWas today the worst day of the last 20 sessions?
below_50English → ruleIs the stock below its 50-day moving average?
drop5forecastWill it drop at least 5% at some point in the next month?
A 5% drawdown within a month

Answers

QuestionAnswerReading
fell3
Did the stock fall more than 3% today
compiled to C / C[-1] - 1 < -0.03
0.7217true
worst
Was today the worst day of the last 20 sessions
compiled to (C < C[-1]) and (C / C[-1] - 1 < ref(min(C / C[-1] - 1, 19), -1))
0.7569true
below_50
Is the stock below its 50-day moving average
compiled to C < sma(C, 50)
0.9347true
drop5
A 5% drawdown within a month
0.44344% · close to even

Actions

Rules on the answers decide what to send.

fell3 >= 0.6 or worst >= 0.6→Emailclient-comms
What each action would send 1 of 1 fired · dry run, nothing sent
explainerwould send (dry run)Email → client-comms
{
  "subject": "About today's market drop",
  "text": "Your growth holdings fell today (QQQ, 2026-10-30). Drops like this are part of long-term investing; your plan already accounts for them. No action is needed."
}

What it means

For QQQ on the session of 2026-10-30: True now: Did the stock fall more than 3% today; Was today the worst day of the last 20 sessions; Is the stock below its 50-day moving average. Forecasts: A 5% drawdown within a month 44%. Fired: explainer (Email → client-comms).

The message is pre-approved and fires only on a real large drop; the forecast is kept internal and never quoted to clients.

Request JSON
{
  "model": "ora-fin-0.1.1",
  "state": {
    "symbol": "QQQ"
  },
  "questions": {
    "fell3": {
      "type": "yes_no",
      "instructions": "Did the stock fall more than 3% today?"
    },
    "worst": {
      "type": "yes_no",
      "instructions": "Was today the worst day of the last 20 sessions?"
    },
    "below_50": {
      "type": "yes_no",
      "instructions": "Is the stock below its 50-day moving average?"
    },
    "drop5": {
      "type": "yes_no",
      "instructions": "Will it drop at least 5% at some point in the next month?"
    }
  },
  "actions": [
    {
      "id": "explainer",
      "when": "fell3 >= 0.6 or worst >= 0.6",
      "do": "email",
      "connection": "client-comms",
      "subject": "About today's market drop",
      "message": "Your growth holdings fell today ({{symbol}}, {{as_of}}). Drops like this are part of long-term investing; your plan already accounts for them. No action is needed."
    }
  ],
  "dry_run": true
}
Response JSON (QQQ, real)
{
  "model": "ora-fin-0.1.1",
  "answers": {
    "fell3": {
      "yes_no": 0.7217,
      "rule": "C / C[-1] - 1 < -0.03",
      "basis": "pattern"
    },
    "worst": {
      "yes_no": 0.7569,
      "rule": "(C < C[-1]) and (C / C[-1] - 1 < ref(min(C / C[-1] - 1, 19), -1))",
      "basis": "pattern"
    },
    "below_50": {
      "yes_no": 0.9347,
      "rule": "C < sma(C, 50)",
      "basis": "comparison"
    },
    "drop5": {
      "yes_no": 0.443
    }
  },
  "context": {
    "symbol": "QQQ",
    "as_of": "2026-10-30"
  },
  "actions": [
    {
      "id": "explainer",
      "fired": true,
      "status": "dry_run",
      "do": "email",
      "connection": "client-comms",
      "preview": {
        "subject": "About today's market drop",
        "text": "Your growth holdings fell today (QQQ, 2026-10-30). Drops like this are part of long-term investing; your plan already accounts for them. No action is needed."
      }
    }
  ]
}

min offset ref sma

Robo-advisor · example 10

Real estate sleeve: VNQ and XLRE trend and income

Decide whether the real estate sleeve stays at weight, using trend and yield facts.

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

State

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

Questions

trendrulediv_yield_ttm > 2 and C > sma(C, 200)
Yield above 2% and above the 200-day
yield3English → ruleIs the dividend yield above 3%?
goldenrulesma(C, 50) > sma(C, 200)
50-day above the 200-day
drop5forecastWill it drop at least 5% at some point in the next month?
A 5% drawdown within a month

Answers

Symboltrendruleyield3rulegoldenruledrop5forecast
VNQ0.62850.88930.37610.218
XLRE0.53840.79970.27520.202

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: Yield above 2% and above the 200-day: true for VNQ of 2. Is the dividend yield above 3%: true for VNQ, XLRE of 2. 50-day above the 200-day: true for none of 2. Highest odds for “A 5% drawdown within a month”: VNQ at 22%.

Yield in an uptrend supports staying at weight; a broken trend moves the sleeve toward the bottom of its band, never to zero.

Request JSON (VNQ; the others differ only in the symbol)
{
  "model": "ora-fin-0.1.1",
  "state": {
    "symbol": "VNQ"
  },
  "questions": {
    "trend": {
      "type": "yes_no",
      "ask": "div_yield_ttm > 2 and C > sma(C, 200)"
    },
    "yield3": {
      "type": "yes_no",
      "instructions": "Is the dividend yield above 3%?"
    },
    "golden": {
      "type": "yes_no",
      "ask": "sma(C, 50) > sma(C, 200)"
    },
    "drop5": {
      "type": "yes_no",
      "instructions": "Will it drop at least 5% at some point in the next month?"
    }
  }
}
Response JSON (VNQ, real)
{
  "model": "ora-fin-0.1.1",
  "answers": {
    "trend": {
      "yes_no": 0.6285,
      "rule": "div_yield_ttm > 2 and C > sma(C, 200)",
      "basis": "rule"
    },
    "yield3": {
      "yes_no": 0.8893,
      "rule": "div_yield_ttm > 3",
      "basis": "pattern"
    },
    "golden": {
      "yes_no": 0.3761,
      "rule": "sma(C, 50) > sma(C, 200)",
      "basis": "rule"
    },
    "drop5": {
      "yes_no": 0.218
    }
  },
  "context": {
    "symbol": "VNQ",
    "as_of": "2026-10-30"
  }
}

div_yield_ttm sma

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, Broker app, Algo / bot developer, 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.