SD book

5. Options strategies

I want to change a trading strategy · 2/5 I want to rerun the evidence · 5/5

6 min read

Options are the natural instrument for an indicator that knows how big but not which way. A straddle (one call plus one put at today's price) pays if price moves a lot in either direction. An iron condor pays if price stays inside a range. You can bet on size without betting on direction.

cargo run --release --bin sd_options                    # every strategy, every era
cargo run --release --bin sd_options -- --sweep         # choose thresholds on 2001-2018
cargo run --release --bin sd_options -- --noise 0.5     # SD sees noisy history
cargo run --release --bin sd_options -- --trades t.csv  # every trade, for a spreadsheet

#The abstraction

Everything a strategy decides is in one small trait (src/strategy/mod.rs):

pub trait Strategy: Send + Sync {
    fn name(&self) -> &'static str;
    fn thesis(&self) -> &'static str;                        // one paragraph: why
    fn enter(&self, ctx: &Context) -> Option<Plan>;          // flat: open what?
    fn exit(&self, ctx: &Context, open: &OpenView) -> bool;  // in a trade: close now?
}

Context is the SD reading, the spot price and implied volatility, all known at today's close. Plan is a list of legs (call/put, strike as a multiple of spot, bought or sold) and days to expiry. The simulator (sim.rs) does everything else: pricing, costs, marking to market, expiry, bookkeeping. A new idea is about 30 lines.

#Recipe: add a strategy

  1. Write a struct and impl Strategy for it in strategy/mod.rs. Put the why in thesis().
  2. Add it to catalog().
  3. If it has a threshold, add variants to sweep() in bin/sd_options.rs and pick the threshold from the n<2019 columns only.
  4. Run sd_options and compare it with its Always* baseline in every era.

#Pricing without option history

We have 25 years of stock prices but no historical option quotes, so options are repriced with Black-Scholes (pricing.rs). The input that decides everything is implied volatility (IV): the market's own estimate of how much the stock will move. We use, in order:

  1. Real Cboe indices for five underlyings: VIX (SPY), VXN (QQQ), VXD (DIA), GVZ (GLD), OVX (USO), daily since 2001–2008. ATM IV is taken as 0.88 × index (indices measure variance-swap levels, which sit above ATM because of skew), plus a linear put skew. Results tagged real.
  2. A proxy for everything else: ln IV = −0.094 + 0.391·ln RV₂₀ + 0.438·ln RV₁₂₆, fitted on those five against their indices (ρ = 0.94). Results tagged proxy.

The proxy's blind spot, stated plainly. Single-stock options price earnings announcements and other jumps. A proxy fitted to index ETFs cannot see them, so it makes single-stock options look cheaper than they really are. That flatters bought options (straddles) and punishes sold ones (condors). Treat proxy results as directional evidence, not as a P&L forecast.

Costs (sim.rs::Costs), per leg, per side: a half-spread of 2% of the option's price (4% for single stocks) with a floor proportional to the stock price, plus commission. Legs that expire worthless are not charged to close. Returns are on capital at risk: the debit paid, or a credit spread's widest wing minus its credit.

#The strategies, and why each exists

StrategyBets onEnters whenExits when
CoilStraddlea big move, either waytier ≥ 2 and SD's expected move ≥ 1.3 × implied move+60% on risk, ≤5 days left, or the fire has decayed below half strength
QuietCondora small moveno squeeze, no fire, intensity ≤ 0.35, implied ≥ 1/0.6 × SD's move50% of max profit, ≤5 days left, or a squeeze starts
FireVerticaldirection after a firejust fired, |lean| ≥ 0.3; short strike at SD's expected move80% of max, lean flips, decay < 0.5, ≤3 days left
SdRouterthe regime SD reportsthe straddle rule (condor optional, off)the rule of whatever it opened
Always*nothingwhenever flatsame profit/time exits

The Always* baselines are the most important rows in every table. SD earns its keep only if a strategy beats its own baseline.

#Results

Mean return on capital at risk per trade, after costs (reports/options_clean.txt).

Size bets: SD's filter turns a losing trade into a winning one.

2001–132014–182019–26
CoilStraddle, proxy IV (trades)+13.4% (229)+20.7% (40)+8.5% (162)
AlwaysStraddle, proxy IV−8.8%−8.0%−3.9%
AlwaysStraddle, real IV−9.6%−6.4%−3.9%

Buying straddles on a timer loses steadily: options charge a premium for movement, the variance risk premium. Buying them only when SD sees a deep coil whose expected move beats the implied move by 30% wins in every era. On the five real-IV ETFs, an edge that large almost never occurs (two trades in 25 years). So the real-IV evidence for this setting is thin, and the proxy's blind spot (above) means the proxy numbers are probably optimistic. Both are true at once.

How the 1.3 threshold was chosen (reports/options_sweep.txt): on 2001–2018 only, returns rise steadily with the required edge (−4.6% real / −3.9% proxy at 1.0, up to +4.2% / +11.8% at 1.3). Above 1.45 there are too few trades to trust. The 2019+ columns were read once, afterwards.

Calm bets: no edge after costs. The best pre-2019 QuietCondor setting earned +1.2% (real) / +0.7% (proxy) before 2019 and −0.5% / −3.4% after. That is not an edge. It stays in the catalog as a documented negative result, and SdRouter leaves it switched off.

Direction bets: SD's lean loses to "always bullish". FireVertical lost −8.4%, −10.5% and −2.4% per trade on real IV, while AlwaysBullCall made +1.1%, −1.7% and +6.0%. That is chapter 2's finding again, in dollars.

Under noise (reports/options_noise_*.txt, CoilStraddle 2019+ proxy): +8.5% clean, +10.5% at 0.25σ, +5.3% at 0.5σ, +0.1% at 1.0σ. The volatility guard (chapter 4) is what keeps it from going negative.

SdRouter, which today means CoilStraddle:

  1. Wait for a coil. SD v2 tier ≥ 2 (** or *** in Group C).
  2. Compare sizes. SD's expected 21-day move vs the implied move, IV × √(21/252) × √(2/π). Buy only if SD's is at least 1.3× larger. The ThinkScript label "Vol edge" shows this using the chart's live implied volatility, so use that, not the proxy, when trading.
  3. Buy the one-month at-the-money straddle.
  4. Take +60% when offered. Otherwise close once the fire has aged past half strength (about 2.5θ after it fired), or 5 trading days before expiry.
  5. Size small. Win rate is about 47–60%; the edge comes from the winners being bigger than the losers. Worst single trades lost about 60% of risk.

sd2 SYMBOL prints the vol edge and whether today is a setup.