Guides / Cookbooks
Cookbooks · Risk and execution · Intermediate · about 8 min
Size positions by volatility regime
Use ATR and realized-volatility rules to place each symbol in a calm, normal or high regime, and scale position size to match.
When to use it
The same dollar size is a very different risk in an index ETF and in a high-beta chip stock. Rules that measure the current regime give a size multiplier before any forecast is involved.
The request
atr_pct(14)is the 14-day average true range as a percentage of the close.hv_highis asked in English; the engine compiles it to a realized-volatility rule.{ "model": "ora-fin1", "state": { "symbol": "NVDA" }, "questions": { "atr_high": { "type": "yes_no", "ask": "atr_pct(14) > 3" }, "atr_mid": { "type": "yes_no", "ask": "atr_pct(14) > 1.5" }, "hv_high": { "type": "yes_no", "instructions": "Is its 20-day historical volatility above 40%?" }, "drop5": { "type": "yes_no", "instructions": "Will it drop at least 5% at some point in the next month?" } } }Open this in the PlaygroundThe real response
NVDA:
{ "model": "ora-fin1", "answers": { "atr_high": { "type": "yes_no", "yes_no": 0.5548, "rule": "atr_pct(14) > 3", "basis": "rule" }, "atr_mid": { "type": "yes_no", "yes_no": 0.9463, "rule": "atr_pct(14) > 1.5", "basis": "rule" }, "hv_high": { "type": "yes_no", "yes_no": 0.1582, "rule": "std(log(C / C[-1]), 20) * sqrt(20 / 19) * sqrt(252) > 0.4", "basis": "pattern" }, "drop5": { "type": "yes_no", "yes_no": 0.523 } }, "usage": { "input_tokens": 395, "output_tokens": 16 }, "context": { "source": "server", "symbol": "NVDA", "as_of": "2026-10-30" }, "version": "ora-fin-0.1.1" }The English question became
std(log(C / C[-1]), 20) * sqrt(20 / 19) * sqrt(252) > 0.4(annualized 20-day volatility over 40%). Across three symbols:Symbol atr_pct(14) > 1.5 atr_pct(14) > 3 20-day HV > 40% Multiplier SPY0.0537 0.0537 0.0537 1× NVDA0.9463 0.5548 0.1582 0.75× AMD0.9463 0.9441 0.938 0.5× NVDA's
atr_highof 0.5548 is just past the 3% line: ATR is a touch above 3%, not far above it. A belief that close to 0.5 is the engine saying "borderline".The code
Requires curl 7.76+. Save as run.sh, then: bash run.shcurl -sS https://oramodel.com/v1/systemone \ -H "Authorization: Bearer $JEV_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "ora-fin1", "state": { "symbol": "NVDA" }, "questions": { "atr_high": { "type": "yes_no", "ask": "atr_pct(14) > 3" }, "atr_mid": { "type": "yes_no", "ask": "atr_pct(14) > 1.5" }, "hv_high": { "type": "yes_no", "instructions": "Is its 20-day historical volatility above 40%?" }, "drop5": { "type": "yes_no", "instructions": "Will it drop at least 5% at some point in the next month?" } } }'The multiplier in the table comes from this function:
def size_multiplier(a): if a["atr_high"] >= 0.6 or a["hv_high"] >= 0.6: return 0.5 # high regime if a["atr_mid"] >= 0.6: return 0.75 # normal to busy return 1.0 # calm a = {k: v["yes_no"] for k, v in data["answers"].items()} shares = int(base_shares * size_multiplier(a))Act on it
Apply the multiplier before the order is built, and log the regime with the trade. Re-check after each close: regimes change faster than most position-sizing tables are updated.
Variations
- Volatility targeting: size so that
shares × ATRis a fixed dollar amount (read ATR from your own data and use the rule only as the regime label). - Use the beliefs smoothly instead of steps: multiplier = 1 − 0.5 ×
atr_high. - Add
drop5to cut size further when the drawdown odds are high (Risk guardrail before an order).
- Volatility targeting: size so that
Information, not investment advice. Every number on this page is a real response for the session shown; answers change with each session.