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 1–10 of 20 · page 1 of 2

Algo / bot developer · example 1

An RSI(2) mean-reversion bot on SPY: signal, risk check, order

A daily bot buys short-term oversold dips in an uptrend and posts the order to the broker API only when the risk checks pass.

ora-fin-0.1.1SPY4 questions2 actionsworkflow · Mon–Fri at 16:15 ET
  1. ScheduleMon–Fri at 16:15 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

rsi2rulersi(C, 2) < 10
Two-day RSI under 10
trendEnglish → ruleIs the stock above its 200-day moving average?
liquidruleavg(C * V, 20) > 100000000
Trades more than $100 million a day
drop5forecastWill it drop at least 5% at some point in the next month?
A 5% drawdown within a month

Answers

QuestionAnswerReading
rsi2
Two-day RSI under 10
0.5164on the line (true)
trend
Is the stock above its 200-day moving average
compiled to C > sma(C, 200)
0.9451true
liquid
Trades more than $100 million a day
0.9463true
drop5
A 5% drawdown within a month
0.20320% · unlikely

Actions

Rules on the answers decide what to send.

rsi2 >= 0.6 and trend >= 0.6 and drop5 < 0.5→Webhookbroker-api
else→Slackbot-log
What each action would send 1 of 2 fired · dry run, nothing sent
buyrule false: skipped
logwould send (dry run)Slack → bot-log
{
  "text": "SPY (2026-10-30): no RSI(2) entry. Oversold 52%, uptrend 95%, 5% drawdown odds 20%."
}

What it means

For SPY on the session of 2026-10-30: True now: Is the stock above its 200-day moving average; Trades more than $100 million a day. On the line: Two-day RSI under 10. Forecasts: A 5% drawdown within a month 20%. Fired: log (Slack → bot-log).

Either an order goes to the broker or a log line goes to Slack, so every session leaves a trace of what the bot decided and why.

As a scheduled workflow (Mon–Fri at 16:15 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": "An RSI(2) mean-reversion bot on SPY: signal, risk check, order",
  "symbols": "SPY",
  "days": [
    1,
    2,
    3,
    4,
    5
  ],
  "at_time": "16:15",
  "model": "ora-fin-0.1.1",
  "questions": {
    "rsi2": {
      "type": "yes_no",
      "ask": "rsi(C, 2) < 10"
    },
    "trend": {
      "type": "yes_no",
      "instructions": "Is the stock above its 200-day moving average?"
    },
    "liquid": {
      "type": "yes_no",
      "ask": "avg(C * V, 20) > 100000000"
    },
    "drop5": {
      "type": "yes_no",
      "instructions": "Will it drop at least 5% at some point in the next month?"
    }
  },
  "actions": [
    {
      "id": "buy",
      "when": "rsi2 >= 0.6 and trend >= 0.6 and drop5 < 0.5",
      "do": "webhook",
      "connection": "broker-api",
      "body": {
        "symbol": "{{symbol}}",
        "side": "buy",
        "order_type": "market_on_open",
        "strategy": "rsi2_dip",
        "p_rsi2": "{{rsi2}}",
        "p_trend": "{{trend}}",
        "p_drop5": "{{drop5}}",
        "as_of": "{{as_of}}"
      }
    },
    {
      "id": "log",
      "when": "else",
      "do": "slack",
      "connection": "bot-log",
      "message": "{{symbol}} ({{as_of}}): no RSI(2) entry. Oversold {{rsi2|pct}}, uptrend {{trend|pct}}, 5% drawdown odds {{drop5|pct}}."
    }
  ]
}
Request JSON
{
  "model": "ora-fin-0.1.1",
  "state": {
    "symbol": "SPY"
  },
  "questions": {
    "rsi2": {
      "type": "yes_no",
      "ask": "rsi(C, 2) < 10"
    },
    "trend": {
      "type": "yes_no",
      "instructions": "Is the stock above its 200-day moving average?"
    },
    "liquid": {
      "type": "yes_no",
      "ask": "avg(C * V, 20) > 100000000"
    },
    "drop5": {
      "type": "yes_no",
      "instructions": "Will it drop at least 5% at some point in the next month?"
    }
  },
  "actions": [
    {
      "id": "buy",
      "when": "rsi2 >= 0.6 and trend >= 0.6 and drop5 < 0.5",
      "do": "webhook",
      "connection": "broker-api",
      "body": {
        "symbol": "{{symbol}}",
        "side": "buy",
        "order_type": "market_on_open",
        "strategy": "rsi2_dip",
        "p_rsi2": "{{rsi2}}",
        "p_trend": "{{trend}}",
        "p_drop5": "{{drop5}}",
        "as_of": "{{as_of}}"
      }
    },
    {
      "id": "log",
      "when": "else",
      "do": "slack",
      "connection": "bot-log",
      "message": "{{symbol}} ({{as_of}}): no RSI(2) entry. Oversold {{rsi2|pct}}, uptrend {{trend|pct}}, 5% drawdown odds {{drop5|pct}}."
    }
  ],
  "dry_run": true
}
Response JSON (SPY, real)
{
  "model": "ora-fin-0.1.1",
  "answers": {
    "rsi2": {
      "yes_no": 0.5164,
      "rule": "rsi(C, 2) < 10",
      "basis": "rule"
    },
    "trend": {
      "yes_no": 0.9451,
      "rule": "C > sma(C, 200)",
      "basis": "comparison"
    },
    "liquid": {
      "yes_no": 0.9463,
      "rule": "avg(C * V, 20) > 100000000",
      "basis": "rule"
    },
    "drop5": {
      "yes_no": 0.203
    }
  },
  "context": {
    "symbol": "SPY",
    "as_of": "2026-10-30"
  },
  "actions": [
    {
      "id": "buy",
      "fired": false,
      "status": "skipped"
    },
    {
      "id": "log",
      "fired": true,
      "status": "dry_run",
      "do": "slack",
      "connection": "bot-log",
      "preview": {
        "text": "SPY (2026-10-30): no RSI(2) entry. Oversold 52%, uptrend 95%, 5% drawdown odds 20%."
      }
    }
  ]
}

avg rsi sma

Algo / bot developer · example 2

Golden-cross trend bot on QQQ with an exit branch

Enter when the 50-day crosses above the 200-day, exit when it crosses back below, do nothing otherwise.

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

State

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

Questions

cross_uprulecrossup(sma(C, 50), sma(C, 200))
50-day crossed above the 200-day today
cross_dnrulecrossdown(sma(C, 50), sma(C, 200))
50-day crossed below the 200-day today
setuprulesma(C, 50) > sma(C, 200)
50-day above the 200-day
up_weekforecastWill the stock be higher in a week?
Higher in a week

Answers

QuestionAnswerReading
cross_up
50-day crossed above the 200-day today
0.05false
cross_dn
50-day crossed below the 200-day today
0.05false
setup
50-day above the 200-day
0.9463true
up_week
Higher in a week
0.56156% · close to even

Actions

Rules on the answers decide what to send.

cross_up >= 0.6→Webhookbroker-api
cross_dn >= 0.6→Webhookbroker-api
What each action would send 0 of 2 fired · dry run, nothing sent
enterrule false: skipped
exitrule false: skipped

What it means

For QQQ on the session of 2026-10-30: True now: 50-day above the 200-day. Not true: 50-day crossed above the 200-day today; 50-day crossed below the 200-day today. Forecasts: Higher in a week 56%. No action fired: every rule was false.

Crosses are rare one-day events, so on almost every run neither branch fires; the setup state says which side the bot should already be on.

Request JSON
{
  "model": "ora-fin-0.1.1",
  "state": {
    "symbol": "QQQ"
  },
  "questions": {
    "cross_up": {
      "type": "yes_no",
      "ask": "crossup(sma(C, 50), sma(C, 200))"
    },
    "cross_dn": {
      "type": "yes_no",
      "ask": "crossdown(sma(C, 50), sma(C, 200))"
    },
    "setup": {
      "type": "yes_no",
      "ask": "sma(C, 50) > sma(C, 200)"
    },
    "up_week": {
      "type": "yes_no",
      "instructions": "Will the stock be higher in a week?"
    }
  },
  "actions": [
    {
      "id": "enter",
      "when": "cross_up >= 0.6",
      "do": "webhook",
      "connection": "broker-api",
      "body": {
        "symbol": "{{symbol}}",
        "side": "buy",
        "strategy": "golden_cross",
        "as_of": "{{as_of}}"
      }
    },
    {
      "id": "exit",
      "when": "cross_dn >= 0.6",
      "do": "webhook",
      "connection": "broker-api",
      "body": {
        "symbol": "{{symbol}}",
        "side": "sell",
        "strategy": "golden_cross",
        "as_of": "{{as_of}}"
      }
    }
  ],
  "dry_run": true
}
Response JSON (QQQ, real)
{
  "model": "ora-fin-0.1.1",
  "answers": {
    "cross_up": {
      "yes_no": 0.05,
      "rule": "crossup(sma(C, 50), sma(C, 200))",
      "basis": "rule"
    },
    "cross_dn": {
      "yes_no": 0.05,
      "rule": "crossdown(sma(C, 50), sma(C, 200))",
      "basis": "rule"
    },
    "setup": {
      "yes_no": 0.9463,
      "rule": "sma(C, 50) > sma(C, 200)",
      "basis": "rule"
    },
    "up_week": {
      "yes_no": 0.561
    }
  },
  "context": {
    "symbol": "QQQ",
    "as_of": "2026-10-30"
  },
  "actions": [
    {
      "id": "enter",
      "fired": false,
      "status": "skipped"
    },
    {
      "id": "exit",
      "fired": false,
      "status": "skipped"
    }
  ]
}

crossdown crossup sma

Algo / bot developer · example 3

A Discord signal bot for oversold large caps

Post oversold-in-uptrend setups for a few large caps to a Discord channel through its incoming webhook.

ora-fin-0.1.14 symbols, one request each4 questions1 action
  1. State4 symbols
  2. Questions4 asked
  3. Answersreal, captured
  4. Actions1 rule · dry run

State

{"symbol":"AAPL"} then MSFT, AMZN, NVDA, one request each. The server fills in the latest completed session.

Questions

setupruleC > sma(C, 200) and rsi(C, 14) < 40
Pullback in an uptrend: above the 200-day, RSI under 40
stochrulestochk(14) < 20
Stochastic %K under 20
willrrulewillr(14) < -80
Williams %R below -80: near the bottom of the 14-day range
up_weekforecastWill the stock be higher in a week?
Higher in a week

Answers

Symbolsetuprulestochrulewillrruleup_weekforecastFired
AAPL0.06340.06830.08930.59none
MSFT0.10640.20220.48420.574none
AMZN0.30730.310.29230.493none
NVDA0.54550.54750.62930.527none

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.

setup >= 0.6→Webhookdiscord-signals
AAPL 0 of 1 fired · dry run, nothing sent
MSFT 0 of 1 fired · dry run, nothing sent
AMZN 0 of 1 fired · dry run, nothing sent
NVDA 0 of 1 fired · dry run, nothing sent

What it means

Session of 2026-10-30, 4 symbols: Pullback in an uptrend: above the 200-day, RSI under 40: true for none of 4. Stochastic %K under 20: true for none of 4. Williams %R below -80: near the bottom of the 14-day range: true for NVDA of 4. Highest odds for “Higher in a week”: AAPL at 59%. discord fired for none.

Discord expects a JSON body with a content field; the bot posts only when the setup rule is true for a symbol.

Request JSON (AAPL; the others differ only in the symbol)
{
  "model": "ora-fin-0.1.1",
  "state": {
    "symbol": "AAPL"
  },
  "questions": {
    "setup": {
      "type": "yes_no",
      "ask": "C > sma(C, 200) and rsi(C, 14) < 40"
    },
    "stoch": {
      "type": "yes_no",
      "ask": "stochk(14) < 20"
    },
    "willr": {
      "type": "yes_no",
      "ask": "willr(14) < -80"
    },
    "up_week": {
      "type": "yes_no",
      "instructions": "Will the stock be higher in a week?"
    }
  },
  "actions": [
    {
      "id": "discord",
      "when": "setup >= 0.6",
      "do": "webhook",
      "connection": "discord-signals",
      "body": {
        "content": "{{symbol}} ({{as_of}}): pullback in an uptrend. Stochastic oversold {{stoch|pct}}, Williams %R oversold {{willr|pct}}, higher in a week {{up_week|pct}}. Not advice."
      }
    }
  ],
  "dry_run": true
}
Response JSON (AAPL, real)
{
  "model": "ora-fin-0.1.1",
  "answers": {
    "setup": {
      "yes_no": 0.0634,
      "rule": "C > sma(C, 200) and rsi(C, 14) < 40",
      "basis": "rule"
    },
    "stoch": {
      "yes_no": 0.0683,
      "rule": "stochk(14) < 20",
      "basis": "rule"
    },
    "willr": {
      "yes_no": 0.0893,
      "rule": "willr(14) < -80",
      "basis": "rule"
    },
    "up_week": {
      "yes_no": 0.59
    }
  },
  "context": {
    "symbol": "AAPL",
    "as_of": "2026-10-30"
  },
  "actions": [
    {
      "id": "discord",
      "fired": false,
      "status": "skipped"
    }
  ]
}

rsi sma stochk willr

Algo / bot developer · example 4

Telegram breakout bot for semiconductors

Send a Telegram message when a chip stock breaks a 55-day high (a Donchian breakout) with volume.

ora-fin-0.1.15 symbols, one request each4 questions1 action
  1. State5 symbols
  2. Questions4 asked
  3. Answersreal, captured
  4. Actions1 rule · dry run

State

{"symbol":"NVDA"} then AMD, MU, SMH, TSM, one request each. The server fills in the latest completed session.

Questions

donchianruleC > highest(C, 55)
55-day closing breakout
volruleC > C[-1] and V > 1.5 * ref(avg(V, 20), -1)
Up on heavy volume
nearEnglish → ruleIs the stock within 5% of its 52-week high?
rally5forecastWill it rally at least 5% at some point in the next month?
A 5% rally within a month

Answers

Symboldonchianrulevolrulenearrulerally5forecastFired
NVDA0.05370.07320.05370.616none
AMD0.05370.05370.05760.836none
MU0.06850.09090.05370.855none
SMH0.05670.05370.05370.728none
TSM0.05370.05390.05370.683none

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.

donchian >= 0.6 and vol >= 0.6→Webhooktelegram-bot
NVDA 0 of 1 fired · dry run, nothing sent
AMD 0 of 1 fired · dry run, nothing sent
MU 0 of 1 fired · dry run, nothing sent
SMH 0 of 1 fired · dry run, nothing sent
TSM 0 of 1 fired · dry run, nothing sent

What it means

Session of 2026-10-30, 5 symbols: 55-day closing breakout: true for none of 5. Up on heavy volume: true for none of 5. Is the stock within 5% of its 52-week high: true for none of 5. Highest odds for “A 5% rally within a month”: MU at 86%. tg fired for none.

The Telegram body is shaped as the bot API expects; signals need both the breakout and the volume rule to be true.

Request JSON (NVDA; the others differ only in the symbol)
{
  "model": "ora-fin-0.1.1",
  "state": {
    "symbol": "NVDA"
  },
  "questions": {
    "donchian": {
      "type": "yes_no",
      "ask": "C > highest(C, 55)"
    },
    "vol": {
      "type": "yes_no",
      "ask": "C > C[-1] and V > 1.5 * ref(avg(V, 20), -1)"
    },
    "near": {
      "type": "yes_no",
      "instructions": "Is the stock within 5% of its 52-week high?"
    },
    "rally5": {
      "type": "yes_no",
      "instructions": "Will it rally at least 5% at some point in the next month?"
    }
  },
  "actions": [
    {
      "id": "tg",
      "when": "donchian >= 0.6 and vol >= 0.6",
      "do": "webhook",
      "connection": "telegram-bot",
      "body": {
        "chat_id": "@chip_breakouts",
        "text": "{{symbol}} ({{as_of}}) broke its 55-day high on volume. 5% rally odds: {{rally5|pct}}."
      }
    }
  ],
  "dry_run": true
}
Response JSON (NVDA, real)
{
  "model": "ora-fin-0.1.1",
  "answers": {
    "donchian": {
      "yes_no": 0.0537,
      "rule": "C > highest(C, 55)",
      "basis": "rule"
    },
    "vol": {
      "yes_no": 0.0732,
      "rule": "C > C[-1] and V > 1.5 * ref(avg(V, 20), -1)",
      "basis": "rule"
    },
    "near": {
      "yes_no": 0.0537,
      "rule": "abs(C / max(H, 252) - 1) <= 0.05",
      "basis": "comparison"
    },
    "rally5": {
      "yes_no": 0.616
    }
  },
  "context": {
    "symbol": "NVDA",
    "as_of": "2026-10-30"
  },
  "actions": [
    {
      "id": "tg",
      "fired": false,
      "status": "skipped"
    }
  ]
}

abs avg highest max offset ref

Algo / bot developer · example 5

Range check before starting a grid bot on GLD

Grid bots work in ranges and lose in trends; check range and trend strength before switching one on.

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

State

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

Questions

tightEnglish → ruleHas the stock traded in a range of less than 5% over the last 10 sessions?
adx_lowruleadx(14) < 20
ADX under 20: no strong trend
range_topEnglish → ruleIs the stock in the top 10% of its 20-day range?
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
tight
Has the stock traded in a range of less than 5% over the last 10 sessions
compiled to max(H, 10) / min(L, 10) - 1 < 0.05
0.1103false
adx_low
ADX under 20: no strong trend
0.2829false
range_top
Is the stock in the top 10% of its 20-day range
compiled to (C - min(L, 20)) / (max(H, 20) - min(L, 20)) >= 0.9
0.0575false
big_move
A big move either way in 5 days
0.42743% · close to even

Actions

Rules on the answers decide what to send.

adx_low >= 0.6 and big_move < 0.5→Webhookgrid-bot
else→Webhookgrid-bot
What each action would send 1 of 2 fired · dry run, nothing sent
start_gridrule false: skipped
stay_offwould send (dry run)Webhook → grid-bot
{
  "symbol": "GLD",
  "command": "stay_off",
  "as_of": "2026-10-30"
}

What it means

For GLD on the session of 2026-10-30: Not true: Has the stock traded in a range of less than 5% over the last 10 sessions; ADX under 20: no strong trend; Is the stock in the top 10% of its 20-day range. Forecasts: A big move either way in 5 days 43%. Fired: stay_off (Webhook → grid-bot).

The grid starts only without a strong trend and with low odds of a big move; otherwise the bot is told explicitly to stay off.

Request JSON
{
  "model": "ora-fin-0.1.1",
  "state": {
    "symbol": "GLD"
  },
  "questions": {
    "tight": {
      "type": "yes_no",
      "instructions": "Has the stock traded in a range of less than 5% over the last 10 sessions?"
    },
    "adx_low": {
      "type": "yes_no",
      "ask": "adx(14) < 20"
    },
    "range_top": {
      "type": "yes_no",
      "instructions": "Is the stock in the top 10% of its 20-day range?"
    },
    "big_move": {
      "type": "yes_no",
      "instructions": "Will there be a big move in either direction in the next 5 days?"
    }
  },
  "actions": [
    {
      "id": "start_grid",
      "when": "adx_low >= 0.6 and big_move < 0.5",
      "do": "webhook",
      "connection": "grid-bot",
      "body": {
        "symbol": "{{symbol}}",
        "command": "start",
        "p_no_trend": "{{adx_low}}",
        "p_big_move": "{{big_move}}",
        "as_of": "{{as_of}}"
      }
    },
    {
      "id": "stay_off",
      "when": "else",
      "do": "webhook",
      "connection": "grid-bot",
      "body": {
        "symbol": "{{symbol}}",
        "command": "stay_off",
        "as_of": "{{as_of}}"
      }
    }
  ],
  "dry_run": true
}
Response JSON (GLD, real)
{
  "model": "ora-fin-0.1.1",
  "answers": {
    "tight": {
      "yes_no": 0.1103,
      "rule": "max(H, 10) / min(L, 10) - 1 < 0.05",
      "basis": "pattern"
    },
    "adx_low": {
      "yes_no": 0.2829,
      "rule": "adx(14) < 20",
      "basis": "rule"
    },
    "range_top": {
      "yes_no": 0.0575,
      "rule": "(C - min(L, 20)) / (max(H, 20) - min(L, 20)) >= 0.9",
      "basis": "pattern"
    },
    "big_move": {
      "yes_no": 0.427
    }
  },
  "context": {
    "symbol": "GLD",
    "as_of": "2026-10-30"
  },
  "actions": [
    {
      "id": "start_grid",
      "fired": false,
      "status": "skipped"
    },
    {
      "id": "stay_off",
      "fired": true,
      "status": "dry_run",
      "do": "webhook",
      "connection": "grid-bot",
      "preview": {
        "body": {
          "symbol": "GLD",
          "command": "stay_off",
          "as_of": "2026-10-30"
        }
      }
    }
  ]
}

adx max min

Algo / bot developer · example 6

Trailing-stop exit for a TSLA swing bot

Exit an open long when the chandelier stop or a swing-low break is hit; warn when only the forecast looks weak.

ora-fin-0.1.1TSLA3 questions2 actions
  1. StateTSLA
  2. Questions3 asked
  3. Answersreal, captured
  4. Actions2 rules · dry run

State

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

Questions

chandelierruleC < highest(H, 22) - 3 * atr(22)
Chandelier exit: 3 ATR under the 22-day high
swing_breakruleC < swinglow(5, 1)
closed below the last confirmed swing low
drop10forecastWill it drop at least 10% at some point in the next month?
A 10% drawdown within a month

Answers

QuestionAnswerReading
chandelier
Chandelier exit: 3 ATR under the 22-day high
0.0986false
swing_break
closed below the last confirmed swing low
0.0602false
drop10
A 10% drawdown within a month
0.63864% · likely

Actions

Rules on the answers decide what to send.

chandelier >= 0.6 or swing_break >= 0.6→Webhookbroker-api
drop10 >= 0.4→Slackbot-log
What each action would send 1 of 2 fired · dry run, nothing sent
exitrule false: skipped
warnwould send (dry run)Slack → bot-log
{
  "text": "TSLA (2026-10-30): stop not hit, but 10% drawdown odds are 64%."
}

What it means

For TSLA on the session of 2026-10-30: Not true: Chandelier exit: 3 ATR under the 22-day high; closed below the last confirmed swing low. Forecasts: A 10% drawdown within a month 64%. Fired: warn (Slack → bot-log).

Stops are exact rules on the close; the forecast only warns, so the bot's exits stay reproducible.

Request JSON
{
  "model": "ora-fin-0.1.1",
  "state": {
    "symbol": "TSLA"
  },
  "questions": {
    "chandelier": {
      "type": "yes_no",
      "ask": "C < highest(H, 22) - 3 * atr(22)"
    },
    "swing_break": {
      "type": "yes_no",
      "ask": "C < swinglow(5, 1)"
    },
    "drop10": {
      "type": "yes_no",
      "instructions": "Will it drop at least 10% at some point in the next month?"
    }
  },
  "actions": [
    {
      "id": "exit",
      "when": "chandelier >= 0.6 or swing_break >= 0.6",
      "do": "webhook",
      "connection": "broker-api",
      "body": {
        "symbol": "{{symbol}}",
        "side": "sell",
        "reason": "trailing_stop",
        "p_chandelier": "{{chandelier}}",
        "p_swing_break": "{{swing_break}}",
        "as_of": "{{as_of}}"
      }
    },
    {
      "id": "warn",
      "when": "drop10 >= 0.4",
      "do": "slack",
      "connection": "bot-log",
      "message": "{{symbol}} ({{as_of}}): stop not hit, but 10% drawdown odds are {{drop10|pct}}."
    }
  ],
  "dry_run": true
}
Response JSON (TSLA, real)
{
  "model": "ora-fin-0.1.1",
  "answers": {
    "chandelier": {
      "yes_no": 0.0986,
      "rule": "C < highest(H, 22) - 3 * atr(22)",
      "basis": "rule"
    },
    "swing_break": {
      "yes_no": 0.0602,
      "rule": "C < swinglow(5, 1)",
      "basis": "rule"
    },
    "drop10": {
      "yes_no": 0.638
    }
  },
  "context": {
    "symbol": "TSLA",
    "as_of": "2026-10-30"
  },
  "actions": [
    {
      "id": "exit",
      "fired": false,
      "status": "skipped"
    },
    {
      "id": "warn",
      "fired": true,
      "status": "dry_run",
      "do": "slack",
      "connection": "bot-log",
      "preview": {
        "text": "TSLA (2026-10-30): stop not hit, but 10% drawdown odds are 64%."
      }
    }
  ]
}

atr highest swinglow

Algo / bot developer · example 7

Candlestick reversal bot on IWM: morning star or engulfing

Buy small caps on a bullish reversal candle at a 20-day low, with a trend filter.

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

State

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

Questions

starrulemorning_star() or engulfing_bull()
Morning star or bullish engulfing
at_lowruleL <= 1.02 * lowest(L, 20)
low within 2% of the prior 20-day low
trendEnglish → ruleIs the stock above its 200-day moving average?
up_weekforecastWill the stock be higher in a week?
Higher in a week

Answers

QuestionAnswerReading
star
Morning star or bullish engulfing
0.0926false
at_low
low within 2% of the prior 20-day low
0.3213false
trend
Is the stock above its 200-day moving average
compiled to C > sma(C, 200)
0.5564on the line (true)
up_week
Higher in a week
0.52653% · close to even

Actions

Rules on the answers decide what to send.

star >= 0.6 and at_low >= 0.6→Webhookbroker-api
What each action would send 0 of 1 fired · dry run, nothing sent
buyrule false: skipped

What it means

For IWM on the session of 2026-10-30: Not true: Morning star or bullish engulfing; low within 2% of the prior 20-day low. On the line: Is the stock above its 200-day moving average. Forecasts: Higher in a week 53%. No action fired: every rule was false.

The candle must print at a low to count; the trend flag is passed along so the bot can size smaller against the trend.

Request JSON
{
  "model": "ora-fin-0.1.1",
  "state": {
    "symbol": "IWM"
  },
  "questions": {
    "star": {
      "type": "yes_no",
      "ask": "morning_star() or engulfing_bull()"
    },
    "at_low": {
      "type": "yes_no",
      "ask": "L <= 1.02 * lowest(L, 20)"
    },
    "trend": {
      "type": "yes_no",
      "instructions": "Is the stock above its 200-day moving average?"
    },
    "up_week": {
      "type": "yes_no",
      "instructions": "Will the stock be higher in a week?"
    }
  },
  "actions": [
    {
      "id": "buy",
      "when": "star >= 0.6 and at_low >= 0.6",
      "do": "webhook",
      "connection": "broker-api",
      "body": {
        "symbol": "{{symbol}}",
        "side": "buy",
        "strategy": "reversal_candle",
        "with_trend": "{{trend}}",
        "as_of": "{{as_of}}"
      }
    }
  ],
  "dry_run": true
}
Response JSON (IWM, real)
{
  "model": "ora-fin-0.1.1",
  "answers": {
    "star": {
      "yes_no": 0.0926,
      "rule": "morning_star() or engulfing_bull()",
      "basis": "rule"
    },
    "at_low": {
      "yes_no": 0.3213,
      "rule": "L <= 1.02 * lowest(L, 20)",
      "basis": "rule"
    },
    "trend": {
      "yes_no": 0.5564,
      "rule": "C > sma(C, 200)",
      "basis": "comparison"
    },
    "up_week": {
      "yes_no": 0.526
    }
  },
  "context": {
    "symbol": "IWM",
    "as_of": "2026-10-30"
  },
  "actions": [
    {
      "id": "buy",
      "fired": false,
      "status": "skipped"
    }
  ]
}

engulfing_bull lowest morning_star sma

Algo / bot developer · example 8

Volatility squeeze breakout bot for XLE

Trade breakouts that come out of a low-volatility squeeze, a classic bot setup.

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

State

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

Questions

squeezerulestd(C, 20) < 0.7 * std(C, 100) and C > highest(C, 20)
Squeeze, then a breakout
bbwEnglish → ruleIs Bollinger Band width at its lowest in 120 sessions?
linregrulelinreg(C, 20) > ref(linreg(C, 20), -5)
20-day regression line rising over a week
vol_riseforecastWill volatility rise over the next 5 days?
Volatility rising over 5 days

Answers

QuestionAnswerReading
squeeze
Squeeze, then a breakout
0.6462true
bbw
Is Bollinger Band width at its lowest in 120 sessions
compiled to ((bbupper(C, 20) - bblower(C, 20)) / bbmid(C, 20)) <= ref(min(((bbupper(C, 20) - bblower(C, 20)) / bbmid(C, 20)), 119), -1)
0.0774false
linreg
20-day regression line rising over a week
0.7215true
vol_rise
Volatility rising over 5 days
0.4646% · close to even

Actions

Rules on the answers decide what to send.

squeeze >= 0.6→Webhookbroker-api
What each action would send 1 of 1 fired · dry run, nothing sent
longwould send (dry run)Webhook → broker-api
{
  "symbol": "XLE",
  "side": "buy",
  "strategy": "squeeze_breakout",
  "p_slope_up": 0.7215,
  "as_of": "2026-10-30"
}

What it means

For XLE on the session of 2026-10-30: True now: Squeeze, then a breakout; 20-day regression line rising over a week. Not true: Is Bollinger Band width at its lowest in 120 sessions. Forecasts: Volatility rising over 5 days 46%. Fired: long (Webhook → broker-api).

Squeeze breakouts are rare; most days the bot simply does nothing, which is what a disciplined breakout bot should do.

Request JSON
{
  "model": "ora-fin-0.1.1",
  "state": {
    "symbol": "XLE"
  },
  "questions": {
    "squeeze": {
      "type": "yes_no",
      "ask": "std(C, 20) < 0.7 * std(C, 100) and C > highest(C, 20)"
    },
    "bbw": {
      "type": "yes_no",
      "instructions": "Is Bollinger Band width at its lowest in 120 sessions?"
    },
    "linreg": {
      "type": "yes_no",
      "ask": "linreg(C, 20) > ref(linreg(C, 20), -5)"
    },
    "vol_rise": {
      "type": "yes_no",
      "instructions": "Will volatility rise over the next 5 days?"
    }
  },
  "actions": [
    {
      "id": "long",
      "when": "squeeze >= 0.6",
      "do": "webhook",
      "connection": "broker-api",
      "body": {
        "symbol": "{{symbol}}",
        "side": "buy",
        "strategy": "squeeze_breakout",
        "p_slope_up": "{{linreg}}",
        "as_of": "{{as_of}}"
      }
    }
  ],
  "dry_run": true
}
Response JSON (XLE, real)
{
  "model": "ora-fin-0.1.1",
  "answers": {
    "squeeze": {
      "yes_no": 0.6462,
      "rule": "std(C, 20) < 0.7 * std(C, 100) and C > highest(C, 20)",
      "basis": "rule"
    },
    "bbw": {
      "yes_no": 0.0774,
      "rule": "((bbupper(C, 20) - bblower(C, 20)) / bbmid(C, 20)) <= ref(min(((bbupper(C, 20) - bblower(C, 20)) / bbmid(C, 20)), 119), -1)",
      "basis": "pattern"
    },
    "linreg": {
      "yes_no": 0.7215,
      "rule": "linreg(C, 20) > ref(linreg(C, 20), -5)",
      "basis": "rule"
    },
    "vol_rise": {
      "yes_no": 0.46
    }
  },
  "context": {
    "symbol": "XLE",
    "as_of": "2026-10-30"
  },
  "actions": [
    {
      "id": "long",
      "fired": true,
      "status": "dry_run",
      "do": "webhook",
      "connection": "broker-api",
      "preview": {
        "body": {
          "symbol": "XLE",
          "side": "buy",
          "strategy": "squeeze_breakout",
          "p_slope_up": 0.7215,
          "as_of": "2026-10-30"
        }
      }
    }
  ]
}

bblower bbmid bbupper highest linreg min ref std

Algo / bot developer · example 9

A voting bot: five momentum signals on NFLX

Combine five independent momentum rules into a vote, and only act when most agree.

ora-fin-0.1.1NFLX5 questions2 actions
  1. StateNFLX
  2. Questions5 asked
  3. Answersreal, captured
  4. Actions2 rules · dry run

State

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

Questions

macdrulemacd(C) > macdsignal(C)
MACD above its signal line
rsirulersi(C, 14) > 50
RSI above 50
rocruleroc(C, 20) > 5
Up more than 5% in 20 sessions
emaruleC > ema(C, 21)
close above the 21-day EMA
kdEnglish → ruleIs stochastic %K above %D?

Answers

QuestionAnswerReading
macd
MACD above its signal line
0.1584false
rsi
RSI above 50
0.0783false
roc
Up more than 5% in 20 sessions
0.1119false
ema
close above the 21-day EMA
0.0972false
kd
Is stochastic %K above %D
compiled to stochk(14, 3, 3) > stochd(14, 3, 3)
0.5569on the line (true)

Actions

Rules on the answers decide what to send.

macd >= 0.6 and rsi >= 0.6 and roc >= 0.6 and ema >= 0.6→Webhookbroker-api
else→Slackbot-log
What each action would send 1 of 2 fired · dry run, nothing sent
strongrule false: skipped
reportwould send (dry run)Slack → bot-log
{
  "text": "NFLX (2026-10-30) vote: MACD 16%, RSI 8%, ROC 11%, EMA 10%, stochastic 56%. No trade."
}

What it means

For NFLX on the session of 2026-10-30: Not true: MACD above its signal line; RSI above 50; Up more than 5% in 20 sessions; close above the 21-day EMA. On the line: Is stochastic %K above %D. Fired: report (Slack → bot-log).

Requiring several rules to agree trades fewer, cleaner signals; the log line shows exactly which votes were missing.

Request JSON
{
  "model": "ora-fin-0.1.1",
  "state": {
    "symbol": "NFLX"
  },
  "questions": {
    "macd": {
      "type": "yes_no",
      "ask": "macd(C) > macdsignal(C)"
    },
    "rsi": {
      "type": "yes_no",
      "ask": "rsi(C, 14) > 50"
    },
    "roc": {
      "type": "yes_no",
      "ask": "roc(C, 20) > 5"
    },
    "ema": {
      "type": "yes_no",
      "ask": "C > ema(C, 21)"
    },
    "kd": {
      "type": "yes_no",
      "instructions": "Is stochastic %K above %D?"
    }
  },
  "actions": [
    {
      "id": "strong",
      "when": "macd >= 0.6 and rsi >= 0.6 and roc >= 0.6 and ema >= 0.6",
      "do": "webhook",
      "connection": "broker-api",
      "body": {
        "symbol": "{{symbol}}",
        "side": "buy",
        "strategy": "momentum_vote",
        "as_of": "{{as_of}}"
      }
    },
    {
      "id": "report",
      "when": "else",
      "do": "slack",
      "connection": "bot-log",
      "message": "{{symbol}} ({{as_of}}) vote: MACD {{macd|pct}}, RSI {{rsi|pct}}, ROC {{roc|pct}}, EMA {{ema|pct}}, stochastic {{kd|pct}}. No trade."
    }
  ],
  "dry_run": true
}
Response JSON (NFLX, real)
{
  "model": "ora-fin-0.1.1",
  "answers": {
    "macd": {
      "yes_no": 0.1584,
      "rule": "macd(C) > macdsignal(C)",
      "basis": "rule"
    },
    "rsi": {
      "yes_no": 0.0783,
      "rule": "rsi(C, 14) > 50",
      "basis": "rule"
    },
    "roc": {
      "yes_no": 0.1119,
      "rule": "roc(C, 20) > 5",
      "basis": "rule"
    },
    "ema": {
      "yes_no": 0.0972,
      "rule": "C > ema(C, 21)",
      "basis": "rule"
    },
    "kd": {
      "yes_no": 0.5569,
      "rule": "stochk(14, 3, 3) > stochd(14, 3, 3)",
      "basis": "comparison"
    }
  },
  "context": {
    "symbol": "NFLX",
    "as_of": "2026-10-30"
  },
  "actions": [
    {
      "id": "strong",
      "fired": false,
      "status": "skipped"
    },
    {
      "id": "report",
      "fired": true,
      "status": "dry_run",
      "do": "slack",
      "connection": "bot-log",
      "preview": {
        "text": "NFLX (2026-10-30) vote: MACD 16%, RSI 8%, ROC 11%, EMA 10%, stochastic 56%. No trade."
      }
    }
  ]
}

ema macd macdsignal roc rsi stochd stochk

Algo / bot developer · example 10

Pairs bot: check both legs before trading XOM vs CVX

Check momentum and stretch for both energy majors before a relative-value bot opens a pair.

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

State

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

Questions

zsrulezscore(C, 20) > 1.5
close more than 1.5 standard deviations above its 20-day mean
zs_lowrulezscore(C, 20) < -1.5
close more than 1.5 standard deviations below its 20-day mean
rocruleroc(C, 10) > 0
10-day rate of change positive
beat_spyforecastWill it beat SPY over the next month?
Beating SPY over a month

Answers

Symbolzsrulezs_lowrulerocrulebeat_spyforecast
XOM0.60120.05370.88250.554
CVX0.50120.05550.87060.564

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: close more than 1.5 standard deviations above its 20-day mean: true for XOM of 2. close more than 1.5 standard deviations below its 20-day mean: true for none of 2. 10-day rate of change positive: true for XOM, CVX of 2. Highest odds for “Beating SPY over a month”: CVX at 56%.

A pair needs one leg stretched up and the other stretched down; the bot compares the two answer sets before sending any order.

Request JSON (XOM; the others differ only in the symbol)
{
  "model": "ora-fin-0.1.1",
  "state": {
    "symbol": "XOM"
  },
  "questions": {
    "zs": {
      "type": "yes_no",
      "ask": "zscore(C, 20) > 1.5"
    },
    "zs_low": {
      "type": "yes_no",
      "ask": "zscore(C, 20) < -1.5"
    },
    "roc": {
      "type": "yes_no",
      "ask": "roc(C, 10) > 0"
    },
    "beat_spy": {
      "type": "yes_no",
      "instructions": "Will it beat SPY over the next month?"
    }
  }
}
Response JSON (XOM, real)
{
  "model": "ora-fin-0.1.1",
  "answers": {
    "zs": {
      "yes_no": 0.6012,
      "rule": "zscore(C, 20) > 1.5",
      "basis": "rule"
    },
    "zs_low": {
      "yes_no": 0.0537,
      "rule": "zscore(C, 20) < -1.5",
      "basis": "rule"
    },
    "roc": {
      "yes_no": 0.8825,
      "rule": "roc(C, 10) > 0",
      "basis": "rule"
    },
    "beat_spy": {
      "yes_no": 0.554
    }
  },
  "context": {
    "symbol": "XOM",
    "as_of": "2026-10-30"
  }
}

roc zscore

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.