Welcome to Limitless Trader Lab

Day 3 of 7 · Cohort intensive · 90 minutes

Drop the control panel.

Yesterday you shipped infrastructure. Today you drop a one-page HTML panel on top of it that renders positions, recent fills, P&L, and a kill switch, running on hand-written seed data. Bonus pack drops mid-morning so the panel template is in your hands. Mid-week live Google Meet at the time pinned in #trader-lab: coach demos the panel; bring your blockers.

90 minutes 1 deliverable #trader-lab · [D3] Bonus pack drops Mid-week live call

Today you’ll learn

You’ll learn how to install the bonus-pack control panel template on top of yesterday’s infrastructure, drop hand-written seed JSON onto the persistent volume, and render positions + recent fills + a kill-switch on your phone. This will help you build the visceral coupling the rest of the cohort depends on: by Day 4, when you place your first real order, the fill lands in the panel you built today, on your phone, in seconds.

Section 01

Why a panel.

By Day 6 your bot is running somewhere that isn’t your laptop. tail -f fills.ndjson over SSH works for the first hour. It stops being fun by hour three. A browser tab on your phone showing the same data, plus a kill-switch button, is the difference between sleeping through Saturday and not. Today is the install. The bonus pack ships the template; you point it at the volume from Day 2, drop seed JSON, and the panel renders. Tomorrow the first real fill lands in this same panel. Day 7 the kill-switch on this same panel is what graduates you.

Glanceable

Positions table, recent-fills feed, P&L curve, kill-switch state. Whole bot in a single tab. Phone-sized by default.

Live

The panel polls the Day 2 volume every 3 seconds. When the bot writes, the panel updates without a refresh.

Stoppable

Kill-switch button writes a sentinel file the bot polls. One tap, one second, bot halts. Same gesture from your phone or your laptop.

API Academy · Module 02 · Trader Control Panel deep-dive

Section 02

The bonus pack drops.

Coach pins the bonus-pack link in #trader-lab mid-morning. The whole cohort gets it in the same hour, on purpose. Today’s install order is short: bonus/CONTROL_PANEL.md first, that’s the panel template. bonus/SECRETS.md second if you didn’t read it pre-Day 1, secrets discipline is non-negotiable before tomorrow’s first order. Everything else (Trading skill, Monitor, Strategy) waits until the day it’s needed.

Today’s install order

bonus/CONTROL_PANEL.md, the panel template (FastAPI backend + single-page HTML). Today.

bonus/SECRETS.md, secrets discipline (API key + EIP-712 private key). Read today if you didn’t pre-Day 1.

bonus/skills/trading/, ships with the bonus pack but installs Day 4 (when first order is placed). Skip today.

bonus/skills/monitor/ + bonus/skills/strategy/, install Day 5. Skip today.

Section 03

Seed the volume.

The panel reads positions from /app/data/positions.json and fills from /app/data/fills.ndjson. No bot exists yet to write them. So you write them by hand, three fake positions and ten fake fills, and prove the panel can render real data shapes. Day 4 you replace the seed with the real first fill. The shape doesn’t change.

1

You are now: writing the seed locally

In your limitless-lab/ folder, create data/positions.json and data/fills.ndjson with hand-written rows. Three positions, ten fills, mixed YES / NO sides. Realistic-shaped, fake-valued.

data/positions.json
[ {"slug": "btc-70k-friday", "title": "BTC > $70K by Friday", "side": "YES", "shares": 12, "avg_price": 0.58, "mark": 0.62}, {"slug": "lakers-tonight", "title": "Lakers win tonight", "side": "NO", "shares": 6, "avg_price": 0.49, "mark": 0.45}, {"slug": "powell-cuts-may", "title": "Powell cuts in May", "side": "YES", "shares": 4, "avg_price": 0.71, "mark": 0.74} ]

For fills.ndjson: one JSON object per line, fields {ts, slug, side, shares, price, order_id}. Ten lines, varied timestamps. Claude will draft both files for you in one prompt.

2

You are now: pushing the seed to the volume

The volume lives on Railway, not your laptop. Use the railway run pattern to copy the local seed onto the production volume.

Run in terminal
# Easiest pattern: pipe the local file into the volume via railway run # macOS / Linux: $ cat data/positions.json | railway run "cat > /app/data/positions.json" $ cat data/fills.ndjson | railway run "cat > /app/data/fills.ndjson" # Windows PowerShell (-Raw preserves the file as a single string): PS> Get-Content data/positions.json -Raw | railway run "cat > /app/data/positions.json" PS> Get-Content data/fills.ndjson -Raw | railway run "cat > /app/data/fills.ndjson" # Verify both files landed (railway run executes inside the Linux container, ls -la works on every OS) $ railway run "ls -la /app/data/" positions.json 408 bytes fills.ndjson 1.2K touch.txt 13 bytes

If the cat-into-railway pattern feels indirect, the bonus pack’s CONTROL_PANEL.md documents two alternatives: a one-shot /admin/seed POST endpoint, or a manual upload via the Railway dashboard.

Section 04

Install the panel backend.

The bonus pack ships control_panel.py, a small FastAPI app that reads from the volume and serves the HTML page + four JSON endpoints (/api/positions, /api/fills, /api/kill, /api/kill/toggle). You don’t write the backend; you mount it. Add it to your Day 2 app.py via app.mount("/panel", panel_app), or run it as a second process. Either works.

1

You are now: copying the panel files into the project

From the unzipped bonus pack, copy CONTROL_PANEL.md’s two embedded files (control_panel.py + control_panel.html) into limitless-lab/panel/. Add fastapi + uvicorn[standard] to requirements.txt if they aren’t there from Day 2.

2

You are now: pointing the panel at your volume

The panel reads paths from env vars. Set them on Railway:

Run in terminal
$ railway variables --set "AGENT_LOG=/app/data/fills.ndjson" $ railway variables --set "POSITIONS_PATH=/app/data/positions.json" $ railway variables --set "KILL_SWITCH=/app/data/kill.flag" # PANEL_TOKEN was set on Day 2; double-check it’s still there # macOS / Linux: $ railway variables | grep PANEL_TOKEN # Windows PowerShell (grep doesn’t exist by default, use Select-String): PS> railway variables | Select-String PANEL_TOKEN

If PANEL_TOKEN isn’t set, mint one now. On macOS/Linux: railway variables --set "PANEL_TOKEN=$(openssl rand -hex 32)". On Windows PowerShell: $token = -join ((48..57)+(97..102) | Get-Random -Count 64 | %{[char]$_}); railway variables --set "PANEL_TOKEN=$token". The token gates every API call, without it, anyone with your URL could trip the kill switch.

3

You are now: redeploying

railway up. Wait for the build. Tail the logs to confirm both processes started.

Run in terminal
$ railway up $ railway logs --tail [uvicorn] Application startup complete. [uvicorn] Uvicorn running on http://0.0.0.0:8080

Section 05

Open it on your phone.

Your panel is at https://<your-railway-domain>/panel/?key=$PANEL_TOKEN. Open it on your phone. Bookmark it. Pin it to your home screen. The whole point of the panel-first arc is the muscle memory: phone in hand, panel in tab, bot in the air. Today the panel renders seed data; tomorrow the first real fill lands in the same view, in seconds.

1

You are now: hitting the URL on your phone

Phone browser. Type the URL. Pass the panel token via the ?key= query param.

You should see the positions table (3 rows from your seed), a recent-fills feed (10 rows), a P&L curve (Chart.js) drawn from the fills, and an ARMED kill-switch button. If the kill button reads TRIPPED, your /app/data/kill.flag file already exists, safe to delete via railway run "rm -f /app/data/kill.flag".

2

You are now: trip + clear the kill from your phone

Tap the kill button. Confirm. Watch the state flip to TRIPPED. Tap again, confirm, watch it return to ARMED.

No bot is running yet, so nothing actually halts. The point is the gesture, tomorrow the bot polls this same flag every iteration.

3

You are now: bookmarking the URL

Phone home screen, bookmark, share to your password manager, whichever fits. From Day 4 onwards, this is the first tab you open every morning.

Section 06

Mid-week live call.

Tonight, 45 minutes on Google Meet. Calendar invite came with your acceptance email; coach also re-pins the link in #trader-lab an hour before. Bring your panel up on your laptop and your phone. Coach demos the panel install live, runs the intervention drill (kill switch from phone), and unblocks anyone whose seed-data step or volume mount is stuck.

1

10 min · Coach demos a clean panel install

From the bonus pack zip on a fresh laptop. Five Railway commands, seed JSON, redeploy, panel rendering on phone. End-to-end in under ten minutes.

2

15 min · Intervention drill

Coach trips the kill switch from a phone, watches the panel flip TRIPPED, clears it via the dashboard, watches it flip back. Every cohort member runs the same drill in parallel. By the end, the gesture is in your hands.

3

10 min · Q&A

Anyone whose deploy or volume mount is sideways gets unstuck on camera. Day 4 depends on the panel working, don’t leave the call with a broken one.

4

10 min · Unblock 1:1 queue

If the Q&A doesn’t finish, coach stays for a 1:1 queue. DM the coach with [help] in #trader-lab if you need slot priority.

Section 07

Today’s deliverable.

A phone screenshot of the panel rendering against your seed data. Positions table visible, recent-fills feed visible, kill-switch button visible, panel token gating in place. Tomorrow this same view will show your first real fill. Today is the foundation.

Day 3 · Deliverable

Post in #trader-lab.

Phone screenshot of your panel rendering against the seed data, positions table + recent-fills feed visible.

Post it in #trader-lab with a [D3] tag at the start of the caption.

Caption: “[D3] Day 3 done. Panel up against seed data. URL: [your /panel/ path]. Mid-week call: [attended / watching recording]. Snags: [none / brief].”

If the panel was tricky to install, post the snag too. Lead with [help] if you need the coach’s eyes first, Day 4 depends on a working panel.

Day 3 complete · mid-week call tonight

Panel up.

A token-gated control panel is rendering on your phone, mounted on top of yesterday’s deployed FastAPI service, reading from the volume at /app/data. The bonus pack is on your laptop. The kill-switch button works.

01

A bonus-pack control_panel.py + control_panel.html wired into your Day 2 deploy, with PANEL_TOKEN, AGENT_LOG, POSITIONS_PATH, and KILL_SWITCH set on Railway.

02

Hand-written seed JSON on the persistent volume (3 positions + 10 fills), the panel rendering it proves the data path works end-to-end before tomorrow’s real fill.

03

A phone-bookmarked URL with a [D3] screenshot in #trader-lab that proves your panel is the live view of your bot, and the kill button is one tap from anywhere.

Tomorrow: Place your first programmatic order. The fill shows up in the panel you built today, on your phone, in seconds. Visceral coupling.

Mid-week cohort call tonight · Day 4 unlocks tomorrow at 9am local