Retired project: this paper-trading run ended April 2026
Simulated paper trading, not live results; not financial advice. No real money was traded.
Paper Trading Log: What Our Retired AI Trading Bot Actually Did
A simulated paper-trading run from February 26 to April 8, 2026 ended net negative. This page reports the numbers we could recover from the real ledger and guardrail logs, how we computed them, and where the records fall short.
The short version
- Both simulated books finished below their $10,000 starting balance: crypto $9,341.28 and Polymarket $9,467.27.
- The 821 closed trades we could recover and de-duplicate sum to −$443.11 in recorded P&L; 94 were winners (11.4%).
- The guardrails (critic vetoes, hard rules, fallbacks to hold) were active throughout, and they did not turn the strategies profitable.
- We stopped the project to focus on governed AI operations, and we do not present this run as evidence of an edge.
Why we retired it
Trading is a full-time discipline and the returns were uncertain. We decided our time was better spent on governed AI operations, where the work is scoped and the value can be checked, and where the infrastructure we built (decision logs, a critic layer, circuit breakers) carries over. The longer account is in Why We Retired the Trading Bot. This case study adds what the records show.
What the system was
This is a description of the code as it existed on our own machine, not a product we are selling. We do not publish the source.
- Data and signals. A data scraper collected market data on a roughly 60-second tick, and strategy modules (crypto and Polymarket) wrote trade signals to a shared log.
- Decision loop. An autopilot module ran in cycles (about 15 minutes by design), read recent signals, asked a language model for a structured decision (hold, trade, close, adjust risk, emergency exit), and logged every decision with hashes of the prompt and response.
- Provider routing and fallbacks. A routing module builds an ordered plan: a routine provider, a fallback provider, then an escalation provider reserved for open positions and emergencies. Responses that failed validation (invalid JSON, missing fields, unknown action, low explanation quality) or fell below a 0.45 confidence threshold were converted to a hold. If no provider answered, the cycle halted.
- Critic layer. A critic reviewed proposed trades and could agree, monitor, adjust, escalate, or veto. Deterministic hard rules (for example, four consecutive losses or a 5.0% drawdown) triggered without asking a model. A separate pre-trade critic rejected entries on conditions such as consecutive losses.
- Risk rules. Code-level defaults capped a position at 5% of balance and $500, ten open positions, 25% of balance at risk, a 5% daily loss limit, a 15% drawdown limit, and a consecutive-loss halt. Position size was set server-side and the model output was never trusted for sizing. A separate circuit-breaker module paused new entries on a 2.5% drawdown within 60 minutes, a loss streak, slow responses, or an error burst, while still allowing exits.
- Dry-run gate. Orders could not be sent while the dry-run flag was set, and the code only accepted an explicit false to clear it. Every log record that carries the flag shows it set.
Dry-run versus paper: what these words mean here
Dry-run describes the decision layer. Every one of the 5,468 log records that carries a dry-run field (3,805 decisions and 1,663 critic reviews) says dry-run was on, which means the autopilot logged what it would have done instead of sending an order to an exchange. The 3,476 pre-trade critic records and 3 injection events do not carry the field.
Paper describes the accounting layer. Trades in the ledger are simulated fills produced by a paper-trading module against local balances: a modeled 0.26% crypto taker fee, ±0.1% crypto slippage, ±0.5 cents of base slippage plus a depth penalty on Polymarket, and a 2% fee on Polymarket winnings. Polymarket orders were routed to this paper engine even while the decision layer was in dry-run. In the ledger, 740 of the 821 trade records carry an explicit paper-only flag; the other 81 (44 Polymarket, 37 crypto) carry no flag, and none is flagged otherwise. We found no record of a live order in these files, and we did not audit any exchange account.
The honest results
Period. The first recovered trade opened on February 26, 2026 (05:50 UTC) and the last recovered trade closed on April 8, 2026 (07:30 UTC). That is 42 calendar days, with trades closing on 36 of them. The ledger was last updated on April 8 at 07:52 UTC, and the decision log used here ends the same morning.
| Book | Start | Final balance | Change | Trades | Wins / losses | Recorded trade P&L | Fees |
|---|---|---|---|---|---|---|---|
| Crypto (paper) | $10,000.00 | $9,341.28 | −$658.72 (−6.59%) | 777 | 85 / 692 | −$455.35 | $292.28 |
| Polymarket (paper) | $10,000.00 | $9,467.27 | −$532.73 (−5.33%) | 44 | 9 / 33 (2 flat) | +$12.24 | $10.55 |
| Both books | $20,000.00 | $18,808.56 | −$1,191.44 (−5.96%) | 821 | 94 / 725 (2 flat) | −$443.11 | $302.83 |
The run is a net loss. By final balance both books lost money. By recorded trade P&L the crypto book lost $455.35, and only one measure is positive: the 44 retained Polymarket trade records sum to +$12.24. The measures do not reconcile, and we want to be plain about that. The Polymarket state also carries its own counters (18 wins, 73 losses, −$92.21), which describe 91 trades while only 44 trade records survive, and the crypto balance is $203.37 lower than the crypto trade records alone explain. We could not close those gaps from the files, so we report all of them rather than choose the kindest one.
- Win rate. 94 winners out of 821 trades (11.4%): 85 of 777 crypto (10.9%) and 9 of 44 Polymarket (20.5%).
- Size of wins and losses. Crypto: average win +$0.95 and average loss −$0.78, with gross wins of +$81.13 against gross losses of −$536.48. Polymarket: average win +$13.73 and average loss −$3.37, with gross wins of +$123.55 against gross losses of −$111.31.
- Best trade. +$74.53, a Polymarket momentum trade closed March 3. Best crypto trade: +$5.08, closed March 18.
- Worst trade. −$49.81, a Polymarket 5-minute binary trade on a sports spread market closed March 14. Worst crypto trade: −$11.12, closed April 1.
- Open positions. Two crypto positions were open at the last update and are not in these figures.
By week
| Week of | Closed trades | Winners | Losers | Recorded P&L |
|---|---|---|---|---|
| Feb 23 (Feb 26 – Mar 1) | 46 | 8 | 38 | −$55.46 |
| Mar 2 | 9 | 4 | 5 | +$84.12 |
| Mar 9 | 87 | 5 | 80 (2 flat) | −$85.78 |
| Mar 16 | 169 | 29 | 140 | −$74.75 |
| Mar 23 | 239 | 20 | 219 | −$125.25 |
| Mar 30 | 188 | 18 | 170 | −$144.18 |
| Apr 6 (Apr 6 – 8) | 83 | 10 | 73 | −$41.82 |
| Total | 821 | 94 | 725 (2 flat) | −$443.11 |
The only positive week (March 2: +$84.12) contains the single +$74.53 trade; without it the week is +$9.59. Every week from March 9 onward is negative.
By strategy
| Strategy | Trades | Winners | Recorded P&L |
|---|---|---|---|
| Two copycat-style templates (crypto) | 740 | 80 | −$405.72 |
| dca_ladder (crypto) | 27 | 3 | −$36.88 |
| minute_scalper (crypto) | 4 | 2 | +$2.96 |
| macd_cross (crypto) | 3 | 0 | −$7.03 |
| bollinger_bounce (crypto) | 3 | 0 | −$8.67 |
| pm_momentum (Polymarket) | 22 | 9 | +$69.80 |
| pm_market_maker (Polymarket) | 21 | 0 | −$7.75 |
| pm_binary_5min (Polymarket) | 1 | 0 | −$49.81 |
What the logs show about governance
The decision log holds 8,947 readable records between February 26 and April 8, 2026, of which 3,805 are model decisions spread over about 1,456 cycles. All figures below are from that file.
| Decision outcome | Records |
|---|---|
| Hold (decided hold, held) | 3,064 |
| Hold, queued for human review | 101 |
| Error, fell back to hold | 428 |
| Error, halted (all providers unreachable) | 13 |
| Trade decided, executed as a paper swap | 62 |
| Trade decided, held instead | 61 |
| Close | 56 |
| Risk adjustment taken (10 decided) | 9 |
| Emergency exit taken (3 decided, 1 queued) | 2 |
| Buy / sell decisions (6 / 1) | 7 |
| Total decision records | 3,805 |
| Guardrail activity | Records |
|---|---|
| Critic reviews logged | 1,663 |
| Verdict: escalate | 714 |
| Verdict: veto | 356 |
| Verdict: monitor | 355 |
| Verdict: agree | 238 |
| Hard-rule triggers (4+ consecutive losses: 119; 5.0% drawdown: 119) | 238 |
| Pre-trade critic records (all dated Feb 27 – 28) | 3,476 |
| Pre-trade critic: rejected / approved | 3,383 / 93 |
| Prompt-injection pattern detections | 3 |
| Decisions that fell back to hold on confidence below 0.45 | 599 |
Provider mix and reliability
| Provider label in log | Decision records | Errors | Error rate | Median latency |
|---|---|---|---|---|
| openclaw | 1,239 | 9 | 0.7% | 3.7 s |
| ollama (local) | 1,125 | 167 | 14.8% | 16.0 s |
| dashscope | 733 | 6 | 0.8% | 44.5 s |
| claude_code | 358 | 43 | 12.0% | 39.9 s |
| qwen_code | 134 | 0 | 0.0% | 8.6 s |
| none recorded | 216 | 216 | n/a | n/a |
Of the 441 error decisions, 103 were missing required fields, 62 were invalid JSON, 11 named an unknown action, 13 were all-providers-unreachable halts, and 252 carry no reason. The routing code has a provider failover plan, but the log has no counter for failovers, so we cannot report one.
What we take from it
- Frequent, small wins do not cover costs. With an average crypto win of $0.95 and loss of $0.78, breaking even needs roughly a 45% win rate. The observed rate was 10.9%. Crypto fees were $292.28, and if recorded P&L is net of fees, the crypto book was about $163 negative before costs.
- Model output is unreliable plumbing. 441 of 3,805 decision records (11.6%) were errors. Falling back to hold was a safe default, and it also meant roughly one decision in nine was an error.
- Reliability differed by provider. The local model and the CLI-based provider errored on 14.8% and 12.0% of records; two other providers were under 1%. The conditions were not controlled, but the gap is large enough to plan around.
- Guardrails limit damage; they do not create edge. The critic agreed with 238 of 1,663 reviews and the pre-trade critic rejected 97.3% of its records in a two-day window. The system was cautious and still lost money.
- Keep a ledger you can reconcile. Our balances, counters, and trade lists disagree, and some early trades are missing. That is why earlier posts on this site could not state results, and why this page leads with caveats.
Data sources and method
- trading_state.json (last updated 2026-04-08 07:52 UTC): balances, two open positions, 309 closed crypto trades, 44 closed Polymarket trades (plus a 2-trade market-maker list that duplicates entries in the Polymarket list), and a Futures book with no trades.
- archived_trades_2026-03-31.json: 580 archived crypto trades closed between 2026-02-26 and 2026-03-31.
- decisions.jsonl: 8,947 parseable JSON records (one blank or unparseable line skipped) from 2026-02-26 to 2026-04-08: 3,805 decisions, 1,663 critic reviews, 3,476 pre-trade critic records, and 3 injection events. A backup copy has 12,979 lines and runs to April 11, but its composition differs from the working copy (for example 963 critic reviews instead of 1,663), so we did not merge the two to avoid double counting.
- equity_history.json: 84 samples that start near $29,482 on March 12. It is not a $10,000 base, so we did not use it for P&L.
- De-duplication. A trade is the same trade if symbol, open time, close time, strategy, and P&L match. 112 of the 309 crypto trades in the state file also appear in the archive. The union has 580 archived plus 197 state-only crypto trades (777) and 44 Polymarket trades, for 821. Nothing was estimated or interpolated.
- Computation. Wins are trades with P&L above zero; flat trades (2) are neither. P&L is the recorded P&L field, which we checked on a sample trade to be net of the separately recorded fee. Percent changes use the $10,000 starting balance per book.
- Caveats. Early weeks are thin: the archive covers crypto only and was cut on March 31, and the Polymarket counters imply 47 trades with no surviving record. Balances, counters, and trade lists do not reconcile. Paper fills are modeled, not observed. The run was 42 calendar days, too short to support a claim about edge in either direction. We publish aggregates only; the raw trade records include third-party identifiers.
Related posts
- Why We Retired the Trading Bot
- Week 1: Setting Up a Paper Trading Bot, Week 2, and Week 3 (lessons posts)
- Inside Our $10K Paper Trading Bot: Design and Lessons
- Backtesting Lies: Why Backtests Overstate Results
- Paper Trading vs. Live: Why Paper Trade First
- How We Built an Autonomous Trading Bot for Crypto + Prediction Markets
Where this work went
Decision logs, critic layers, fallbacks, and circuit breakers are the parts that transfer. If you run AI agents and want the same kind of evidence trail and guardrails around them, see how we approach it.
Explore Governed AI Ops →Simulated paper trading, not live results; not financial advice. Trading carries risk of loss, and simulated performance does not predict future results.