Use cases · Builders
Trading educator / newsletter: 20 ways to use Ora
Lessons and newsletters built on real setups, with the rule shown next to every claim. Each example is a complete, runnable request with the real answers it returned (32 requests, captured 2026-10-31), what they mean and, where it fits, the action it would send.
ora-fin-0.1.1. Another model changes the request JSON and the Playground link; run it there to see its answers.Rule functions and facts used by this player (62)
ref 7sma 6offset 4rsi 3avg 3highest 3swinghigh 3swinglow 3atr 3std 2morning_star 2evening_star 2bbupper 2min 2cci 2iif 1dragonfly_doji 1engulfing_bull 1hammer 1harami_bull 1piercing_line 1dark_cloud 1engulfing_bear 1gravestone_doji 1hanging_man 1shooting_star 1beat_eps_last 1beat_streak 1days_to_earnings 1macd 1bblower 1bbmid 1log 1sqrt 1lowest 1days_to_ex_div 1div_count_ttm 1div_yield_ttm 1raised_last 1years_of_growth 1gap_up 1stochd 1stochk 1willr 1max 1roc 1spinning_top 1three_black_crows 1three_white_soldiers 1barssince 1highestbars 1linreg 1lowestbars 1percentrank 1adx 1diminus 1diplus 1ema 1obv 1inside_bar 1marubozu 1outside_bar 1
Examples 1–10 of 20 · page 1 of 2
Trading educator / newsletter · example 1
Lesson: what 'above the 200-day' really means, live on SPY
Open a moving-average lesson with today's real answers, showing the English question and the exact rule it compiles to.
- StateSPY
- Questions5 asked
- Answersreal, captured
- Actionsnone
State
{"symbol":"SPY"} The server fills in the latest completed session.
Questions
en200 | English → rule | Is the stock above its 200-day moving average? |
rule200 | rule | C > sma(C, 200)close above the 200-day average, written as a rule |
en50 | English → rule | Is the stock above its 50-day moving average? |
slope | English → rule | Is the 200-day moving average rising, higher than 5 sessions ago? |
stacked | English → rule | Is price above the 20-day, the 20-day above the 50-day, and the 50-day above the 200-day moving average? |
Answers
| Question | Answer | Reading |
|---|---|---|
en200Is the stock above its 200-day moving average compiled to C > sma(C, 200) | 0.9451 | true |
rule200close above the 200-day average, written as a rule | 0.9451 | true |
en50Is the stock above its 50-day moving average compiled to C > sma(C, 50) | 0.1128 | false |
slopeIs the 200-day moving average rising, higher than 5 sessions ago compiled to sma(C, 200) > ref(sma(C, 200), -5) | 0.9463 | true |
stackedIs price above the 20-day, the 20-day above the 50-day, and the 50-day above the 200-day moving average compiled to (C > sma(C, 20)) and (sma(C, 20) > sma(C, 50)) and (sma(C, 50) > sma(C, 200)) | 0.0816 | false |
What it means
For SPY on the session of 2026-10-30: True now: Is the stock above its 200-day moving average; close above the 200-day average, written as a rule; Is the 200-day moving average rising, higher than 5 sessions ago. Not true: Is the stock above its 50-day moving average; Is price above the 20-day, the 20-day above the 50-day, and the 50-day above the 200-day moving average.
Students see that the English question and the written rule give the same answer, which is the point of the lesson: words map to exact rules.
Request JSON
{
"model": "ora-fin-0.1.1",
"state": {
"symbol": "SPY"
},
"questions": {
"en200": {
"type": "yes_no",
"instructions": "Is the stock above its 200-day moving average?"
},
"rule200": {
"type": "yes_no",
"ask": "C > sma(C, 200)"
},
"en50": {
"type": "yes_no",
"instructions": "Is the stock above its 50-day moving average?"
},
"slope": {
"type": "yes_no",
"instructions": "Is the 200-day moving average rising, higher than 5 sessions ago?"
},
"stacked": {
"type": "yes_no",
"instructions": "Is price above the 20-day, the 20-day above the 50-day, and the 50-day above the 200-day moving average?"
}
}
}Response JSON (SPY, real)
{
"model": "ora-fin-0.1.1",
"answers": {
"en200": {
"yes_no": 0.9451,
"rule": "C > sma(C, 200)",
"basis": "comparison"
},
"rule200": {
"yes_no": 0.9451,
"rule": "C > sma(C, 200)",
"basis": "rule"
},
"en50": {
"yes_no": 0.1128,
"rule": "C > sma(C, 50)",
"basis": "comparison"
},
"slope": {
"yes_no": 0.9463,
"rule": "sma(C, 200) > ref(sma(C, 200), -5)",
"basis": "pattern"
},
"stacked": {
"yes_no": 0.0816,
"rule": "(C > sma(C, 20)) and (sma(C, 20) > sma(C, 50)) and (sma(C, 50) > sma(C, 200))",
"basis": "pattern"
}
},
"context": {
"symbol": "SPY",
"as_of": "2026-10-30"
}
}Trading educator / newsletter · example 2
Lesson: RSI overbought and oversold, with live examples on AAPL and TSLA
Show the same RSI questions on a calm stock and a volatile one, so students see that thresholds behave differently.
- State2 symbols
- Questions5 asked
- Answersreal, captured
- Actionsnone
State
{"symbol":"AAPL"} then TSLA, one request each. The server fills in the latest completed session.
Questions
ob | English → rule | Is the stock overbought on RSI, above 70? |
os | English → rule | Is the stock oversold on RSI, below 30? |
above50 | English → rule | Is the 14-day RSI above 50? |
rsi2 | rule | rsi(C, 2) < 10Two-day RSI under 10 |
adaptive | rule | rsi(C, 14) < iif(C > sma(C, 200), 40, 30)RSI under 40 in an uptrend, under 30 otherwise |
Answers
| Symbol | obrule | osrule | above50rule | rsi2rule | adaptiverule |
|---|---|---|---|---|---|
AAPL | 0.0657 | 0.0537 | 0.8179 | 0.1464 | 0.0634 |
TSLA | 0.0873 | 0.0537 | 0.9267 | 0.1345 | 0.0537 |
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 stock overbought on RSI, above 70: true for none of 2. Is the stock oversold on RSI, below 30: true for none of 2. Is the 14-day RSI above 50: true for AAPL, TSLA of 2. Two-day RSI under 10: true for none of 2.
The adaptive rule shows students how professionals change the oversold line with the trend instead of using one number everywhere.
Request JSON (AAPL; the others differ only in the symbol)
{
"model": "ora-fin-0.1.1",
"state": {
"symbol": "AAPL"
},
"questions": {
"ob": {
"type": "yes_no",
"instructions": "Is the stock overbought on RSI, above 70?"
},
"os": {
"type": "yes_no",
"instructions": "Is the stock oversold on RSI, below 30?"
},
"above50": {
"type": "yes_no",
"instructions": "Is the 14-day RSI above 50?"
},
"rsi2": {
"type": "yes_no",
"ask": "rsi(C, 2) < 10"
},
"adaptive": {
"type": "yes_no",
"ask": "rsi(C, 14) < iif(C > sma(C, 200), 40, 30)"
}
}
}Response JSON (AAPL, real)
{
"model": "ora-fin-0.1.1",
"answers": {
"ob": {
"yes_no": 0.0657,
"rule": "rsi(C, 14) > 70",
"basis": "pattern"
},
"os": {
"yes_no": 0.0537,
"rule": "rsi(C, 14) < 30",
"basis": "pattern"
},
"above50": {
"yes_no": 0.8179,
"rule": "rsi(C, 14) > 50",
"basis": "comparison"
},
"rsi2": {
"yes_no": 0.1464,
"rule": "rsi(C, 2) < 10",
"basis": "rule"
},
"adaptive": {
"yes_no": 0.0634,
"rule": "rsi(C, 14) < iif(C > sma(C, 200), 40, 30)",
"basis": "rule"
}
},
"context": {
"symbol": "AAPL",
"as_of": "2026-10-30"
}
}Trading educator / newsletter · example 3
Weekly newsletter: three setups with the rule behind every claim
Every Sunday-night issue checks the same setups on a few names and publishes the rule next to each yes or no.
- ScheduleFri at 18:00 ET
- State3 symbols
- Questions4 asked
- Answersreal, captured
- Actions1 rule · dry run
State
{"symbol":"NVDA"} then MSFT, AMZN, one request each. The server fills in the latest completed session.
Questions
pullback | rule | C > sma(C, 200) and C < sma(C, 20) and rsi(C, 14) > 40Uptrend, under the 20-day, RSI still above 40 |
breakout | rule | C > highest(C, 20) and V > 1.5 * ref(avg(V, 20), -1)20-day breakout on 1.5× volume |
squeeze | rule | std(C, 20) < 0.7 * std(C, 100) and C > highest(C, 20)Squeeze, then a breakout |
up_week | forecast | Will the stock be higher in a week? Higher in a week |
Answers
| Symbol | pullbackrule | breakoutrule | squeezerule | up_weekforecast | Fired |
|---|---|---|---|---|---|
NVDA | 0.2184 | 0.0537 | 0.0537 | 0.527 | draft |
MSFT | 0.7427 | 0.0604 | 0.0604 | 0.574 | draft |
AMZN | 0.3073 | 0.0545 | 0.0545 | 0.493 | draft |
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.
pullback >= 0→Webhooknewsletter-platform{
"issue": "weekly_setups",
"symbol": "NVDA",
"as_of": "2026-10-30",
"trend_pullback": 0.2184,
"breakout_on_volume": 0.0537,
"squeeze_breakout": 0.0537,
"p_higher_in_week": 0.527,
"disclaimer": "Education only, not investment advice."
}{
"issue": "weekly_setups",
"symbol": "MSFT",
"as_of": "2026-10-30",
"trend_pullback": 0.7427,
"breakout_on_volume": 0.0604,
"squeeze_breakout": 0.0604,
"p_higher_in_week": 0.574,
"disclaimer": "Education only, not investment advice."
}{
"issue": "weekly_setups",
"symbol": "AMZN",
"as_of": "2026-10-30",
"trend_pullback": 0.3073,
"breakout_on_volume": 0.0545,
"squeeze_breakout": 0.0545,
"p_higher_in_week": 0.493,
"disclaimer": "Education only, not investment advice."
}What it means
Session of 2026-10-30, 3 symbols: Uptrend, under the 20-day, RSI still above 40: true for MSFT of 3. 20-day breakout on 1.5× volume: true for none of 3. Squeeze, then a breakout: true for none of 3. Highest odds for “Higher in a week”: MSFT at 57%. draft fired for NVDA, MSFT, AMZN.
The platform receives a draft block per symbol with a disclaimer built in; the editor writes the prose around real answers.
As a scheduled workflow (Fri at 18: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": "Weekly newsletter: three setups with the rule behind every claim",
"symbols": "NVDA MSFT AMZN",
"days": [
5
],
"at_time": "18:00",
"model": "ora-fin-0.1.1",
"questions": {
"pullback": {
"type": "yes_no",
"ask": "C > sma(C, 200) and C < sma(C, 20) and rsi(C, 14) > 40"
},
"breakout": {
"type": "yes_no",
"ask": "C > highest(C, 20) and V > 1.5 * ref(avg(V, 20), -1)"
},
"squeeze": {
"type": "yes_no",
"ask": "std(C, 20) < 0.7 * std(C, 100) and C > highest(C, 20)"
},
"up_week": {
"type": "yes_no",
"instructions": "Will the stock be higher in a week?"
}
},
"actions": [
{
"id": "draft",
"when": "pullback >= 0",
"do": "webhook",
"connection": "newsletter-platform",
"body": {
"issue": "weekly_setups",
"symbol": "{{symbol}}",
"as_of": "{{as_of}}",
"trend_pullback": "{{pullback}}",
"breakout_on_volume": "{{breakout}}",
"squeeze_breakout": "{{squeeze}}",
"p_higher_in_week": "{{up_week}}",
"disclaimer": "Education only, not investment advice."
}
}
]
}Request JSON (NVDA; the others differ only in the symbol)
{
"model": "ora-fin-0.1.1",
"state": {
"symbol": "NVDA"
},
"questions": {
"pullback": {
"type": "yes_no",
"ask": "C > sma(C, 200) and C < sma(C, 20) and rsi(C, 14) > 40"
},
"breakout": {
"type": "yes_no",
"ask": "C > highest(C, 20) and V > 1.5 * ref(avg(V, 20), -1)"
},
"squeeze": {
"type": "yes_no",
"ask": "std(C, 20) < 0.7 * std(C, 100) and C > highest(C, 20)"
},
"up_week": {
"type": "yes_no",
"instructions": "Will the stock be higher in a week?"
}
},
"actions": [
{
"id": "draft",
"when": "pullback >= 0",
"do": "webhook",
"connection": "newsletter-platform",
"body": {
"issue": "weekly_setups",
"symbol": "{{symbol}}",
"as_of": "{{as_of}}",
"trend_pullback": "{{pullback}}",
"breakout_on_volume": "{{breakout}}",
"squeeze_breakout": "{{squeeze}}",
"p_higher_in_week": "{{up_week}}",
"disclaimer": "Education only, not investment advice."
}
}
],
"dry_run": true
}Response JSON (NVDA, real)
{
"model": "ora-fin-0.1.1",
"answers": {
"pullback": {
"yes_no": 0.2184,
"rule": "C > sma(C, 200) and C < sma(C, 20) and rsi(C, 14) > 40",
"basis": "rule"
},
"breakout": {
"yes_no": 0.0537,
"rule": "C > highest(C, 20) and V > 1.5 * ref(avg(V, 20), -1)",
"basis": "rule"
},
"squeeze": {
"yes_no": 0.0537,
"rule": "std(C, 20) < 0.7 * std(C, 100) and C > highest(C, 20)",
"basis": "rule"
},
"up_week": {
"yes_no": 0.527
}
},
"context": {
"symbol": "NVDA",
"as_of": "2026-10-30"
},
"actions": [
{
"id": "draft",
"fired": true,
"status": "dry_run",
"do": "webhook",
"connection": "newsletter-platform",
"preview": {
"body": {
"issue": "weekly_setups",
"symbol": "NVDA",
"as_of": "2026-10-30",
"trend_pullback": 0.2184,
"breakout_on_volume": 0.0537,
"squeeze_breakout": 0.0537,
"p_higher_in_week": 0.527,
"disclaimer": "Education only, not investment advice."
}
}
}
]
}Trading educator / newsletter · example 4
Lesson: bullish reversal candles, checked on IWM today
Teach six bullish reversal patterns and show which, if any, printed on the latest bar.
- StateIWM
- Questions6 asked
- Answersreal, captured
- Actions2 rules · dry run
State
{"symbol":"IWM"} The server fills in the latest completed session.
Questions
hammer | English → rule | Is today's candle a hammer after a decline? |
engulf | English → rule | Is today a bullish engulfing candle? |
harami | English → rule | Is today a bullish harami? |
piercing | English → rule | Is today a piercing line? |
morning | English → rule | Is there a morning star on the last three candles? |
dragonfly | English → rule | Is today's candle a dragonfly doji? |
Answers
| Question | Answer | Reading |
|---|---|---|
hammerIs today's candle a hammer after a decline compiled to hammer() | 0.1246 | false |
engulfIs today a bullish engulfing candle compiled to engulfing_bull() | 0.0926 | false |
haramiIs today a bullish harami compiled to harami_bull() | 0.0926 | false |
piercingIs today a piercing line compiled to piercing_line() | 0.0887 | false |
morningIs there a morning star on the last three candles compiled to morning_star() | 0.0906 | false |
dragonflyIs today's candle a dragonfly doji compiled to dragonfly_doji() | 0.0698 | false |
Actions
Rules on the answers decide what to send.
hammer >= 0.6 or engulf >= 0.6 or harami >= 0.6 or piercing >= 0.6 or morning >= 0.6 or dragonfly >= 0.6→Slackclass-channelelse→Slackclass-channel{
"text": "No bullish reversal candle on IWM (2026-10-30). That is the usual case: reversal candles are rare."
}What it means
For IWM on the session of 2026-10-30: Not true: Is today's candle a hammer after a decline; Is today a bullish engulfing candle; Is today a bullish harami; Is today a piercing line; Is there a morning star on the last three candles; Is today's candle a dragonfly doji. Fired: none (Slack → class-channel).
Most days none of them is true; that is a lesson too, because reversal candles are rare and should not be seen everywhere.
Request JSON
{
"model": "ora-fin-0.1.1",
"state": {
"symbol": "IWM"
},
"questions": {
"hammer": {
"type": "yes_no",
"instructions": "Is today's candle a hammer after a decline?"
},
"engulf": {
"type": "yes_no",
"instructions": "Is today a bullish engulfing candle?"
},
"harami": {
"type": "yes_no",
"instructions": "Is today a bullish harami?"
},
"piercing": {
"type": "yes_no",
"instructions": "Is today a piercing line?"
},
"morning": {
"type": "yes_no",
"instructions": "Is there a morning star on the last three candles?"
},
"dragonfly": {
"type": "yes_no",
"instructions": "Is today's candle a dragonfly doji?"
}
},
"actions": [
{
"id": "spotted",
"when": "hammer >= 0.6 or engulf >= 0.6 or harami >= 0.6 or piercing >= 0.6 or morning >= 0.6 or dragonfly >= 0.6",
"do": "slack",
"connection": "class-channel",
"message": "Candle spotted on {{symbol}} ({{as_of}}): hammer {{hammer|pct}}, engulfing {{engulf|pct}}, harami {{harami|pct}}, piercing {{piercing|pct}}, morning star {{morning|pct}}, dragonfly {{dragonfly|pct}}."
},
{
"id": "none",
"when": "else",
"do": "slack",
"connection": "class-channel",
"message": "No bullish reversal candle on {{symbol}} ({{as_of}}). That is the usual case: reversal candles are rare."
}
],
"dry_run": true
}Response JSON (IWM, real)
{
"model": "ora-fin-0.1.1",
"answers": {
"hammer": {
"yes_no": 0.1246,
"rule": "hammer()",
"basis": "pattern"
},
"engulf": {
"yes_no": 0.0926,
"rule": "engulfing_bull()",
"basis": "pattern"
},
"harami": {
"yes_no": 0.0926,
"rule": "harami_bull()",
"basis": "pattern"
},
"piercing": {
"yes_no": 0.0887,
"rule": "piercing_line()",
"basis": "pattern"
},
"morning": {
"yes_no": 0.0906,
"rule": "morning_star()",
"basis": "pattern"
},
"dragonfly": {
"yes_no": 0.0698,
"rule": "dragonfly_doji()",
"basis": "pattern"
}
},
"context": {
"symbol": "IWM",
"as_of": "2026-10-30"
},
"actions": [
{
"id": "spotted",
"fired": false,
"status": "skipped"
},
{
"id": "none",
"fired": true,
"status": "dry_run",
"do": "slack",
"connection": "class-channel",
"preview": {
"text": "No bullish reversal candle on IWM (2026-10-30). That is the usual case: reversal candles are rare."
}
}
]
}dragonfly_doji engulfing_bull hammer harami_bull morning_star piercing_line
Trading educator / newsletter · example 5
Lesson: bearish reversal candles on QQQ
The bearish counterpart: engulfing, dark cloud, evening star, shooting star, hanging man and gravestone doji.
- StateQQQ
- Questions6 asked
- Answersreal, captured
- Actionsnone
State
{"symbol":"QQQ"} The server fills in the latest completed session.
Questions
engulf | English → rule | Is today a bearish engulfing candle? |
cloud | English → rule | Is today a dark cloud cover? |
evening | English → rule | Is there an evening star on the last three candles? |
star | English → rule | Is today's candle a shooting star? |
hanging | rule | hanging_man()hanging man candle: Hammer shape, closing above the close five bars back. |
gravestone | rule | gravestone_doji()gravestone doji candle: Doji with a long upper wick and almost no lower wick. |
Answers
| Question | Answer | Reading |
|---|---|---|
engulfIs today a bearish engulfing candle compiled to engulfing_bear() | 0.0537 | false |
cloudIs today a dark cloud cover compiled to dark_cloud() | 0.0537 | false |
eveningIs there an evening star on the last three candles compiled to evening_star() | 0.0863 | false |
starIs today's candle a shooting star compiled to shooting_star() | 0.0537 | false |
hanginghanging man candle: Hammer shape, closing above the close five bars back. | 0.1466 | false |
gravestonegravestone doji candle: Doji with a long upper wick and almost no lower wick. | 0.0537 | false |
What it means
For QQQ on the session of 2026-10-30: Not true: Is today a bearish engulfing candle; Is today a dark cloud cover; Is there an evening star on the last three candles; Is today's candle a shooting star; hanging man candle: Hammer shape, closing above the close five bars back.; gravestone doji candle: Doji with a long upper wick and almost no lower wick..
Each answer carries its pattern function, so students can open the definition and see why a candle did or did not qualify.
Request JSON
{
"model": "ora-fin-0.1.1",
"state": {
"symbol": "QQQ"
},
"questions": {
"engulf": {
"type": "yes_no",
"instructions": "Is today a bearish engulfing candle?"
},
"cloud": {
"type": "yes_no",
"instructions": "Is today a dark cloud cover?"
},
"evening": {
"type": "yes_no",
"instructions": "Is there an evening star on the last three candles?"
},
"star": {
"type": "yes_no",
"instructions": "Is today's candle a shooting star?"
},
"hanging": {
"type": "yes_no",
"ask": "hanging_man()"
},
"gravestone": {
"type": "yes_no",
"ask": "gravestone_doji()"
}
}
}Response JSON (QQQ, real)
{
"model": "ora-fin-0.1.1",
"answers": {
"engulf": {
"yes_no": 0.0537,
"rule": "engulfing_bear()",
"basis": "pattern"
},
"cloud": {
"yes_no": 0.0537,
"rule": "dark_cloud()",
"basis": "pattern"
},
"evening": {
"yes_no": 0.0863,
"rule": "evening_star()",
"basis": "pattern"
},
"star": {
"yes_no": 0.0537,
"rule": "shooting_star()",
"basis": "pattern"
},
"hanging": {
"yes_no": 0.1466,
"rule": "hanging_man()",
"basis": "rule"
},
"gravestone": {
"yes_no": 0.0537,
"rule": "gravestone_doji()",
"basis": "rule"
}
},
"context": {
"symbol": "QQQ",
"as_of": "2026-10-30"
}
}dark_cloud engulfing_bear evening_star gravestone_doji hanging_man shooting_star
Trading educator / newsletter · example 6
Lesson: facts versus forecasts, using NVDA's earnings
Show the difference between questions with an exact answer (did it beat) and questions that are odds (will it beat).
- StateNVDA
- Questions5 asked
- Answersreal, captured
- Actions1 rule · dry run
State
{"symbol":"NVDA"} The server fills in the latest completed session.
Questions
beat | English → rule | Did the stock beat EPS estimates last quarter? |
streak | English → rule | Has the stock beaten EPS estimates 4 quarters in a row? |
soon | English → rule | Is earnings in the next 14 days? |
beat_next | forecast | Will the stock beat earnings next quarter? Beating earnings next quarter |
big_move | forecast | Will there be a big move in either direction in the next 5 days? A big move either way in 5 days |
Answers
| Question | Answer | Reading |
|---|---|---|
beatDid the stock beat EPS estimates last quarter compiled to beat_eps_last > 0.5 | 0.8591 | true |
streakHas the stock beaten EPS estimates 4 quarters in a row compiled to beat_streak >= 4 | 0.9463 | true |
soonIs earnings in the next 14 days compiled to days_to_earnings <= 14 | 0.1033 | false |
beat_nextBeating earnings next quarter | 0.516 | 52% · close to even |
big_moveA big move either way in 5 days | 0.318 | 32% · unlikely |
Actions
Rules on the answers decide what to send.
beat >= 0→Webhookcourse-platform{
"lesson": "facts_vs_forecasts",
"symbol": "NVDA",
"as_of": "2026-10-30",
"fact_beat_last": 0.8591,
"fact_streak4": 0.9463,
"fact_earnings_14d": 0.1033,
"forecast_beat_next": 0.516,
"forecast_big_move": 0.318
}What it means
For NVDA on the session of 2026-10-30: True now: Did the stock beat EPS estimates last quarter; Has the stock beaten EPS estimates 4 quarters in a row. Not true: Is earnings in the next 14 days. Forecasts: Beating earnings next quarter 52%; A big move either way in 5 days 32%. Fired: post (Webhook → course-platform).
Facts come back with a rule and sit near yes or no; forecasts come back with no rule and sit near the middle, which students learn to read as odds.
Request JSON
{
"model": "ora-fin-0.1.1",
"state": {
"symbol": "NVDA"
},
"questions": {
"beat": {
"type": "yes_no",
"instructions": "Did the stock beat EPS estimates last quarter?"
},
"streak": {
"type": "yes_no",
"instructions": "Has the stock beaten EPS estimates 4 quarters in a row?"
},
"soon": {
"type": "yes_no",
"instructions": "Is earnings in the next 14 days?"
},
"beat_next": {
"type": "yes_no",
"instructions": "Will the stock beat earnings next quarter?"
},
"big_move": {
"type": "yes_no",
"instructions": "Will there be a big move in either direction in the next 5 days?"
}
},
"actions": [
{
"id": "post",
"when": "beat >= 0",
"do": "webhook",
"connection": "course-platform",
"body": {
"lesson": "facts_vs_forecasts",
"symbol": "{{symbol}}",
"as_of": "{{as_of}}",
"fact_beat_last": "{{beat}}",
"fact_streak4": "{{streak}}",
"fact_earnings_14d": "{{soon}}",
"forecast_beat_next": "{{beat_next}}",
"forecast_big_move": "{{big_move}}"
}
}
],
"dry_run": true
}Response JSON (NVDA, real)
{
"model": "ora-fin-0.1.1",
"answers": {
"beat": {
"yes_no": 0.8591,
"rule": "beat_eps_last > 0.5",
"basis": "pattern"
},
"streak": {
"yes_no": 0.9463,
"rule": "beat_streak >= 4",
"basis": "pattern"
},
"soon": {
"yes_no": 0.1033,
"rule": "days_to_earnings <= 14",
"basis": "pattern"
},
"beat_next": {
"yes_no": 0.516
},
"big_move": {
"yes_no": 0.318
}
},
"context": {
"symbol": "NVDA",
"as_of": "2026-10-30"
},
"actions": [
{
"id": "post",
"fired": true,
"status": "dry_run",
"do": "webhook",
"connection": "course-platform",
"preview": {
"body": {
"lesson": "facts_vs_forecasts",
"symbol": "NVDA",
"as_of": "2026-10-30",
"fact_beat_last": 0.8591,
"fact_streak4": 0.9463,
"fact_earnings_14d": 0.1033,
"forecast_beat_next": 0.516,
"forecast_big_move": 0.318
}
}
}
]
}Trading educator / newsletter · example 7
Quiz of the day: is KO in an uptrend? Post the answer to the class Slack
Each weekday, post yesterday's quiz answer with the rule, so students can check their own chart reading.
- ScheduleMon–Fri at 08:00 ET
- StateKO
- Questions4 asked
- Answersreal, captured
- Actions1 rule · dry run
State
{"symbol":"KO"} The server fills in the latest completed session.
Questions
trend | English → rule | Is the stock above its 200-day moving average? |
macd | English → rule | Is MACD above zero? |
rsi | English → rule | Is the 14-day RSI above 50? |
hh_hl | English → rule | Is the stock making higher swing highs and higher swing lows? |
Answers
| Question | Answer | Reading |
|---|---|---|
trendIs the stock above its 200-day moving average compiled to C > sma(C, 200) | 0.9463 | true |
macdIs MACD above zero compiled to macd(C) > 0 | 0.9314 | true |
rsiIs the 14-day RSI above 50 compiled to rsi(C, 14) > 50 | 0.8988 | true |
hh_hlIs the stock making higher swing highs and higher swing lows compiled to (swinghigh(5, 1) > swinghigh(5, 2)) and (swinglow(5, 1) > swinglow(5, 2)) | 0.1446 | false |
Actions
Rules on the answers decide what to send.
trend >= 0→Slackclass-channel{
"text": "Quiz answer for KO (2026-10-30): above the 200-day 95%, MACD above zero 93%, RSI over 50 90%, higher swing highs and lows 14%. How did your read compare?"
}What it means
For KO on the session of 2026-10-30: True now: Is the stock above its 200-day moving average; Is MACD above zero; Is the 14-day RSI above 50. Not true: Is the stock making higher swing highs and higher swing lows. Fired: answer (Slack → class-channel).
The answer is posted the next morning, so students commit to a view first and then compare with the exact rules.
As a scheduled workflow (Mon–Fri at 08: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": "Quiz of the day: is KO in an uptrend? Post the answer to the class Slack",
"symbols": "KO",
"days": [
1,
2,
3,
4,
5
],
"at_time": "08:00",
"model": "ora-fin-0.1.1",
"questions": {
"trend": {
"type": "yes_no",
"instructions": "Is the stock above its 200-day moving average?"
},
"macd": {
"type": "yes_no",
"instructions": "Is MACD above zero?"
},
"rsi": {
"type": "yes_no",
"instructions": "Is the 14-day RSI above 50?"
},
"hh_hl": {
"type": "yes_no",
"instructions": "Is the stock making higher swing highs and higher swing lows?"
}
},
"actions": [
{
"id": "answer",
"when": "trend >= 0",
"do": "slack",
"connection": "class-channel",
"message": "Quiz answer for {{symbol}} ({{as_of}}): above the 200-day {{trend|pct}}, MACD above zero {{macd|pct}}, RSI over 50 {{rsi|pct}}, higher swing highs and lows {{hh_hl|pct}}. How did your read compare?"
}
]
}Request JSON
{
"model": "ora-fin-0.1.1",
"state": {
"symbol": "KO"
},
"questions": {
"trend": {
"type": "yes_no",
"instructions": "Is the stock above its 200-day moving average?"
},
"macd": {
"type": "yes_no",
"instructions": "Is MACD above zero?"
},
"rsi": {
"type": "yes_no",
"instructions": "Is the 14-day RSI above 50?"
},
"hh_hl": {
"type": "yes_no",
"instructions": "Is the stock making higher swing highs and higher swing lows?"
}
},
"actions": [
{
"id": "answer",
"when": "trend >= 0",
"do": "slack",
"connection": "class-channel",
"message": "Quiz answer for {{symbol}} ({{as_of}}): above the 200-day {{trend|pct}}, MACD above zero {{macd|pct}}, RSI over 50 {{rsi|pct}}, higher swing highs and lows {{hh_hl|pct}}. How did your read compare?"
}
],
"dry_run": true
}Response JSON (KO, real)
{
"model": "ora-fin-0.1.1",
"answers": {
"trend": {
"yes_no": 0.9463,
"rule": "C > sma(C, 200)",
"basis": "comparison"
},
"macd": {
"yes_no": 0.9314,
"rule": "macd(C) > 0",
"basis": "pattern"
},
"rsi": {
"yes_no": 0.8988,
"rule": "rsi(C, 14) > 50",
"basis": "comparison"
},
"hh_hl": {
"yes_no": 0.1446,
"rule": "(swinghigh(5, 1) > swinghigh(5, 2)) and (swinglow(5, 1) > swinglow(5, 2))",
"basis": "pattern"
}
},
"context": {
"symbol": "KO",
"as_of": "2026-10-30"
},
"actions": [
{
"id": "answer",
"fired": true,
"status": "dry_run",
"do": "slack",
"connection": "class-channel",
"preview": {
"text": "Quiz answer for KO (2026-10-30): above the 200-day 95%, MACD above zero 93%, RSI over 50 90%, higher swing highs and lows 14%. How did your read compare?"
}
}
]
}Trading educator / newsletter · example 8
Lesson: ATR, Bollinger Bands and realized volatility on TLT
Explain three ways to measure volatility, with today's answers for a bond fund.
- StateTLT
- Questions5 asked
- Answersreal, captured
- Actionsnone
State
{"symbol":"TLT"} The server fills in the latest completed session.
Questions
atr | English → rule | Is the 14-day ATR less than 2% of the price? |
bb | English → rule | Is Bollinger Band width at its lowest in 120 sessions? |
hv | English → rule | Is 20-day historical volatility below 20%? |
vol5 | English → rule | Is 5-day volatility higher than 20-day volatility? |
next | forecast | Will volatility be higher over the next month? Higher volatility next month |
Answers
| Question | Answer | Reading |
|---|---|---|
atrIs the 14-day ATR less than 2% of the price compiled to atr(14) / C < 0.02 | 0.9463 | true |
bbIs 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.055 | false |
hvIs 20-day historical volatility below 20% compiled to std(log(C / C[-1]), 20) * sqrt(20 / 19) * sqrt(252) < 0.2 | 0.9463 | true |
vol5Is 5-day volatility higher than 20-day volatility compiled to std(log(C / C[-1]), 5) * sqrt(5 / 4) > std(log(C / C[-1]), 20) * sqrt(20 / 19) | 0.2703 | false |
nextHigher volatility next month | 0.583 | 58% · close to even |
What it means
For TLT on the session of 2026-10-30: True now: Is the 14-day ATR less than 2% of the price; Is 20-day historical volatility below 20%. Not true: Is Bollinger Band width at its lowest in 120 sessions; Is 5-day volatility higher than 20-day volatility. Forecasts: Higher volatility next month 58%.
Three measures usually agree on calm or wild; when they disagree, the lesson asks students why.
Request JSON
{
"model": "ora-fin-0.1.1",
"state": {
"symbol": "TLT"
},
"questions": {
"atr": {
"type": "yes_no",
"instructions": "Is the 14-day ATR less than 2% of the price?"
},
"bb": {
"type": "yes_no",
"instructions": "Is Bollinger Band width at its lowest in 120 sessions?"
},
"hv": {
"type": "yes_no",
"instructions": "Is 20-day historical volatility below 20%?"
},
"vol5": {
"type": "yes_no",
"instructions": "Is 5-day volatility higher than 20-day volatility?"
},
"next": {
"type": "yes_no",
"instructions": "Will volatility be higher over the next month?"
}
}
}Response JSON (TLT, real)
{
"model": "ora-fin-0.1.1",
"answers": {
"atr": {
"yes_no": 0.9463,
"rule": "atr(14) / C < 0.02",
"basis": "pattern"
},
"bb": {
"yes_no": 0.055,
"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"
},
"hv": {
"yes_no": 0.9463,
"rule": "std(log(C / C[-1]), 20) * sqrt(20 / 19) * sqrt(252) < 0.2",
"basis": "pattern"
},
"vol5": {
"yes_no": 0.2703,
"rule": "std(log(C / C[-1]), 5) * sqrt(5 / 4) > std(log(C / C[-1]), 20) * sqrt(20 / 19)",
"basis": "pattern"
},
"next": {
"yes_no": 0.583
}
},
"context": {
"symbol": "TLT",
"as_of": "2026-10-30"
}
}Trading educator / newsletter · example 9
Lesson: swing highs, swing lows and trend structure on CVX
Teach market structure with confirmed pivots: higher highs, higher lows, and the second-to-last swing with k.
- StateCVX
- Questions5 asked
- Answersreal, captured
- Actionsnone
State
{"symbol":"CVX"} The server fills in the latest completed session.
Questions
hh | rule | swinghigh(5, 1) > swinghigh(5, 2)latest 5-bar swing high above the one before |
hl | rule | swinglow(5, 1) > swinglow(5, 2)latest 5-bar swing low above the one before |
above | English → rule | Did the stock close above its last swing high today? |
near_sup | English → rule | Is the stock within 2% above its last swing low (support)? |
lower | English → rule | Is the stock making lower swing highs and lower swing lows? |
Answers
| Question | Answer | Reading |
|---|---|---|
hhlatest 5-bar swing high above the one before | 0.9252 | true |
hllatest 5-bar swing low above the one before | 0.5739 | on the line (true) |
aboveDid the stock close above its last swing high today compiled to (C > swinghigh(5, 1)) and (C[-1] <= ref(swinghigh(5, 1), -1)) | 0.083 | false |
near_supIs the stock within 2% above its last swing low (support) compiled to (C >= swinglow(5, 1)) and (C <= swinglow(5, 1) * 1.02) | 0.0537 | false |
lowerIs the stock making lower swing highs and lower swing lows compiled to (swinghigh(5, 1) < swinghigh(5, 2)) and (swinglow(5, 1) < swinglow(5, 2)) | 0.0748 | false |
What it means
For CVX on the session of 2026-10-30: True now: latest 5-bar swing high above the one before. Not true: Did the stock close above its last swing high today; Is the stock within 2% above its last swing low (support); Is the stock making lower swing highs and lower swing lows. On the line: latest 5-bar swing low above the one before.
Pivots are confirmed five bars later, which teaches students why structure always lags price a little.
Request JSON
{
"model": "ora-fin-0.1.1",
"state": {
"symbol": "CVX"
},
"questions": {
"hh": {
"type": "yes_no",
"ask": "swinghigh(5, 1) > swinghigh(5, 2)"
},
"hl": {
"type": "yes_no",
"ask": "swinglow(5, 1) > swinglow(5, 2)"
},
"above": {
"type": "yes_no",
"instructions": "Did the stock close above its last swing high today?"
},
"near_sup": {
"type": "yes_no",
"instructions": "Is the stock within 2% above its last swing low (support)?"
},
"lower": {
"type": "yes_no",
"instructions": "Is the stock making lower swing highs and lower swing lows?"
}
}
}Response JSON (CVX, real)
{
"model": "ora-fin-0.1.1",
"answers": {
"hh": {
"yes_no": 0.9252,
"rule": "swinghigh(5, 1) > swinghigh(5, 2)",
"basis": "rule"
},
"hl": {
"yes_no": 0.5739,
"rule": "swinglow(5, 1) > swinglow(5, 2)",
"basis": "rule"
},
"above": {
"yes_no": 0.083,
"rule": "(C > swinghigh(5, 1)) and (C[-1] <= ref(swinghigh(5, 1), -1))",
"basis": "pattern"
},
"near_sup": {
"yes_no": 0.0537,
"rule": "(C >= swinglow(5, 1)) and (C <= swinglow(5, 1) * 1.02)",
"basis": "pattern"
},
"lower": {
"yes_no": 0.0748,
"rule": "(swinghigh(5, 1) < swinghigh(5, 2)) and (swinglow(5, 1) < swinglow(5, 2))",
"basis": "pattern"
}
},
"context": {
"symbol": "CVX",
"as_of": "2026-10-30"
}
}Trading educator / newsletter · example 10
Lesson: real breakout or fakeout? XLE today
Compare a price breakout with its volume confirmation and the one-week forecast.
- StateXLE
- Questions4 asked
- Answersreal, captured
- Actions2 rules · dry run
State
{"symbol":"XLE"} The server fills in the latest completed session.
Questions
price | rule | C > highest(C, 20)20-day closing breakout |
volume | rule | V > 2 * ref(avg(V, 20), -1)Volume more than twice the previous 20-day average |
failed | rule | L < lowest(L, 20) and C > lowest(L, 20)Undercut the 20-day low and closed back above it |
high_next | forecast | Will it make a new 20-day high in the next week? A new 20-day high next week |
Answers
| Question | Answer | Reading |
|---|---|---|
price20-day closing breakout | 0.6462 | true |
volumeVolume more than twice the previous 20-day average | 0.0537 | false |
failedUndercut the 20-day low and closed back above it | 0.0537 | false |
high_nextA new 20-day high next week | 0.865 | 87% · likely |
Actions
Rules on the answers decide what to send.
price >= 0.6 and volume >= 0.6→Slackclass-channelprice >= 0.6→Slackclass-channel{
"text": "XLE (2026-10-30): price broke out without volume (5%). Discuss: is this a fakeout?"
}What it means
For XLE on the session of 2026-10-30: True now: 20-day closing breakout. Not true: Volume more than twice the previous 20-day average; Undercut the 20-day low and closed back above it. Forecasts: A new 20-day high next week 87%. Fired: fake (Slack → class-channel).
A breakout with volume is the textbook case; price without volume is the fakeout students learn to be careful with.
Request JSON
{
"model": "ora-fin-0.1.1",
"state": {
"symbol": "XLE"
},
"questions": {
"price": {
"type": "yes_no",
"ask": "C > highest(C, 20)"
},
"volume": {
"type": "yes_no",
"ask": "V > 2 * ref(avg(V, 20), -1)"
},
"failed": {
"type": "yes_no",
"ask": "L < lowest(L, 20) and C > lowest(L, 20)"
},
"high_next": {
"type": "yes_no",
"instructions": "Will it make a new 20-day high in the next week?"
}
},
"actions": [
{
"id": "real",
"when": "price >= 0.6 and volume >= 0.6",
"do": "slack",
"connection": "class-channel",
"message": "{{symbol}} ({{as_of}}): textbook breakout, price and volume agree. New 20-day high next week {{high_next|pct}}."
},
{
"id": "fake",
"when": "price >= 0.6",
"do": "slack",
"connection": "class-channel",
"message": "{{symbol}} ({{as_of}}): price broke out without volume ({{volume|pct}}). Discuss: is this a fakeout?"
}
],
"dry_run": true
}Response JSON (XLE, real)
{
"model": "ora-fin-0.1.1",
"answers": {
"price": {
"yes_no": 0.6462,
"rule": "C > highest(C, 20)",
"basis": "rule"
},
"volume": {
"yes_no": 0.0537,
"rule": "V > 2 * ref(avg(V, 20), -1)",
"basis": "rule"
},
"failed": {
"yes_no": 0.0537,
"rule": "L < lowest(L, 20) and C > lowest(L, 20)",
"basis": "rule"
},
"high_next": {
"yes_no": 0.865
}
},
"context": {
"symbol": "XLE",
"as_of": "2026-10-30"
},
"actions": [
{
"id": "real",
"fired": false,
"status": "skipped"
},
{
"id": "fake",
"fired": true,
"status": "dry_run",
"do": "slack",
"connection": "class-channel",
"preview": {
"text": "XLE (2026-10-30): price broke out without volume (5%). Discuss: is this a fakeout?"
}
}
]
}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, Algo / bot developer, Data vendor / platform.