NewWheel runs the options wheel strategy (sell cash-secured puts; if assigned, sell covered calls) against an Alpaca paper account, with a language model that can suggest trades but cannot place them. Each pass, Python snapshots the paper account, pulls the VIX and VIX3M closes from Cboe, scans a seven-name watchlist of put chains and keeps only the candidates inside the target delta band. That context goes to one Claude API call with a server-enforced JSON schema. Claude returns up to three proposals, each with a plain-English thesis. A pure-Python gatekeeper then runs 24 deterministic checks on every proposal (market open, DTE band, strike below spot, bid floor, spread, term structure, sizing, collateral caps, one entry per name per day, and more). Every check fails closed on missing data, and every verdict with every reason is written to a JSONL ledger. Only accepted proposals reach the executor, which sends orders through one chokepoint that re-verifies the paper endpoint, the kill switch and the dry-run flag before calling the Alpaca MCP server's trading process. Market data comes from a separate MCP process without the trading toolset; the model has no tools at all and never sees place_option_order. Built in Python 3.13 with alpaca-py, alpaca-mcp-server, the MCP Python client and the Claude API (claude-opus-5, structured outputs). Gates, executor, transport and the pass all have offline self-tests. To run: clone, make a venv from requirements.txt, put Alpaca paper keys and an Anthropic key in .env (see .env.example), then PROFILE=competition python agent_pass.py; add --offline-proposer to skip the model. Deliberately not done yet: every pass so far has run in dry-run, so the executor logged the orders it would have sent and sent nothing; no live paper order has gone through this loop. The earnings-date gate is built but disarmed for want of a data source. Covered calls after assignment exist in the wheel code but have not run through the agent pass.
Category tags: