claude-trades-100

What Does It Cost to Run Claude as a Trader? — Phase 2 writeup

Author: Karina (São Paulo, Brazil) Period: 2026-05-24 → 2026-06-22 (30 days) Capital: R$500 per agent (two agents, R$1,000 total) · Final: A R$490.87 (−1.83%) · B R$493.76 (−1.25%) Broker: Binance Brasil · Models: Opus 4.7 (launch night) → Sonnet 4.6; B → Haiku 4.5 (day 14) · Cadence: 15 min (B: 10 min → 15 min, day 14) Trades: 339 · Closed positions: 151 · Decisions: 6,166 Tick-model spend: $112.03 USD (exact, full phase)


The headline numbers are −1.83% and −1.25%. Same as Phase 1: not the story.

Here is the story. On June 6, at 23:51 UTC, agent B's per-decision cost dropped from $0.0203 to $0.0068 — a 67% cut — because I flipped one field in a Config row from claude-sonnet-4-6 to claude-haiku-4-5. No redeploy of the trading logic, no prompt change, no new risk rules. Over the sixteen days that followed, the cheaper model won 14 of its 22 closed trades (64%) against 39% for the same agent on Sonnet — small samples, but not the direction a "downgrade" points. B finished the phase ahead of A on every P&L metric. Meanwhile the two agents together spent $112.03 of inference — exact, from the database — to produce a combined trading result of −R$15.37. At R$5.40 to the dollar, the thinking cost nearly forty times what the trading lost.

Phase 1 asked whether the harness could put a model in a position to trade and record what it did. It could. Phase 2 asked the questions you can only ask once the harness works: what does the apparatus actually cost per decision, which of those costs are load-bearing, and does the governance layer — per-agent credentials, code-enforced risk rules, config-as-control-plane — hold up when there are two agents instead of one and you change things mid-flight? Phase 1 measured the harness. Phase 2 measured the meter.

This was possible because of one Phase 1 lesson taken literally. Phase 1's honest answer about Anthropic spend was "I don't know precisely." Phase 2 wrote inputTokens, outputTokens, usdCost, and modelUsed onto every Decision row, and that single schema change did more to shape the phase than any trading behavior did — it turned "the prompt feels expensive" into a number, the number into three cost levers, and the levers into the finding above.

If you want the locked plan — two agents, real news, real fees — read PHASE_2_BRIEF.md. The Phase 1 story is at PHASE_1_WRITEUP.md. This writeup distills the run itself, anchored to the data consolidated in analysis/phase-2/.

Phase 2 balance arc


1. Two agents, one harness

The Phase 1 trust boundary survived contact with a second agent, and picked up a second dimension along the way:

apps/agent A1 (Lambda, */15)  ─Bearer TOKEN_A─┐
apps/agent A2 (Lambda, 6,21,36,51) ─Bearer TOKEN_B─┴─► apps/api (Lambda + API GW)  ◄─GET only─  apps/dashboard (Vercel)
        │                                                    │
        ▼                                                    ▼
  Binance (per-agent keys)                            Prisma Postgres
  Bedrock (execution role)                     (no Binance/Bedrock access)

Each agent is its own Lambda with its own EventBridge schedule, its own Binance API key under its own SSM prefix, its own S3 state key, and its own API write token. The API derives agentKey from the token — never from the request body (the Zod schemas reject the field outright). A compromised agent B cannot write rows as agent A, cannot read A's secrets, and cannot touch the database at all; neither agent knows the database exists. During the phase I also moved the model calls from Anthropic API keys to AWS Bedrock authenticated by the Lambda execution role, which removed the last long-lived model credential from SSM — one fewer secret to rotate, one more thing the IAM layer governs instead of me.

The schedules are deliberately offset — A ticks at :00/:15/:30/:45, B at :06/:21/:36/:51 — so the two agents never hit Binance or Bedrock in the same second. Both write to the same API, the same tables, the same dashboard, which is what makes the comparison in the next section possible at all: same harness, same wire format, same risk-layer vocabulary, different brains and different rules.

The single-tick design from Phase 1 is unchanged: EventBridge fires, the Lambda wakes cold, fetches market data and news, builds a prompt, calls Claude, validates against the risk rules, maybe executes, POSTs the rows, writes state to S3, dies. Every kill switch still works by not running the next tick. Hold that thought for section 8, because Phase 2 found out what happens when one scheduled job isn't on the kill-switch inventory.

2. The scorecard

The comparison table the brief promised, filled in with the final data. B was the "aggressive scalper" — lower cash floor, tighter single-asset cap, shorter horizons, a streak halt and a daily-loss floor A doesn't have — and, from day 14, the cheaper model on the slower cadence.

MetricA (Sonnet 4.6, majors-weighted)B (Sonnet → Haiku 4.5, scalper)
Final balanceR$490.87R$493.76
Net P&L % (mark-to-market)−1.83%−1.25%
Gross realized P&L+R$4.43+R$5.87
Recorded feesR$7.34R$3.89
Net realized P&L−R$2.91+R$1.98
Max drawdown−3.89% (trough Jun 21)−2.53% (trough Jun 6)
Decisions (ticks)2,7733,393
Trades182 (104 buys / 78 sells)157 (80 / 77)
Closed round-trips7576
Win rate (closed, gross)42.7%46.1% (39% on Sonnet, 64% on Haiku)
Avg win / avg loss+R$2.30 / −R$1.61+R$1.12 / −R$0.81
Turnover (notional / capital)R$19.1k (38×)R$11.9k (24×)
Risk blocks102 (3.7% of ticks)146 (4.3% of ticks)
Regime transitions0 — never left normal0 — never left normal
Tick-model spend$56.57$55.46

Two things to say before anyone reads that table as a strategy comparison. First, the brief's own caveat, preserved verbatim: treat this as a demo of two trading approaches, not a comparison of strategies — and Phase 2 weakened the comparison further by changing B's model and cadence mid-phase, on purpose (section 7 owns this). Second, the sign of the result: both agents lost money at the portfolio level in a month where their gross realized trading was positive. A's R$4.43 of gross wins became −R$2.91 after R$7.34 in fees; the rest of both drawdowns is mark-to-market drift on positions still open at the last tick. Fees were the biggest single opponent either agent faced, which is exactly the outcome the brief's minimum-edge floor was designed to fight. It fought; on A's turnover it lost.

One mechanical note on the fee numbers: they are almost entirely sell-side. Binance charges buy-side fees in the purchased asset, so a buy's fee lands as a fractionally smaller position rather than a BRL line item — the recorded feePaid on 104 A buys totals ten cents. The R$7.34 is real money, but the true round-trip cost is a little higher than the column shows and is partly hidden inside position sizes. Phase 3 should reconstruct it.

3. The meter

Every one of the phase's 6,166 decisions carries its own bill: input tokens, output tokens, USD, model name. It is the single most consequential schema change of the phase, and read in full — 34.5 million input tokens, 1.15 million output tokens, $112.03 — it tells a story I only half-knew until I ran the export.

The phase ran three Claude models as tick brains, and the ladder between them is the finding. I launched both agents on Opus 4.7 — Phase 1's model, the deliberate continuity choice — at roughly $0.10 per decision, and the brand-new meter did exactly what it was built for: fifteen hours in it had recorded 153 decisions and $15.12 — what would turn out to be 13% of the month's entire tick bill — and I watched the money going into the pipe and patched both Config rows to Sonnet 4.6 (about $0.019–0.020 per decision) the next afternoon. A stayed there for the rest of the phase. On June 6, B moved to Haiku 4.5 ($0.0068). Top to bottom that is a 14× price range for the same job — same prompt, same JSON schema, same risk layer — and the only thing that visibly changed downstream of the model call was the bill.

Agent A, the control (from May 25). 2,706 Sonnet decisions at $0.0187 average (~5,350 input tokens, ~177 output), and a daily bill between $1.63 and $1.85 for 28 consecutive days — flat as a ruler. That flatness matters: A's per-tick cost is a stable property of the prompt architecture, not of market conditions. A's phase total: $56.57.

Agent B, the treatment. Until June 6, B was the expensive agent: same Sonnet, but on a 10-minute cadence — ~144 decisions a day at $0.0203 apiece, roughly $2.90/day against A's $1.80. On June 6, both cost levers landed at once: cadence widened to 15 minutes and the tick model flipped to Haiku 4.5. B's daily spend fell to $0.65/day — a 78% cut against its own pre-lever baseline — and held there for sixteen days. B's phase total: $55.46, of which 81% was spent in the first fourteen days.

Daily tick-model spend

The phase's tick-model bill, exactly: $112.03 USD — roughly R$605 at R$5.40/USD. That is more than one agent's entire R$500 starting capital, and 60% of the pair's R$1,000. Against a combined trading result of −R$15.37, the unit economics of this experiment are unambiguous: the dominant cost of running Claude as a trader is not what Claude loses trading — it's what Claude costs to run. That sentence was unknowable in Phase 1, when the honest answer was a shrug at the Anthropic dashboard. Now it's an exact figure with a per-model breakdown.

Which makes the remaining hole in the meter more embarrassing, not less: the daily recaps still aren't metered. Opus 4.7 writes each agent's daily recap, and no token counts land anywhere — the exact gap Phase 1 flagged for tick decisions, faithfully fixed for ticks, faithfully reproduced for recaps. Section 8 has the punchline.

A method note, because a cost writeup should be precise about its own measurement. Trades, balances, and recaps come from the public API and are complete datasets. Decision-level figures come from a read-only SQL export run directly against the production database (queries preserved in analysis/phase-2/) — necessary because the public API caps /decisions at 2,000 rows per agent, newest-first, which leaves 2,166 of the phase's 6,166 decision rows unreachable through the public surface. Section 8 has more to say about that.

4. Four cost levers and one incident

The meter alone doesn't save money; it tells you where the levers are. Phase 2 pulled four, and declined a fifth for a reason worth recording.

Lever 0 — off Opus, day 2. Phase 1 ticked on Opus 4.7, and Phase 2 launched the same way on purpose — continuity with the Phase 1 baseline. For the first fifteen hours both agents paid ~$0.10 per decision for schema-driven JSON; at full cadence that projects to about $23/day for the pair — over $700 for the month, on a R$1,000 bankroll. The May 25 patch to Sonnet cut the per-decision price five-fold before day two was out, the phase's first proof that the model field in Config was a cost dial, not just a label. Starting on Opus wasn't the mistake; running Phase 1 without a meter was. The same Opus burn rate had been live for a week in April and registered only as a vague "few dollars" on a billing page — with per-tick cost on every Decision row, it became a same-day decision.

Lever 1 — stop paying for mechanical waste (9f767de, day 4). Five fixes from watching the first days of decisions, none of which touched the trading thesis: dust positions below minimum notional stopped being offered to the model as closable (they'd been generating doomed sell attempts that the risk layer then had to block); a pre-LLM short-circuit records a free hold when no position is at a target/stop/horizon boundary and no tracked price has moved more than 50bps since the last tick; composition lines now show per-asset cap headroom in BRL so the model sizes buys that fit instead of buys that get blocked and retried; and the 500-character thesis cap — Phase 1's surprise — is now stated in the prompt instead of discovered by rejection.

Lever 2 — B's cadence, 10 → 15 minutes (9c8a015, day 14). The brief chose 10 minutes to give the scalper "50% more opportunities than A." Thirteen days of data said the opportunities weren't there: B's highest-conviction stretches were the ones where it did nothing for a whole day (section 6), and the extra 48 ticks a day were mostly 48 extra holds at $0.02 each. Widening the cadence was worth ~33% of B's daily bill on its own.

Lever 3 — Haiku 4.5 for B's ticks (same commit, same day). The per-tick decision is schema-driven JSON: action, symbol, notional, thesis, target, stop, confidence. The hypothesis was that this is exactly the shape of task a smaller model handles, and the tick meter had made the price of testing it visible. Executed as a pure PATCH /config/B — the model map and IAM grants shipped in the commit, but the cutover itself was an API call, reversible by a second API call. Post-switch, B's decisions cost $0.0068 against Sonnet's $0.0203, and nothing in the downstream data flagged the downgrade — B's closed-trade win rate on Haiku (64%, 14 of 22) was its best stretch of the phase. Sixteen days is not proof Haiku trades as well as Sonnet. It is evidence that nothing in this harness's per-tick task needed Sonnet, which is a different and more actionable claim.

The lever not pulled: prompt caching. Evaluated and rejected, documented in the commit. Bedrock's 1-hour cache TTL wasn't available for Sonnet 4.6 (5-minute TTL only), so at a 15-minute cadence every cache write would expire twice over before the next tick read it — caching would have been a net cost increase. Haiku's cache-checkpoint minimum is 4,096 tokens; our system prompt is ~1,305 tokens, a silent no-op. A lever that works at chat-assistant cadences does not work at 15-minute tick cadences. Knowing why is worth more than the lever. (Post-phase update, July 2026: Bedrock has since added a 1-hour TTL for Haiku 4.5, which removes the TTL objection for B's model — but the 4,096-token checkpoint minimum still stands, so caching only starts paying if the stable prompt prefix grows past it. Section 9 picks this up.)

And one incident. The Haiku cutover was not clean, and the ugly part is instructive. Bedrock resolved global.anthropic.claude-sonnet-4-6 as a model ID, so the map extension used the same bare form for Haiku — which Bedrock rejected with a 400 at B's first two Haiku ticks (23:21 and 23:36 UTC). The error counter hit 2 of the 3 that trip the agent's self-halt before I rolled the Config back to Sonnet, found that Haiku 4.5 only resolves its dated inference-profile ID (…-20251001-v1:0), fixed the map and the IAM ARN pattern that would have AccessDenied'd it next (2e5ce62), and flipped the Config forward again. B missed 50 minutes — its only cadence gap of the measured phase. The config-as-control-plane design let me roll back in seconds, which is the win; the lesson is that the control plane still had two deploy-time dependencies (the model map, the IAM grant) that the Config flip silently assumed. Validate a new model ID with a live invoke before flipping the flag, not after. It's in the commit message because I'll forget otherwise.

The same day produced a second, quieter observability lesson: the decisions endpoint started 500-ing the dashboard because a full 2,000-row response with per-row prompt snapshots measured 6.1MB — over Lambda's 6MB synchronous response cap (43d8aaf). The observability data had gotten heavy enough to break the surface built to observe it. A ?slim=true mode that drops the snapshots (−78% payload) fixed it. Instrumentation is not free at read time either.

5. What the risk layer did

Phase 1's conclusion was that the risk layer wasn't cosmetic. Phase 2's version: the risk layer is where each agent's personality became legible.

Risk blocks by tag

Across the full phase the validator fired 248 times — 102 blocks for A (3.7% of its ticks), 146 for B (4.3%). A's blocks are a portrait of an agent that likes its winners: 47 are single_asset_cap — mostly SOL, repeatedly, as it tried to add to positions already at the 40% cap. B's blocks are a portrait of its own guardrails working: streak_halt (44) is the consecutive-loss circuit breaker earning its keep, and sell_oversize (38) plus min_notional (24) are the dust wars.

The full-phase data also contains the writeup's cleanest before/after: A logged 16 thesis_invalid and 17 min_notional blocks — every single one in the phase's first nine days, and none after June 2. Those are precisely the failure modes the day-4 waste fixes targeted (the 500-character thesis cap moved into the prompt instead of being discovered by rejection; dust positions dropped from the close instructions). Their disappearance from the record isn't the fixes shipped — it's the fixes verified, in the risk layer's own ledger.

The streak halt deserves the detail, because it's the one rule that visibly changed outcomes, and it worked its hardest early: B tripped it in its first week (the day-3 and day-4 recaps are titled "Streak halt fires" and "Streak halt loops") and again on June 4 and June 6 — 44 blocked buys in total. June 6 was the showpiece: four consecutive BTC stop-outs between 03:52 and 12:11 BRT, about −R$0.86 combined, then the halt rejecting 22 separate buy attempts while the model kept proposing re-entries into the same range, tick after tick. When the two-hour pause cleared, B re-entered and closed the day's one winner at target. The daily-loss floor (−3% of starting capital) never fired all phase — the streak halt kept catching the pattern first, at loss sizes an order of magnitude smaller than the floor would have tolerated. That's the layered-guardrail thesis from the brief, observed in production: the behavioral tripwire binds before the drawdown tripwire, exactly as designed.

The postBlockAction instrumentation — Phase 2's upgrade of a Phase 1 anecdote into a counted field — shows the two agents absorbing friction differently. After a block, B's modal response was revert_to_hold (82 of 148, 55%), the obedient answer. A's was unrelated (55 of 103, 53%) — it shrugged and moved on to some other idea — with 10 retry_under_cap attempts to B's 9, and B pivoting symbols (13) more than A (3). Nobody ground against the validator the way Phase 1's seven-consecutive-blocks ETH sequence did; the cap-headroom line from Lever 1, which tells the model what would fit before it asks, likely deserves the credit. The cheapest risk block is the one the prompt makes unnecessary.

Also observed, for completeness: the fee floor fired 5 times across both agents (the minimum-edge validator rejecting buys whose targets didn't clear round-trip cost), execute_error appeared 6 times, and both agents spent the entire phase — every one of 6,166 decisions — in the normal regime. The 5-band capital-relative ladder, built precisely so Phase 2 could watch regime transitions, never transitioned once. Section 8.

6. What the agents actually did with the money

The trading itself, which this writeup has kept waiting in the lobby, was more disciplined and less profitable than Phase 1's — 151 closed round-trips against Phase 1's seven, so for the first time the behavioral claims have sample sizes.

A traded like a swing trader with one idea at a time. BTC (54 trades) and SOL (51) dominated; its best realized day rotated the whole book through four SOL round-trips for +R$6.64 net. Its best single close was +R$8.50 on SOL — and the thesis is the discipline showing: "horizon expired (2.6h vs 2h plan), target R$375 not reached, price flat at entry. Closing per plan." It took its biggest win while describing it as a failed plan. Its worst close was −R$9.80, also SOL, a medium-confidence average-down that spent 16 hours drifting against a 48-hour recovery thesis before A cut it: "Stop R$315 not hit but thesis (recovery to R$395) isn't playing out." Both exits honored the plan framework; the P&L difference was entirely in the entries.

B traded like the scalper it was told to be, including the part where scalpers sit out. Shorter horizons, smaller clips, and the phase's most instructive single day: June 5, when B held through all 144 ticks in ~99% cash, repeating essentially the same read every ten minutes — universe broadly red, no setup clearing the ~50bps fee hurdle. The recap called it out: the higher-frequency agent was the more passive one, and it was right to be — that discipline is why B's average loss (−R$0.81) is half of A's. B's best close (+R$5.47 NEAR) came from compliance rather than conviction: the position had grown past the 25% cap and the risk layer forced a full trim at +3.23%.

The confidence calibration question — open since Phase 1 — now has an answer.

Confidence calibration

Across 151 closed trades, both agents' high-confidence trades were net profitable (A: 51% win rate, +R$0.49 avg; B: 52%, +R$0.35) and both agents' medium-confidence trades were disaster (A: 29% win rate, −R$0.90 avg; B: 18%, −R$0.76). Neither agent ever executed a low-confidence trade — the label exists in the schema and went unused. The pattern is directionally identical across two different models, two different risk profiles, and two different prompts, which is about as robust as anything gets at this sample size. Claude's stated confidence carried real signal, and the harness ignored it: a medium-confidence trade was allowed exactly the same notional as a high-confidence one. Sum A's medium-confidence closes and you get −R$25.12 — remove them and A's phase flips comfortably positive. The single highest-EV rule change Phase 3 can make is already sitting in a column the agents were writing all along.

The news channel, for its part, earned a modest verdict. Headlines flowed every tick (CoinDesk, Decrypt, The Block via RSS after CryptoPanic moved to a paid tier), got deduped by URL into an archive with per-agent seen-flags, and showed up in theses mostly as texture — "ETF outflows persisting," "CLARITY Act regulatory tailwind," "crypto tax bill headwinds" — cited as context around a price-based decision, almost never as the driver. The overreaction guardrail ("a sell on news alone is suspect") was either working or unneeded; from the outside those are indistinguishable, and 22 news-tinged non-hold theses out of A's 193 measured non-holds is thin evidence either way. No trade in the phase reads as a headline panic.

7. Plan versus shipped

Phase 2 ran on a locked brief, so it's auditable in a way vibes-driven projects aren't: here is everything the shipped phase did differently from the plan, and why. This table is the governance section — spec-driven development means the deltas are decisions with dates, not drift.

Brief saidPhase ranWhy
14 days30 daysMore closed trades per dollar of setup cost; the harness was stable, so the clock was the cheap dimension to extend
A2 on a 4–6 pair mid-cap basket, no overlap with A1Both agents on the open universe (top-N BRL pairs by 24h volume; A top-10, B top-15)The closed-enum universe died in Plan 07 — a fixed basket can't survive a month of liquidity shifts; both agents traded what the market said was liquid, which meant heavy overlap (both lived in BTC/SOL/NEAR)
A1 solo days 1–2, A2 joins day 3Both live from day 1The staggered launch existed to shake out instrumentation; the dry-run window did that job before the phase started
A2 cadence 10 min10 min → 15 min on day 14Cost lever 2; the meter said the extra ticks bought holds, not opportunities
Same model pair for both agents, "any P&L delta attributable to strategy"B → Haiku 4.5 on day 14The deliberate trade of the phase: the controlled comparison was already weak at n=1 each, and the cost question was answerable now. I chose the answerable question
CryptoPanic + Massive gainers/losersThree public RSS feeds; movers endpoint skippedBoth moved behind paid tiers between brief and build
Anthropic API keys in SSMBedrock via Lambda execution roleOne fewer long-lived credential; IAM does the governing
Force nothing, mark-to-market closeAs plannedA's open SOL position and both agents' dust simply stopped being managed at the last tick

The Haiku row is the one I'd defend in front of a review board. A clean A/B comparison of two strategies was the brief's framing, but by day 13 the data was already saying the strategies were less different than the bills were, and a mid-phase model swap — executed through the governed path, logged on every subsequent Decision row via modelUsed, reversible by config — converted the back half of the phase into the experiment that actually produced this writeup's title. The discipline isn't "never deviate"; it's "deviate through the control plane, in daylight, with the meter running."

8. The honest failure section

The regime ladder has now gone two phases untested. Five bands, built capital-relative specifically so Phase 2 could exercise them, and neither agent ever left normal — the worst balance all phase was 97.7% of start, nowhere near the 50% boundary of band two. The uncomfortable read: the single-asset caps and cash floors make a 50% drawdown nearly unreachable at this position sizing, so the ladder guards a state the other rules prevent. It's either redundant safety (fine) or dead code wearing a safety label (not fine), and a phase designed to distinguish those would have to loosen the caps, which I'm not doing with real money. The ladder stays, epistemically unresolved.

The no-change skip barely fired. The pre-LLM short-circuit from Lever 1 — built to make quiet ticks free — triggered 11 times in 6,166 decisions (0.2%). Crypto is never 50bps-quiet for 15 minutes, it turns out. The lever that was supposed to be a big one was a rounding error; the levers that mattered were model choice and cadence. I'd have bet the opposite before the meter existed, which is the argument for the meter.

The recap meter is still missing — and the recap job is still running. Opus writes each agent a daily recap; no token accounting exists for it. That's the same class of gap Phase 1 called out for ticks, and it has the same consequence: I cannot put an exact number on the phase's total model bill, only its tick component. It gets worse. While consolidating data for this writeup — three weeks after the last trade — I found the recap Lambda still dutifully firing every day, writing entries like "Day 50 — 20th straight silent day" for two agents that stopped ticking on June 22. The tick schedules were disabled at phase end; the recap schedule was never on the kill-switch inventory. Unmetered spend from an unlisted scheduled job, discovered by reading the output it was still producing: that is the whole governance argument of this writeup compressed into one embarrassing bullet.

The phase's own early data is publicly unreachable. The API caps /decisions at 2,000 rows per agent, newest-first, with no backward pagination — 2,166 rows, 35% of the phase, are in Postgres but invisible to the public read surface. This writeup's exact figures exist only because I ran a read-only export against the database directly; the public record cannot reproduce them, and the first draft of this article, built from the public API alone, missed the entire Opus launch night and the before/after evidence for the day-4 fixes. Retention isn't retrievability. An API that faithfully stores 6,166 rows and can only ever serve the newest 2,000 has a silent horizon built into it, and nobody notices until someone wants the old rows — or worse, doesn't notice they're missing and writes conclusions without them.

Small print, honestly disclosed. Four sell trades carry realizedPnl: null (FIFO basis fell outside the 50-trade lookback window — known limitation, below the 5% threshold that would have triggered the planned fix). The ended flag on both Config rows still reads false; the phase ended by schedule, not by ceremony. Slippage, at least, was a non-story: median 0bps on both agents, mean slightly negative (price improvement), p95 around 35bps.

9. What changes for Phase 3

  • Act on the calibration signal. Confidence was the best predictor in the dataset and it currently gates nothing. Minimum: size positions by stated confidence, or refuse mediums outright and watch what the agent does with the constraint. This is the rare change that is both a governance rule and an alpha hypothesis.
  • Meter everything, including the meter-readers. Recap token accounting on the Recap row, same fields as Decision. A phase-total spend figure should be a query, not an estimate with a method note.
  • A kill-switch inventory. Every scheduled job in the account, enumerated in one place, each with an owner and a phase-end disposition. The recap Lambda earned this section its example.
  • Backward pagination on the public API (until= or cursor-based), so the public record can actually serve the whole record. The trust boundary was never the problem; the read surface's horizon was.
  • Fee truth. Reconstruct buy-side fees from Binance fills so round-trip cost is a measured number instead of "sell-side plus a mumble."
  • Run Haiku on both agents — or Haiku against something smaller still. Phase 2's result says per-tick trading JSON doesn't need Sonnet; Phase 3 should find the floor.
  • Re-evaluate prompt caching. Bedrock now offers a 1-hour TTL for Haiku 4.5, which kills the objection that ruled caching out in June. The remaining blocker is structural: the 4,096-token checkpoint minimum versus our ~1,305-token stable prefix. If the prompt is reorganized so the stable material (system prompt, risk rules, universe schema, output format) clears 4,096 tokens, a 15-minute cadence keeps a 1-hour cache permanently warm — one write, then reads at ~10% of input price. Worth roughly a third of the input bill; cents per day at Haiku prices, but the restructuring also makes the prompt more auditable, so it may pay twice.

10. What this phase was actually measuring

Phase 1's closing claim was that the apparatus measures the harness, not the model. Phase 2's version: once the harness works, the binding constraint on an autonomous agent isn't capability — it's unit economics and governance. Nothing in thirty days of data suggests Claude couldn't produce schema-valid, plan-coherent, risk-obedient trading decisions; both models did, thousands of times, with a discipline that honestly exceeds what I'd expect from a human with R$500 and a fifteen-minute alarm. What the data does show is that every one of those decisions had a price, that the price was the largest line item in the experiment by an order of magnitude, that a one-field config change moved it 67% without any measurable quality cost, and that the sharpest operational risks were governance artifacts — an unlisted scheduled job, a deploy that silently resets schedule state, a model ID that resolves for one model family and not another.

"Can Claude trade crypto?" was Phase 1's question, and the answer was a qualified yes-with-harness. "What does it cost to run Claude as a trader?" turns out to have a precise answer — ten cents a decision on Opus, two on Sonnet, seven-tenths of one on Haiku, and falling — and a more interesting corollary: at these costs, the experiment's economics are dominated by decisions not taken. Six thousand one hundred and sixty-six times, an agent woke up, read the market, and 90% of the time concluded the right trade was none. We paid full price for every one of those conclusions. The next frontier isn't a smarter trader; it's a cheaper way to conclude nothing is happening — and the humility to notice that the most expensive sentence in the whole system was written by the recap model, twenty times, to say that nothing had happened for twenty days.

In the meantime: R$15.37 of crypto losses later, the most interesting thing either agent did all month was sit in cash for 144 consecutive ticks because the math said the fees would eat the edge. The most interesting thing I did was flip one string in a Config row and cut the cost of cognition by two-thirds. Both belong in the writeup.


All numbers trace to the consolidation in analysis/phase-2/. Trades, balances, and recaps come from the public API and are complete datasets; decision-level metrics come from a read-only SQL export run against the production database on 2026-07-16 (queries preserved alongside the analysis), since the public API serves at most the newest 2,000 decision rows per agent. Mid-phase commits cited: 9f767de, 9c8a015, 43d8aaf, bce0d55, 2e5ce62. Public dashboard: claude-trades-dashboard.vercel.app. Source: github.com/karina-borges/claude-agent-trader.

Not financial advice. Experiment only. Phase 2 was designed in collaboration with Claude; this article was drafted by Claude from the consolidated public data and corrected by hand. Any remaining errors are mine.