The options wheel, automated — and safety-gated.

A Rust terminal & desktop assistant that runs the wheel strategy and short-dated index structures on Interactive Brokers. It ranks the trades, you approve them. Paper-first. Nothing transmits without a three-step gate.

Download Read the source

Rust Interactive Brokers · ibapi Paper-first AGPL-3.0

What it does

BetterWheel connects to IB Gateway / TWS, reconciles your live positions into wheel state, and ranks suggestions over live option chains: which put to sell, which covered call to write, when to take profit or roll. You always see a what-if preview and explicitly arm before anything is sent. Offline, it falls back to consistent demo data so it's always usable.

Terminal UI

A ratatui app with a Suggestions tab and a 0DTE tab. Pure render over app state; key-driven. The original and primary front-end.

Desktop app

A native Tauri dashboard with inline payoff charts and auto-update. Same guardrailed core, a point-and-click face. Windows & macOS.

Strategy 1 — the wheel

Sell a cash-secured put for premium. If assigned, you own the stock at a discount; write covered calls against it for income until it's called away. Then repeat. BetterWheel automates the selection at every leg and ranks management before new entries, then by annualized yield.

1

Cash-secured put

The entry. Sell an OTM put, collect premium, stand ready to buy the shares at the strike.

2

Covered call

Post-assignment income. Write calls against the assigned lot above your cost basis.

3

Manage

Take-profit and roll. Close winners early; roll threatened legs to keep the wheel turning.

Selling the put

BetterWheel scans each watchlist name's option chain for out-of-the-money puts, filters by moneyness — by delta, or a Black-Scholes delta rebuilt from implied volatility when IBKR reports no greek — and ranks every candidate by annualized return on the cash you'd post as collateral. You take the premium up front; above the strike the put expires worthless and you keep it, below it you're assigned the shares at a price you already chose.

Writing the call

Holding an assigned lot, the covered_call selector looks for a call to write above your cost basis, so being called away still books a gain while the premium keeps lowering that basis. BetterWheel tracks the basis and the running premium itself — IBKR can't tell you which leg of the wheel a position is on.

Managing what's open

Trades aren't fire-and-forget. The manage selector proposes take-profit closes — buying a short back cheap once most of its premium has decayed — and rolls, closing a threatened leg and reopening it further out in time or strike to keep the wheel turning instead of taking a bad assignment.

What's ranked first

Every connected reload yields one ranked list, and plan() sorts management before new entries — tending what you already hold beats opening fresh risk — then by annualized yield. You act from the top; nothing fires on its own.

strike max profit = premium assigned below
Cash-secured put — premium is capped; downside is owning the shares at the strike.

Under the hood

The strategy is a pure, broker-agnostic engine/: three selectors — csp (entry), covered_call (post-assignment income) and manage (take-profit / roll) — over plain types, with zero I/O and exhaustive unit tests. A separate reconciler folds your raw IBKR holdings into wheel state (which symbol sits at which leg, the share lot, the open short), and a local SQLite store keeps what the broker doesn't: cost basis, cumulative premium, pending rolls.

Strategy 2 — 0DTE index structures

A second, separate strategy family: short-dated, defined-risk structures on cash-settled index options (SPX/SPXW). No assignment, no shares — multi-leg combos that live and die intraday. A generic piecewise-linear payoff engine derives risk, reward and breakevens for any leg set. Surfaced on a dedicated 0DTE tab.

Iron condor
Put credit spread
Call credit spread
Broken-wing fly
Iron fly
Short strangle · gated
Iron condor
Sell an out-of-the-money put spread and call spread together; keep both credits as long as price stays between the short strikes. Defined risk on each wing.
Put / call credit spread
The one-sided version — sell a single spread on the side you don't expect price to reach. Max profit is the credit; max loss is the width less the credit.
Broken-wing fly
A butterfly with unequal wings that skews the risk to one side, often opened for a credit so the other side carries little or no loss.
Iron fly
A short straddle wrapped in long wings: a fatter credit than a condor in exchange for a narrow profit zone centred on the strike.
Short strangle · gated
A naked short put and call — the only undefined-risk structure here, so it sits behind an extra gate.
max profit = net credit put wing call wing
Iron condor — collect the credit while price stays between the short strikes; the wings are the stop.

Under the hood

Each structure is a pure selector over a both-sides chain that emits a single OpenStructure { kind, legs } action, and one generic piecewise-linear payoff enginepayoff_at, max_loss_per_share, breakevens — derives the risk, reward and breakevens for any leg set (that's what draws every payoff curve). Because SPX/SPXW are cash-settled and European, there's no assignment and no shares: these live entirely outside the wheel's state machine and go to market as one guaranteed combo order, priced to IB's $0.05 index tick.

Hands-off — only if you ask

Any 0DTE slot can be set to automate: a 30-second scheduler enters at your configured time and places a standing profit-close on fill — the long wings are the stop, so there's no separate stop order. It's off by default, per slot, still bound by every guardrail, and a loud ⚡ AUTO-TRADING banner shows whenever a slot is live.

Talking to Interactive Brokers

BetterWheel has no brokerage of its own — it drives your Interactive Brokers account through IB's local API. You keep IB Gateway (or TWS) running; BetterWheel connects to it over a socket with the ibapi Rust crate, reads your positions and the live option chains, and routes every order back through it. Nothing of yours goes anywhere but to IB.

What IB Gateway is

A small, headless companion app from Interactive Brokers that holds your authenticated session and exposes the trading API on a local port — the lightweight alternative to the full Trader Workstation (same API, no charts). BetterWheel talks to whichever one you have open.

Paper first, live on purpose

It defaults to the paper port and only goes live when you deliberately switch. Reconnect, timeouts and guardrails behave identically either way — paper is just a different port and a different account.

The gotcha worth knowing up front

Connecting isn't the same as getting prices. Even on a paper account, IB returns no option quotes or greeks — so the Suggestions tab stays empty — until you finish the market-data setup in the IBKR client portal: the Market Data API access configuration, the Non-Commercial Form, your subscriber status, and an actual options subscription (OPRA for US options). The app connects fine without it; it just can't rank anything until the data flows. Offline demo mode is unaffected.

Under the hood

All of IB sits behind a single boundary: one module owns the ibapi client and maps its types into plain structs, every streaming request is bounded by a timeout, and one submit_or_preview entry point keeps the what-if and live order paths from ever diverging. An incomplete snapshot is treated as unknown, never as "your account is empty," so a dropped connection can't wipe your wheel state — and if the Gateway isn't reachable within five seconds at startup, the app falls back to Black-Scholes-consistent demo data so it's always usable.

Safety model

It is designed so a bug, a typo, or a bad fill can't quietly cost you money.

Paper-first

Defaults to the paper account (port 4002). Live trading is a deliberate switch, not the default.

Three-step transmit gate

Preview (what-if) → arm → execute. A successful live submit auto-disarms immediately.

Guardrails

read_only blocks all transmits; caps on per-order size and total deployed collateral are enforced regardless of what the engine suggests.

0DTE automation is opt-in

Auto-management is off by default, per slot, and still honors every guardrail. A loud banner shows whenever a slot is live.

Get BetterWheel

Free and open source under the AGPL-3.0. Paper-trade it first, read every line if you like, and arm nothing you don't understand.