An options-trading agent that cares about one number: the cash it can actually walk away with at a fixed deadline.
Most trading bots quote you a P&L marked at the bid-ask midpoint. On a spread-y options book that number is fiction — the moment you try to close, you cross the spread and collect less. MARKGAP keeps two books side by side: the mid-mark everyone shows, and the liquidation value you could really settle at right now. The distance between them is the markgap, and the whole agent is built around shrinking it to zero before its clock runs out.
It trades a real Alpaca paper account, on its own, and writes down every decision — including the trades it refuses to make.
- It optimizes realized cash at a deadline, not expected return. A clock state machine winds the risk budget down as the terminal timestamp approaches and forces the book flat before it. A position still open at the horizon is treated as a bug.
- Defined risk, always. Every structure has a known maximum loss computed before the order goes in. It prices its own exit before it enters — if it can't, it doesn't trade.
- The model is on a short leash. An open-weight LLM (via Featherless) does two things: hand back a risk-budget multiplier between 0 and 1, and write plain-English notes into the journal. It never picks a strike, sizes a position, or sends an order. The arithmetic is all deterministic and all tested.
A credit spread only pays if you're in the right regime. Before it sells, four independent checks have to line up — each one added because an earlier version lost money without it:
- Variance risk premium — only sell when implied vol is richer than realized. If you're not paid to carry vol, you don't.
- Dealer gamma — computed from open interest and the agent's own gamma. When dealers are short gamma the tape trends and runs over short premium, so it stands down.
- Trend agreement — the 20-day and 5-day trends have to point the same way, or it sits out the chop.
- News — recent headlines feed the model's risk read; a geopolitical or macro shock pulls the budget down.
When they don't agree, it refuses and records why. A refusal is an output, not a failure.
You need Python 3.10+ and Alpaca paper API keys.
python -m venv .venv && . .venv/Scripts/activate # or .venv/bin/activate on macOS/Linux
pip install -r requirements.txt
cp .env.example .env # then paste your Alpaca paper keysThen, using the built-in task runner:
python run.py preflight # check the account, balance, options level, and data feeds
python run.py test # the arithmetic test suite
python run.py dry # build candidates and run the gates — no orders sent
python run.py smoke # open and close one real spread end-to-end (needs market open)
python run.py once # one full agent tick against the paper account
python run.py session # run the loop
python run.py dash # serve the dashboard at localhost:8000
python run.py flatten # force the whole book flat right nowpreflight, test, and dry are safe to run anytime and don't place orders.
src/markgap/
clock.py the deadline state machine and risk-budget schedule
greeks.py Black-Scholes and an IV solver — the agent computes its own Greeks
marks.py the dual book: mid, liquidation, and the gap between them
signals.py dealer gamma exposure from open interest
candidates.py turns a chain into a gated, sized, ready-to-trade proposal
gates.py twelve pre-trade checks, each returning a named pass or refusal
sizing.py Kelly per structure under a quarter-Kelly cap
execution.py multi-leg orders, the net-price sign convention, safe exits
registry.py reconstructs whole structures from Alpaca's per-leg positions
regime.py the deterministic regime read and the model's two jobs
agent.py the loop that ties it together
journal.py a hash-chained, tamper-evident record of every decision
The engine is separated from the execution on purpose: the parts that do math are pure functions with tests, and the parts that talk to the network are thin.
Paper trading flatters you — no slippage, no size limits against the real book. The markgap is the correction, and MARKGAP puts it on screen instead of hiding it. When the first live book lost money, it took the small loss, found the regime that caused it, and shipped the filter that prevents the repeat. The number it reports is the number it can collect.