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.
What the market says it is worth. Zero expected value, as arbitrage requires - which is why scoring this way ranks every candidate identically.
What it is worth if the underlying keeps moving the way it actually has been. Jump-robust, so one earnings gap cannot masquerade as a regime.
The dollar gap between those two numbers is the variance risk premium - and it is the only reason to put the trade on.
A high win rate is not an edge. It is a way to lose money slowly and feel good about it. Anything with non-positive expectancy under the physical measure is refused - however high its probability of profit.
Defined-risk structures only. Every short leg sits inside a long of the same right, so the worst case is a property of the geometry rather than a promise - and the wing is what makes the maximum loss knowable before the order is sent.
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.
What is the market doing?
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 to trade at all.
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.
risk_gate.py imports nothing but the standard library. Given the same proposal and the same book it returns the same verdict, forever.
This sends a genuinely hostile order to the gate running right now: a 10-lot naked NVDA call carrying $15,000 of undefined downside. Nothing is routed and no state changes.
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, so the universe is selected for depth of option chain rather than for interesting stories.
Roughly half of every scan ends in a documented refusal to trade. That is the desk working, not the desk idle.
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