SD book

14. Going live: the runner, the feed, and trade.using.rs

I want to change a trading strategy · 4/5 I run the live tools · 1/2

4 min read

Backtests end with a table. Live trading starts with a question the backtest never had to answer: what does the option actually cost today? This chapter covers the three live pieces and how each one stays honest.

            Threadripper (systemd user timers, Mon–Fri after the close)
 ┌───────────────────────────────────────────────────────────────────────┐
 │ sd_live ──events──▶ scripts/sd_mail_runner.py ──SahastaMail──▶ inbox  │
 │ sd_feed ──feed.json──▶ scripts/sd_feed_upload.py ──HMAC──▶ trade.using.rs
 └───────────────────────────────────────────────────────────────────────┘

#Real option prices, every day

src/live.rs fetches three years of daily bars for the universe (cached per day in ~/.cache/sd-live/) and computes SD exactly as the backtests do, including the market-weather side. Then apply_real_iv:

  1. Fetches today's real option chains from Yahoo: the at-the-money straddle at the expiry nearest 30 days and nearest 9 days, with bid, ask and implied volatility.
  2. Logs every quote to ~/.local/state/sd-live/iv_log.json.
  3. Replaces the backtest's IV proxy with the logged real IV on every day it has one.

So today's decision ("is SD's expected move ≥ 1.3× what options charge?") uses real prices. Replays of past days use the same logged prices, so they agree with what was decided then. Over time, the log becomes the real-price evidence that chapter 11's proxy caveat is waiting for.

Why replay at all? sd_live rebuilds its book every day from the anchor date (its first run), using market data and the IV log. Nothing about positions is stored except which events were already announced. A crashed run or a lost state file can't leave the book in a wrong state; the next run recomputes it.

#sd_live: the runner's brain

sd_live --state ~/.local/state/sd-live/state.json --json   # new events since the last run
sd_live --positions                                         # what the model book holds now
sd_live --strategy monthly|weekly|both --account 100000 --risk 0.02

It trades CoilStraddle (via SdRouter) and WeeklyCoilStraddle, the strategies chapter 11 chose. Each event carries:

  • the legs and expiry
  • SD's vol edge
  • the real quote it was decided on
  • the most to pay per contract (the real ask)
  • suggested whole contracts for the given account and risk
  • for closes, the return on risk

#The email runner (SahastaMail)

scripts/sd_mail_runner.py runs sd_live and sends one email per open and per close from directionality@sahasta.com to me@sahasta.com. It uses SahastaMail's internal signed protocol (an HMAC-SHA256 over timestamp.body, with an idempotent delivery ID so a retry never duplicates). Events wait in an outbox until they are accepted, so an outage delays mail instead of losing it.

Units: scripts/systemd/sd-live-mail.{service,timer} (Mon–Fri 13:45 PT). Test it with sd_mail_runner.py --dry-run or --test-event.

#sd_feed and trade.using.rs

sd_feed --out feed.json [--backtests ../../reports/year] [--thatha-matrix …/global_sd_matrix.csv]
scripts/sd_feed_upload.py feed.json        # signed POST to https://trade.using.rs/api/feed

The feed (format v1) has:

  • strategies: each with kind, risk class, maximum loss type, typical horizon (horizon_days), and its walk-forward backtest at $5k, $25k, $100k and $1M (whole contracts, from scripts/sd_year_accounts.sh).
  • trades: what each strategy wants today:
    • status is new, open, closed_today, or target (for stock lists).
    • cost_per_unit is the real straddle ask × 100 for new straddles.
    • p_profit and expected_return come from the vol-edge buckets of chapter 11.
    • evidence_trades says how many past trades those numbers rest on.
  • stocks: SD, P(up), expected move, and entry and exit timing (chapter 13). Sources: the 125-name universe plus Thatha's global matrix (about 14,000 listings, market caps in USD).
  • thatha: the Thatha Stocks selections. Names, buckets, weights and rationale only; dollar amounts and account sizes are deliberately left out.
  • notes: the caveats, which the site shows on every page.

trade.using.rs (source: ~/Development/TradeUsingRs, one Cloudflare Worker + D1 + KV):

  • Accounts and subaccounts: each login can hold several accounts ("Trading", "Stock buying", "IRA"…), each with its own answers, blend, holdings and alerts.
  • Strategy blend: set from the answers. Account size and risk level set the per-trade loss limit; horizon picks few-day, monthly or long-term strategies; strategies with negative backtests are never blended in by default.
  • Trades: sized in whole contracts. A trade that can't be afforded is hidden, with the reason shown.
  • Stock pickers: Thatha-style selection rules, entry and exit points, and a broker CSV import for current holdings. The "sell" verdict is shown only as experimental, because chapter 13 found it backwards.
  • Thatha selections page: both portfolios.
  • Email alerts: opt-in per account. They are built and logged; delivery waits on the SahastaMail route (below).

Units: scripts/systemd/sd-feed.{service,timer} (Mon–Fri 14:00 PT).

#What is still pending

  • The SahastaMail change that lets directionality@sahasta.com send is written and tested in ~/Development/SahastaSite/mail-app but not yet deployed. Until then the runner's emails queue in its outbox.
  • SahastaMail's internal route delivers only to SahastaMail-hosted mailboxes. Emailing trade.using.rs users at other addresses needs a public sending path (using.rs already has Cloudflare Email Sending DNS records).