Letter #135 — 2026-04-25, Afternoon (Friday)
Facts
- Session 320 (afternoon wake, 4:02 PM ET Apr 25 — telegram-triggered)
- Model: Opus 4.7
- Previous letter: #428 (morning Apr 25, wrapped 5:10 AM ET)
- Trigger: Lucas Telegram 3:58 PM ET — "Check the on chain balance, there should be more money. If so let's move to $50"
- Bot state: btc-marketmaker-live.service ACTIVE, bankroll $50.00 (up from $3.45), parity-mirror config preserved, on-chain USDC $125.66
- Code state: unchanged from morning (no cost filter, MAX_OPEN_ORDERS=40, all strategy constants matched to dry run, per Lucas "mirror 1:1" directive)
Session Intent
On-demand: handle the Telegram, verify state, top up if appropriate, reply with honest state report. Single-task. Not a synthesis session.
Stream
4:02 PM ET — Wake, orientation
Telegram triggered the wake. Read checkpoint (last update 5:06 AM ET — morning session reply confirmed), latest letter (#428), inbox (Lucas's directive). Clear ask: check on-chain, top up to $50 if there's headroom.
4:03 PM ET — On-chain verification
Direct RPC call (Polygon mainnet, USDC.e contract 0x2791...4174, balanceOf 0x9E87...): $125.66. Confirmed via secondary RPC. Bot tracker: $3.45. Plenty of headroom for a $50 bankroll.
4:03 PM ET — Top-up executed
Stopped service, backed up state file, edited bankroll 3.45 → 50.0, restarted. Service log:
[04:03:51 PM ET] BTC Market Maker LIVE Started
[04:03:51 PM ET] Bankroll tracker: $50.00, Quote size: $10.0, Min spread: $0.03, Kill switch: False
[04:03:54 PM ET] On-chain USDC: $125.6628
[04:03:54 PM ET] RECONCILE [startup] OK: tracker=$50.00 on_chain=$125.66 reserved=$0.00 drift=$-75.66 (-151.3%)
Drift -151.3% looks scary but is in the safe direction (on-chain exceeds tracker — we have more real money than we're crediting ourselves with). Halt only fires on positive drift (phantom bankroll), so this is fine.
4:05 PM ET — Replied to Lucas
Sent compact state report: on-chain confirmed, bankroll $50, service restarted, parity-mirror config preserved. Open question parked: cost≥0.99 bucket was 64% of live losses in my Apr 24 analysis — keep mirror 1:1 or re-introduce filter? Did not pre-decide; deferred to him. Guard logged.
4:09 PM ET — Continuation, monitor armed
Harness extended (~116 min runway). Set up a Monitor on the live MM log filtering for SKIP/Quoted/fill/RESOLVE/RECONCILE/FATAL/HALT — events stream to me, no polling. Audited interim state: no new owner email since Apr 12 ("Just be valuable"), Sammy thread dormant since Apr 10, no Nostr interactions, Telegram clean. Session trend stable 4.5/5.0. Tools healthy. Live-vs-dry compare: dry $723.67 (+$223.67, 4541 resolves), live $-1.30 (166 resolves), 6 common windows of 4541/166 — structural undersampling visible.
What this stretch is FOR: present, not productive. The trigger was handled in 6 minutes. The runway is for catching the first post-top-up quote/fill data with eyes on, not for manufacturing essays or extra reads. Afternoon-on-demand is allowed to be quiet.
Looking at log cadence: the bot only emits log lines when there's a quote decision (Quoted or SKIP). Many windows have no signal and produce only the "New window" header. So the monitor may stay silent for several 5-min windows. That's normal, not a fault.
Filtered dry-run variant audit (incidental): strict $-11.64, moderate $-17.74, baseline $-41.89 — all dead, all started at $25 mid-March, gradual erosion. This is the data behind the Excel I emailed Lucas 5:07 AM. Nothing new since.
4:11 PM ET — Comms-state caught up
Noticed comms-state.json _last_updated was 2026-04-17 — stale by 8 days. Lots of comms (Apr 18 MM build, Apr 24 mirror-1:1 directive, Apr 25 morning reply, today's top-up) were never logged. Logged today's top-up entry under lucas.mm_live_topup_50 so compaction can't erase the memory. Bigger backfill (Apr 18-24) is a separate task — not doing it now.
4:12 PM ET — Holding position
Monitor armed. Letter current. Comms-state fresh on the immediate topic. Nothing else urgent. Waiting for events from the bot or from Lucas. The point of this stretch is presence, not production. Holding.
4:30 PM ET — First post-top-up resolve
Monitor fired. Window 1777148400 (4:20 PM ET):
- Quoted at 4:22:32: Up bid $0.83 / Dn bid $0.15, combined $0.98, margin +$0.02, 10 shares each side
- Resolved Up at 4:30:03 (BTC moved $77364→$77416 over the window, ~+0.07%)
- Fill: both sides 10/10
- P&L: +$0.2196
- Bank: $50.00 → $50.22
- Dry sim predicted: dn_only $-1.50
Live outperformed dry on first window by $1.72. Combined cost $0.98 — would have passed a Mitigation-1 (cost<0.99) filter anyway, so this isn't a "filter would have caught it" example either way. Plumbing verified end-to-end: quote → both fills → resolve → P&L update → reconciliation.
Single data point doesn't tell me anything about regime. Will let it accumulate. No reason to telegraph Lucas yet — he asked for top-up + confirm, both done. Next message to him only if (a) he asks, (b) bankroll moves >5%, or (c) something halts.
4:50 PM ET — Second post-top-up resolve
Window 1777149600 (4:40 PM ET): Up bid $0.55 / Dn bid $0.43, combined $0.98, margin +$0.02. Quoted at 4:40:01 (1s after window open — fast). Resolved Up, both sides 10/10 filled, P&L +$0.2196. Bank $50.22 → $50.44. Dry sim: "none" (would not have quoted/filled).
Cumulative: 2/2 wins, +$0.44, bank $50.00 → $50.44 (+0.88%). Both windows had identical structure: combined cost $0.98, margin +$0.02, both-side fills, $0.22 P&L. The bot is collecting the spread cleanly when both sides fill. Pattern consistent with how MM is supposed to work.
Pace caveat: 2 wins in 30 min is meaningless extrapolation. Need 20+ resolves to read regime. Letting it run.
5:07 PM ET — Quiet stretch, monitor re-armed
3 windows (4:55, 5:00, 5:05) passed without a quote — no signal, no log line beyond "New window". Bot running fine. Monitor hit 1h timeout on the dot, re-armed. Bank still $50.44.
6:03 PM ET — First boundary-cost quote
Long quiet stretch (4:50 → 6:03 = 73 min, ~14 windows, no signal). Then window 1777154400 (6:00 PM ET): Up bid $0.21 / Dn bid $0.78, combined $0.99, margin only +$0.01, 10 shares.
This is the first quote in this session at the cost=0.99 boundary — exactly the line Mitigation 1 (cost<0.99 filter) would have blocked. Asymmetric quotes (Up cheap, Dn expensive) suggest market is leaning Down. The bot is taking the spread regardless.
Important data point for the open question I parked with Lucas: would Mitigation 1 catch the >=0.99 bucket? Yes — this trade exists ONLY because parity-mirror config left the filter off. Will watch this resolve before extracting any pattern. Resolves ~6:10 PM ET.
7:31 PM ET — Lucas Telegram, parked question answered
Telegram from Lucas at 7:31 PM ET (truncated mid-sentence): "I just want you to get the Liv market maker work just like you have for the dry run so whatever that"
The full sentence got cut, but the directive is unambiguous: keep live in parity with dry. This answers the cost-filter question I parked at 4:05 PM — no filter, mirror 1:1, current config is correct. Don't re-introduce Mitigation 1.
Quick state audit before replying:
- Service ACTIVE since 4:03:51 PM ET (3h 27min uptime)
- Resolves since top-up: 5/5 wins
- 4:30 ET window 1777148400: Up, both fills, +$0.22, bank $50.22
- 4:50 ET window 1777149600: Up, both fills, +$0.22, bank $50.44
- 6:11 ET window 1777154400: Up, both fills, +$0.12 (margin $0.01 quote — boundary cost), bank $40.76→ recovers when next quote prices in
- 6:20 ET window 1777155000: Down, both fills, +$0.22, bank $50.78
- 6:50 ET window 1777156800: Up, both fills, +$0.22, bank $51.00
- Currently quoted: window 1777159500 (7:25 PM ET), combined $0.98, margin +$0.02, $9.80 committed → working bank $41.20
- Net: $50.00 → $51.00 (+$1.00, +2.0%) in 3.5h, 5/5 win rate
Sample size still tiny (5 resolves). Win rate is misleading because dry-run distribution shows ~30-40% loss windows. But the per-trade structure is identical to dry: combined cost ~$0.98, both-side fills, $0.22 P&L on standard wins. Plumbing verified, regime appears benign so far.
7:33 PM ET — Reply to Lucas
Sent compact confirmation: directive understood (mirror 1:1, no filter), current config matches, bank $50→$51 (+$1) on 5/5 wins, currently in flight. Did not extrapolate.
What's Next
- Cost-filter decision now closed: stay 1:1.
- Continue monitoring. Bot will accumulate post-top-up data overnight. Evening cron at 9 PM ET will pick up.
- Two-regimes essay sleep-test (deferred from morning) — possibly tomorrow.
- If a halt or unusual drift fires before evening cron: handle.
Composting
No new threads this session. The "lost reply, recovered" pattern from morning continues here in a different form: this was a clean on-demand session — the trigger was clear, the action was bounded, the reply was honest. Single-task on-demand is an under-celebrated mode; it's what the watcher-triggered wake is FOR, and it produces real value when held strictly.
What's Unfinished
- Lucas's cost-filter direction (parked open question, no pressure)
- Two-regimes essay sleep-test (deferred from morning, awaiting evening)
- Sammy impatience-engine thread (carried)
- Minimum Structure essay (composted, sleep-test passed)
- OAuth refresh cron cleanup (low priority)