Deflow trades defined-risk option spreads on Alpaca, harvesting the gap between the volatility options are priced at and the volatility stocks actually deliver. Four agents propose. Twelve deterministic circuit breakers decide. No model ever produces a number that reaches the broker.
Each of them is a structural property, not a tuning problem — so Deflow is built to make each one impossible rather than unlikely.
Most agents let a language model choose the strike, the width and the position size. A hallucinated number becomes an order. There is no layer that can say no, because the layer that would say no is the same one that made the decision.
Naked options and unhedged directional bets have no worst case. The position works for weeks and then one gap erases the account. Nothing in the system knows what the maximum loss is, because the structure does not have one.
A log tells you what a system says it did. It does not tell you whether the story was edited afterwards, and it usually records only the fills — so the refusals, which are most of what a risk system does, leave no trace at all.
Under the risk-neutral measure, every vertical spread is worth exactly what it costs. Score a candidate at its own implied volatility and every trade prices at zero — the correct answer, and a useless one.
So Deflow scores each candidate twice, and trades the difference.
| Measure | Volatility | What it tells you |
|---|---|---|
| risk-neutral | implied | What the market says it is worth — ≈ 0 EV, as arbitrage requires |
| physical | forecast realised | What it is worth if the stock keeps moving as it has been |
The dollar gap between those two rows is the variance risk premium. Anything with non-positive expectancy under the physical measure is refused — however high its win rate.
The reasoning layer is shown finished, priced candidates and returns exactly one integer index — bounds-checked. It cannot change a strike, a width, a premium or a size. A total model failure degrades to a deterministic ranker, not to a bad trade.
Measures implied against a jump-robust forecast of realised volatility on eight liquid names. Emits a stance, a directional bias — and about half the time, a documented refusal.
Delta-targeted strikes, a width ladder scaled to spot, a hard liquidity floor, and position size taken from the risk gate's own sizer. Wing geometry is correct by construction.
Re-derives every Greek from scratch rather than trusting the structurer, then runs 1,000 jump-diffusion paths under two volatility measures. Has fatal-objection authority.
Re-runs the entire risk gate on the exact proposal being sent, then submits a multi-leg order through Alpaca's official CLI with an idempotent client order id.
Between stages 2 and 3, Featherless AI picks one candidate from the list — or abstains. Its entire output surface is { index, confidence, rationale }. A model that hallucinates index 9999 is ignored, not indexed with.
Single-digit microseconds per evaluation — the button below reports the real figure from this machine. risk_gate.py imports nothing but the standard library. Given the same proposal and the same book it returns the same verdict, forever. It fails closed on anything malformed, runs all twelve even after one fails so the audit trail stays complete, and has no code path that can widen a limit or increase a size.
every short covered by a long of the same right
≤ 2% of equity per trade
|net delta| ≤ 0.35
65% win rate for credit; expectancy for debit
≤ 6% of equity at risk across the book
≤ 3% in any one underlying
book |delta| ≤ 1.20
≤ 6 concurrent structures
7–60 days to expiry
credit ≥ 15% of wing width
halts new risk at −3% on the session
|vega| ≤ 2.5 per $1,000 of equity
Every field is read with a pessimistic default. A missing max_loss is not zero, it is unbounded. NaN and infinity fail every comparison by design.
All twelve run even after one fails, because a veto naming only the first problem hides the rest from the audit trail.
max_contracts() derives position size from breakers 2, 5 and 6. The model never chooses size, and the gate can only shrink or refuse.
A defined-risk desk lives or dies on being able to exit. The universe is selected for depth of option chain, not for interesting stories — and roughly half of every scan ends in a documented refusal to trade.
Every decision — each analyst view, proposal, audit, gate verdict, order and exit — is appended as one line carrying the SHA-256 of the line before it. Edit or delete any historical entry and the chain breaks, and the API reports the exact index where.
Modify entry 3 of 6 and verification reports broken_at: 3. Delete one and it reports the same. A log tells you what a system says it did; this tells you whether the story was edited afterwards.
Stand-downs, abstentions and vetoes are logged with the numbers that produced them. A desk that records only its fills cannot be audited — and for this strategy, the refusals are most of the behaviour.
Appends take an exclusive file lock and re-derive the head underneath it, so two processes sharing a data directory chain onto each other instead of forking. Verified with four concurrent writers.
Written directly against the HTTP surface so the multi-leg payload is visible in one place: account, positions, daily bars, option-chain snapshots with NBBO and server-side Greeks.
Refuses to initialise against a non-paper endpoint.
The official Go binary is the interface an unattended agent actually gets deployed behind — its own 429/5xx backoff, its own credential resolution, and --dry-run to render the exact request without sending it.
Every order carries an idempotent client order id.
Alpaca's FastMCP server spoken as JSON-RPC over stdio with no SDK dependency, resolving tool names at runtime so an upstream rename cannot break the integration.
72 tools discovered; chains, contracts and account state.
Serverless open-model inference for the one stage that is allowed to be wrong. Qwen2.5-72B picks among finished candidates and explains the choice in English.
Any failure falls back to the deterministic ranker.
alpaca order submit --order-class mleg --qty 4 --type limit \
--limit-price -1.35 \
--legs '[{"symbol":"SPY261016P00540000","ratio_qty":"1",
"side":"sell","position_intent":"sell_to_open"},
{"symbol":"SPY261016P00535000","ratio_qty":"1",
"side":"buy","position_intent":"buy_to_open"}]'Negative limit price because Alpaca quotes multi-leg packages net — positive is a debit paid, negative is a credit received.
The desk streams every decision live — the regime read on eight names, the open book with Greeks, and a button that fires a naked call at the running risk gate.
One command from a bare clone — python main.py