The bankroll

Risk in options

A deployer picks an underlying, calls or puts, and one risk number. That number decides how far from the money the vault sits and how long its contracts have to run. This page is the whole mapping, in one table, and what each band actually buys.

Why options are different#

Policy.risk carries one meaning in the program: the share of the vault's equity that may be deployed to venues at once. For a perpetual that is a clean statement, because a perp position can be closed at roughly what it is marked at, so deployed and at risk are different quantities.

For a long option, deployed and at risk are the same number

Premium paid is the maximum loss. So for options, risk is not a sizing dial. It is the answer to "how much of this vault may be permanently destroyed". A deployment to a perps venue that goes badly leaves something behind; a long option that expires out of the money leaves nothing.

PerpetualLong option
Deployed capitalmargin postedpremium paid
Maximum lossbounded by liquidation, not by the deploymentexactly the premium
What risk governshow large a position may behow much may be written off
Loses when nothing happensno, aside from fundingyes, every day, through theta

The slider is nearly inert for long options#

Two constraints squeeze it from both sides.

  1. Config.min_risk_for_class[OPTION] is 80, so an options venue account cannot be registered below risk 80 at all. The expressible range is 80 to 100, not 0 to 100.
  2. Bound C below caps long premium at risk at max_deviation_bps / 10000 of equity, which is 20% on the current configuration. 20% is lower than 80, so 20% binds.

Moving the slider between 80 and 100 changes nothing

The binding constraint on a long-option policy is 20% of equity per deployment, from the deviation rail, and it does not move when the slider does. risk gates whether options can be traded, and then stops governing exposure.

This is recorded in the design notes as a design smell rather than a feature. The cleaner fix is separating "may this policy trade options at all" from "how much may it deploy", which today are the same number. That would be a program change and is not proposed.

So something else has to express how much risk the deployer is actually taking, and that something is which contract gets bought.

Moneyness is the real risk dial#

Three choices determine risk when buying contracts, in descending order of how much they matter:

#ChoiceWhy it mattersExpressed today?
1MoneynessA 0.85-delta call behaves nearly like the underlying and rarely expires worthless. A 0.20-delta call is mostly a lottery ticket. Same underlying, same expiry, same dollar at risk, completely different distribution of outcomes.No. This is the gap.
2TenorInside about a week, theta and gamma dominate and the position stops tracking the underlying, which defeats the point of a deterministic policy.No. This is the gap.
3SizeHow much premium goes in.Yes, by risk and bound C.

Risk picks the contract#

The deployer chooses two things at launch: the underlying, and whether the vault is long calls or puts. Both ride on chain. Everything else about the contract, how far from the money it sits and how long it has to run, is derived from the risk number the deployer already set. There is no strike control and no expiry control, because a launch happens once and a strike chosen once goes stale within weeks while the page is live forever.

So the mandate is stored as a relationship, not a contract, and is re-resolved against Derive's live instrument list on every read. The same function that tells a deployer what their risk setting means is the one the token page calls to display it, imported rather than copied, so the promise made at launch and the contract shown afterwards cannot drift apart.

RiskDistance from the moneyTenorWhat the deployer is choosing
0 to 1915% in the moneyQuarterlyMostly intrinsic value. Tracks the underlying most closely, decays slowest, least exposure per dollar of premium.
20 to 395% in the moneyQuarterlyStill mostly intrinsic, with more room to move.
40 to 59At the moneyMonthlyThe most sensitive to being right about direction and timing together.
60 to 795% out of the moneyMonthlyAll extrinsic. Needs a move to be worth anything.
80 to 9410% out of the moneyWeeklyCheap per contract, and decaying fast.
95 to 10025% out of the moneyWeeklyMost exposure per dollar, and most likely to be worth nothing at expiry.

Bands cover 0 to 100 exactly once and are monotonic on both axes. The reader snaps to the nearest listed strike and reports its real distance from Derive's live index, so what is shown is the contract that exists rather than the one the table describes.

Why the steps are uneven

The distances step -15, -5, 0, +5, +10, +25, which is deliberately not a straight line. Near the money five points is a large change in delta and in premium; far out of the money it is barely distinguishable. The top band jumps to 25% so that it buys a genuinely different instrument rather than a rounding error away from the band below it.

The band table is ours, not the chain's

The chain holds the underlying, the call-or-put choice and the risk number. Turning that number into a strike and an expiry is our code. If the table is edited, every existing policy's stated mandate changes with it. That is a real difference from the fields above it, and the interface says so rather than letting the whole mandate look equally on-chain.

target_leverage_x means nothing here

It is written as 1 on an options policy and read by nothing. Leverage in an option comes from its moneyness, not from a multiplier, so there is no honest number to put in that field. The review screen shows it as 1x (options carry no leverage dial) rather than hiding a field the policy really carries, because hiding one is a worse kind of quiet than showing one that does nothing.

The target leverage field is reused in options mode to select moneyness. Setting one targets a delta of 0.75 to 0.90, deep in the money, which tracks the underlying most closely and rarely expires worthless. Two targets 0.60 to 0.75, in the money. Three targets 0.45 to 0.60, near the money and most sensitive to timing. Four targets 0.30 to 0.45, out of the money. Five targets 0.15 to 0.30, far out of the money, which gives the most exposure per dollar and is usually worth nothing at expiry. Below, the mechanism: bound A caps delta-adjusted notional at five times equity and never moves, so the same delta budget buys roughly four times as many contracts at 0.20 delta as at 0.80 delta. That is where an option's leverage comes from.TARGET_LEVERAGE_X, IN OPTIONS MODE10.75 to 0.90deep in the money, tracks the underlying20.60 to 0.75in the money30.45 to 0.60near the money, most sensitive to timing40.30 to 0.45out of the money50.15 to 0.30far out, usually worth nothing at expirytracks the underlyingmost exposure per dollarWHY MONEYNESS IS THE RISK DIALBound A caps delta-adjusted notional at 5x equityand it never movesAt 0.80 deltafew contracts fill the budgetAt 0.20 deltaroughly four times as many

The deployer is not turning the leverage cap up. They are choosing a payoff shape inside a cap that never moves. The shapes and counts here are illustrative, not priced.

The tenor rule#

nearest listed expiry inside the band the risk number selects

The three tenor bands are contiguous and do not overlap, so "nearest listed expiry inside the band" is unambiguous: weekly is 2 to 14 days, monthly 15 to 59, quarterly 60 to 180. Weekly starts at 2 days rather than 1 on purpose, because Derive also lists daily expiries and "nearest weekly" quietly resolving to tomorrow would be a surprise rather than a choice. A band with nothing listed in it falls back to the nearest overall, and the reader says so rather than pretending it matched.

The five bounds#

These generalise the 5x perp cap to options. The generalisation is exact rather than analogous: 5x expresses first-order sensitivity, and delta is the first derivative, so sum(delta * index) is precisely the notional word that report_remote_equity already checks against 5 * equity.

BoundStatementWhat it stops
Aabs(sum(delta * index)) <= 5 * equityThe same 5x the perp slider sets. This is the on-chain notional check in report_remote_equity; nothing new is needed to enforce it.
BA again after a plus or minus 20% shock, with delta re-estimated from gammaA perp's delta is constant. An option's is not, so a position inside A today can breach it on a move.
Clong premium at risk <= max_deviation_bps / 10000 * equityA long option loses when nothing happens. Without C a single expiry could move reported equity further than the deviation rail tolerates, pausing the policy on a fully predictable outcome.
DNo naked short legsUnbounded loss. Derive will not enforce this for us: shorting "changes your margin requirement, not what you can hold".
Emargin requirement <= 1/5 of equityThe same statement as A, through the margin engine. Derive reports margin net, so the requirement is subaccount_value - maintenance_margin.

The 20% in C is Config.max_deviation_bps = 2000, read from the live config, not an invented figure.

Only bound A is enforced on chain

A is the existing notional check. B through E cannot be checked by the program, because a Solana program cannot see greeks or a remote margin engine. They are enforced by the keeper, which means they are a policy of the off-chain runner and not a property of the chain. See the safety model.

Where the leverage actually comes from#

Bound A caps delta-adjusted notional, and this is the mechanism worth understanding.

delta budget = 5 * equity          (bound A, constant)

at 0.80 delta ──▶ N contracts fit inside the budget
at 0.20 delta ──▶ roughly 4N contracts fit inside the same budget

Buying 0.20-delta contracts means roughly four times as many contracts as 0.80-delta for the same delta budget. That is precisely where an option's leverage comes from, and it is why moneyness is the real risk dial while A stays constant at 5x. The deployer is not turning the leverage cap up; they are choosing a payoff shape inside a cap that never moves.

What "high risk" concretely means#

Two configurations, at the ends of what the dial can express. Neither is a recommendation.

risk 100, target_leverage_x 5

The vault repeatedly buys far out of the money contracts, each with roughly a 20 to 30 percent chance of finishing with any value at all, spending up to 20% of equity per deployment. Each individual purchase is capped, so no single trade ruins the vault.

Repetition is the risk. Absent a large move in the chosen direction, that configuration converges to zero, and it does so quietly, one expiry at a time.

risk 80, target_leverage_x 1

Deep in the money contracts that track the underlying, where the premium at risk is mostly intrinsic value rather than time value. The closest an options policy gets to simply holding the asset.

Minimum sizes and fees#

Both matter for a vault small enough that a deployment is a handful of contracts. Verified live from each venue's public API, with no authentication.

VenueMinimumStepFee floor
Derive, ETH optionsminimum_amount 0.1amount_step 0.01a flat base_fee of 0.5 USD per trade
Hyperliquid$10 minimum order valuen/an/a

Very small positions are disproportionately expensive

Derive's base_fee is flat per trade, so it is a fixed cost that does not shrink with the order. A vault deploying small amounts pays it on every entry and every exit.

Hyperliquid's $10 minimum is quoted from its own API documentation. It is notional, so leverage counts toward it, and it is per order, not per position, so a position built or unwound in slices has to clear it every time.

The data behind the contract choice is all public: get_ticker returns delta, gamma, vega, theta, iv and mark_price per contract, and get_instruments returns strike, expiry, option_type, minimum_amount and amount_step. So the keeper's contract selection is reproducible by anyone, from data they can fetch themselves.

Where the numbers come from#

Chosen, not fitted

The six bands and the three tenor windows are a design choice. They are monotonic, they cover the range exactly once, and the uneven steps are reasoned about above, but they are not fitted to a backtest and nobody should read them as though they were. They are a mapping from one number a deployer understands to a contract that exists, and their virtue is that the same mapping is applied everywhere, is readable in one table, and can be argued with.

Calls and puts are handled by the same table. The distance is stored without a sign relative to the money, and which side of the index that lands on is applied when the contract is resolved: out of the money is above the index for a call and below it for a put. One table, mirrored, rather than two that can disagree.

And the reason none of this is running yet#

Every rule on this page is a rule for a position that does not exist. No Stags options vault has been created, and one cannot be created today: Derive's private/set_session_key answers [-32603] Internal error (null) for every valid payload, and public/register_deposit_address, which is the only thing that creates a subaccount, answers HTTP 503. Both are write paths on Derive's own service, and their read endpoints answer normally at the same moment.

When it does run, the key model is the right one. Derive v3 session keys carry real protocol_scopes, and a key scoped to options trading was refused withdraw and every transfer put to it, against a control that proved the route was live. This site previously said v3 had no options book at all; that was our own measurement bug and is corrected on venues.

What still holds is the Solana half. The program has no instruction that pays an address the agent chooses, so the bankroll only ever reaches a venue account the authority registered in advance. The split is set out on the safety model, and the venue detail is on venues.