The Trdrbot Loop
An autonomous options-trading agent, explained from the top down — the loop, then each stage, then one real trade traced end to end, then every subsystem by name.
Start here: what this actually is
trdrbot is a program that wakes up every 60 seconds, looks at the market and the news, and occasionally decides to buy or sell an options position through a broker — on its own, with no human in the loop. It runs on a paper trading account: real market data, simulated money.
The one idea everything else follows from. Most trading bots score themselves on profit. Over a single week, profit is mostly luck — we measured it: an agent with a genuine skill edge only beats a coin flip about 69% of the time over 20 trades. So a bot that learns from profit alone will happily learn superstitions.
trdrbot instead separates two questions that profit blurs together: "was my view of the world right?" and "was the trade I built to express it right?" It scores those separately — and when it makes money on a view that turned out to be wrong, it deliberately learns nothing from it, and that trade is barred from earning it permission to bet bigger.
Everything below is machinery in service of that: three different ways of coming up with an idea, arithmetic that refuses to flatter a bad one, and a scoring loop that only counts evidence that actually teaches something.
The loop at a glance
Four stages run in a fixed order, over and over. The expensive thinking happens rarely; the cheap safety checks happen constantly.
↑ click any stage to open it — or press Tab, then Enter
Sense — look at the world
Collect information and compute every number that doesn't need judgement.
How it works
A sensor is a declared source of information — Alpaca's market data, Alpaca's news feed, Polymarket's prediction-market odds. Each declares how often it runs, how much to trust it, and how to filter what it finds. Everything they return lands in a single inbox as typed items. In parallel, pure-Python analytics recomputes the state of the book: current prices, per-position Greeks, and total portfolio exposure.
The actual subsystems
Think — form a plan and price it
Turn information into a falsifiable thesis, then into a specific, sized trade — or, very often, into a documented decision to do nothing.
Part 1 — three ways to have an idea
Three independent generators propose trade ideas. They exist separately because each is blind in a different way, and all three feed one shared inbox with one shared admission gate.
Part 2 — inside one decision
When the decide cycle runs, the AI's job is deliberately narrow: state a thesis, propose at least two genuinely different ways to trade it, and state an honest probability. Everything after that is arithmetic it doesn't get a vote on.
The actual subsystems
Act — place the order, then verify reality
Submit through Alpaca, then continuously check that what we think we own matches what the broker says we own.
How it works
Orders go through the Alpaca MCP server — one connection shared for a whole tick rather than reopened for every call. Every order carries an ID computed deterministically from the decision that caused it, so if the process crashes and retries, it resubmits the same order instead of accidentally opening a second position. Then, every single tick, the reconciler diffs the broker's actual holdings against trdrbot's own records.
verified by trdrbot/reconcile — the
position went from "we think we placed this" to "the broker agrees this exists."The actual subsystems
Learn — guard the position, then judge it honestly
Enforce the exits the agent promised, and afterwards work out what — if anything — the outcome actually taught.
Part 1 — the guard
When the agent opens a position it must also write its own exit conditions. A deterministic evaluator then checks them every 60 seconds — far faster than the AI runs — and closes the position when one triggers. Crucially, thesis-level stops watch the underlying stock price, not the option's own quoted price, which on a thin option can swing wildly for no real reason.
Part 2 — the scoring that makes profit honest
At the thesis's own stated deadline — not when the position closes — the system asks two separate questions, and the four possible answers are treated very differently.
The actual subsystems
Remember — four stores, four different questions
Deliberately not one database doing four jobs, because the four jobs have genuinely different rules.
| Alpaca | "What do I actually hold?" The broker is the only authority on this. Real-time, external, and always trusted over our own records. |
| Journal | "What happened, in order?" An append-only log, never edited. Every decision is written here before the order is placed, so a crash can always be reconstructed. |
| Wiki | "What's the story?" Human-readable pages: one per position with its full thesis, plus market context and accumulated lessons. |
| elfmem | "What do I know that matters right now?" Evolving memory whose confidence in each stored pattern moves with real outcomes. |
The actual subsystems
A worked example: one real trade, start to finish
This is an actual position the system opened on 28 August 2026 — real numbers, taken from its own records. Step through it to see all four stages do their job.
Something happens in the world
The news sensor picks up coverage of Fed Chair Warsh's Jackson Hole speech. Fed funds futures have flipped to price a September rate hike as more likely than a hold — roughly 60%. Gold, Bitcoin and long-dated Treasuries all sell off.
At the same moment, analytics records the market state — no AI involved, just arithmetic.
The agent forms a falsifiable claim
It notices a mismatch: everything else repriced for a hike, but SPY is only −0.3% after touching 775. Its view is that equities have barely discounted the news.
Note what makes this a thesis and not a hunch: it names a target range, a deadline, and — most importantly — the exact price that would prove it wrong.
Several ways to trade it, priced honestly
The agent must propose at least two genuinely different structures. Each is priced with trading costs charged up front, not after — because at this scale the cost of getting in and out is often the same size as the entire edge.
The winner is a bear put spread: buy the SPY 766 put, sell the 758 put, both expiring 3 September. Buying one and selling the other caps both the cost and the maximum possible loss.
How big? Not the agent's choice
The agent states its honest probability; the code decides the size. That probability is shrunk toward its measured track record — an agent that has not yet proven itself gets a fraction of what its confidence would otherwise justify.
The result is checked against three caps at once: this position, this underlying, and the whole book — all measured in dollars that can actually be lost.
Placed, then verified against the broker
The order goes out through Alpaca's MCP server at 17:34, tagged with an ID derived from the decision itself. The decision was written to the journal before the order was sent — so if the process died mid-flight, a restart would find the record and resume the same order rather than open a second one.
Seven minutes later, reconciliation confirms the broker really shows both legs.
Five rules now watch it, every 60 seconds
The agent wrote these itself at entry. From this point they run without it — no AI call needed to close a position that has gone wrong.
The thesis stop is the interesting one: it watches SPY itself, not the option's price. The agent said 776 would prove it wrong, so 776 is what gets watched.
On 3 September, two separate questions
At the thesis's own deadline — not when the trade closed — the system asks:
1. Was the view right? Did SPY actually land between 745 and 766? That's a yes/no about the world, and it's the question that moves the calibration score.
2. Was the structure right? Given what the market did, was a 766/758 put spread a good way to express it?
If it made money but SPY finished at 790, the answer is: this was luck. The system records that plainly, learns nothing from it, and that trade cannot count toward earning the right to trade bigger.
Every subsystem, by name
The concepts above map onto real modules. This is the whole system — roughly 45 modules, grouped by the stage they serve.
Sense — gather and compute
| sensors | The registry of information sources. Adding one is an entry, not new code. |
| polymarket | Prediction-market odds — crowd probabilities, free and unauthenticated. |
| news_extract | Turns raw headlines into dense structured signal with citations. |
| evidence | The shared "what do I look at first" gatherer used by all three thesis sources. |
| analytics | Portfolio state, per-position Greeks, beta-weighted book exposure. |
| market_stats | Technicals, realized volatility, and a bootstrap Monte Carlo from real history. |
| inbox | The file queue everything lands in — also the system's main testing seam. |
Think — decide
| research | Daily top-down cycle: regime → company dossiers → falsifiable opportunities. |
| discovery | The news nominates companies; a deterministic gauntlet filters before any write-up. |
| muse | Creative collision — unrelated concepts forced together, then adversarially gated. |
| opportunity | The single admission gate all three sources must pass through. |
| experiments | Thesis → candidate structures → ranked, comparable results. |
| optmath | Options maths, split hard into exact facts vs. modelled estimates. |
| sizing | Kelly on the conditional payoff, shrunk by measured calibration. |
| competence | The four-tier ladder: size is earned by resolved, explicable results. |
| local_tools | The three tools the agent actually calls: simulate, size, record. |
| llm | Model gateway with an ordered fallback chain across providers. |
| compact | Shrinks heavy tool results before they ever reach the model's context. |
| idle | What to do when nothing has happened — sleep, review, or hunt. |
| tick | The loop itself: what runs every 60s, what runs every 15 minutes. |
Act — execute
| mcp_client | One Alpaca MCP session per tick, not one per call. |
| tool_guard | Forces deterministic order IDs so a retry can't double a position. |
| reconcile | Broker truth vs. our records — and it runs first, every tick. |
| positions | Position pages and the status machine that guarantees one resolution. |
| lock | Single-flight tick lock, breakable if a previous run died. |
Learn — guard and score
| exit_rules | The agent's own commitments, executed every 60s against the underlying. |
| attribution | The view-vs-structure verdict, at the thesis horizon. |
| calibration | Brier score and Murphy decomposition on every stated probability. |
| ledger | Pre-registration: every thesis recorded, traded or not. |
| learn | Credit assignment — which memories and sources get reinforced. |
| coach | Paired A/B trials on its own prompts; promotes only on real evidence. |
| housekeeping | Runs while markets are closed: interim scoring, memory consolidation. |
| health | Asks of every subsystem: did it run and produce, or run and do nothing? |
| report | One self-contained HTML page: gauges over time with the Coach's actions marked. |
Remember — the substrate
| journal | Append-only event log; decisions written before orders are sent. |
| wiki | Position pages, market context and lessons, in a documented format. |
| elfmem_adapter | Evolving memory whose confidence moves with scored outcomes. |
| constitution | Ten epistemic principles — how to reason, remember, and change. |
| lessons | Measured lessons seeded into memory, each carrying its own numbers. |
| store | Atomic writes, so a crash mid-save can't corrupt a state file. |
Chassis — keeping it alive
| config | One place for models, watchlist, cadences and secrets. |
| cli | Every human-facing command: doctor, health, report, calibration, coach. |
| usage | Token and cost accounting across every provider and role. |
| failures | Classifies errors so a transient blip isn't treated like a permanent one. |
| ids | The provenance spine — one ID threading a position through every store. |
| prompts | Fingerprints every prompt, so decisions stay comparable across changes. |