ESP32-S3 Bench Guide
ESP32-S3 N16R8 bench guide: live pinout, lessons, simulators and the bench log.
An AI-native market laboratory: simulated traders, a real limit order book, and glass-box strategies.
Translation pending
EducationTypeScript · CSSGitHub @matr-botOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
AI-native market lab: simulated traders in a real limit order book
Translation pending
Taken from the repository README
Loading the full README. The saved excerpt is shown below.
An AI-native market laboratory for learning how markets and trading strategies actually work.Read the full README ↗An AI-native market laboratory for learning how markets and trading strategies actually work.
Live demo: marketlab-nine.vercel.app
Problem. Finance students learn market mechanics (order books, liquidity, slippage, panics) from textbooks and from charts of prices that have already happened. Neither lets them touch the market. Coding platforms such as QuantConnect let them test strategies against history, but only after they can program. Even there, the student's own trades can never move the price. So students go from theory to code without ever seeing why prices move or why a strategy that looks good on paper loses money when it actually executes.
Thesis. When prices emerge from a crowd of simulated traders in a real limit order book, a student can see cause and effect. They can change one thing, such as a headline, a strategy, or how much liquidity market makers provide, and watch the market respond. If every experiment can also be opened up into its rules, formulas and code, students build real intuition for market microstructure before they can code. They also arrive at quant platforms already understanding what their code will do.
Bloomberg shows students what markets did. QuantConnect teaches students to code strategies. MarketLab lets students experiment with how markets work before they can code — then exposes the math and code behind every experiment.
Who it's for: college finance and economics professors, trading labs, investment clubs, and college students interested in quant or hedge fund careers.
What it is not: it does not predict real markets and does not trade real money.
A crowd of simulated traders (market makers, noise traders, momentum and value traders, panic sellers, whales) trades in a continuous double-auction order book. Prices are not scripted or drawn from a formula. They come from those trades. On top of that market, a student can:
What sets it apart: the student's own orders move the price (market impact), they can invent any counterfactual event, and the rules, formulas and code behind every experiment are shown.
Browser UI (Next.js)
├─ Web Worker: Simulation Engine (pure TypeScript, no network)
│ Sim Clock → Agents → MarketRegistry (one OrderBook per ticker) → Matching Engine
│ → Event Stream (trades, quotes, fills) → Analytics
└─ /api/interpret (Next.js route) → LLM → JSON validated with Zod → engine parameters
| Rule | Why |
|---|---|
| Prices and cash are integer cents, never floats | Exact P&L and slippage; no rounding drift |
| Price-time priority, continuous double auction | How real exchanges match orders |
| Seeded RNG for all randomness | Same seed + same inputs = same result, which makes what-if reruns fair |
One OrderBook per ticker in a MarketRegistry | Ready for more than one stock from day one |
src/engine has zero React/DOM imports | Testable in isolation; enforced by ESLint |
| Every fill records each side's arrival quote and limit price | Slippage is exact: intended price (the arrival mid) vs executed price |
The engine boundary is checked automatically. An ESLint rule in eslint.config.mjs fails
npm run lint if anything in src/engine/ imports React, React DOM, Next.js or UI code, or
uses window/document. A Vitest test (src/engine/boundary.test.ts) checks that the rule
itself keeps working.
Engine steps 1–5 ✅ done (matching engine, seeded randomness and sim clock, noise traders and
the simulation loop, realized volatility, Avellaneda–Stoikov market makers), the market is
alive on the live site, and headlines move it: type FED in the command bar and watch value
traders reprice, panic sellers cascade and market makers pull back. What exists today:
Headline shocks: fair value jumps, value traders carry the news into the price, panic sellers cascade (Granovetter thresholds) and value traders buy the overshoot back. Four offline headlines (FED, CEO, BEAT, DOWNGRADE) run with no network call, and each one's first-minute P&L by trader type is recorded (market makers lose to informed traders: adverse selection)
A 77-trader crowd: 40 noise traders, 2 market makers, 15 value traders, 20 panic sellers
A terminal-style UI on marketlab-nine.vercel.app: the
market is already trading when the page loads. Status bar (last price, change, volume, sim
clock, seed), a scrolling trade ticker, a candlestick price chart (GP), time & sales
(TAPE) and the order book (BOOK), every number from the engine
The whole simulation runs in a Web Worker; the page pulls one coalesced frame per animation frame, and the real clock only decides how many ticks run, never what happens in them
OrderBook: integer-cent prices, tick size, price-time priority, add / cancel / partial
fill, per-owner orders and cancel-all, best bid/ask, spread and depth. It is never crossed,
and rejected orders come back with a reason code instead of throwing.
Matching engine: limit and market orders, sweeps across price levels, partial fills, self-trade prevention, and a frozen fill log recording both sides' agent type, limit price and arrival quote, so slippage (vs the arrival mid) and "who moved the price?" are exact
Seeded randomness: the same seed gives the same market in every browser. One seeded
generator (xoshiro128**, verified against the authors' reference C code), an independent
named stream per agent, and our own deterministic ln/exp/pow, since browsers may
compute Math.log and friends differently
Sim clock (100 ms ticks from 09:30:00.000) and Poisson order arrivals with exact timestamps
A living market: 40 zero-intelligence noise traders trading from $187.00, with the same seed giving a byte-identical market (the whole fill log is fingerprinted and pinned)
The panels in the UI say which week they go live. They show no fake market data.
The judges are software engineers, so the engine is tested the way exchange software should be: not just "does it work on my example" but "can any small bug slip past the tests?"
| Check | Result |
|---|---|
| Unit and property tests (Vitest) | 720 passing across 29 files |
| Browser smoke tests (Playwright, in CI) | Production build: the page loads and prices move; FED from the command bar moves the market with no network call; FED typed 30 times never freezes the page |
| Randomized shadow-model comparison | Order book and matching engine, 5 seeds × 3,000 operations each, full state compared after every step |
Mutation score (Stryker) on src/engine | 95.69%: 2,019 of 2,110 mutants detected (D-050) |
| Same seed → identical market | The whole fill log and final book of a 10-minute, 40-trader market are fingerprinted and pinned; seed 188 differs |
| Same seed → same numbers in every browser | Random generator matches the reference C code exactly; ln/exp bits pinned over 226,000+ inputs; inexact Math functions banned by lint and by a runtime test |
| Throughput benchmark | ~1.5 million matching-engine operations per second with real fills |
Shadow models. src/engine/testing/shadow.ts contains a deliberately naive reference order
book and matching engine: a flat array where every question is answered by filtering and
sorting from scratch. They share no code with the real engine, not even validation or limits,
so the two can only agree if both are correct. A seeded random generator drives the real and
shadow versions through the same operations and compares everything observable after each step:
every trade (price, size, both sides' agent types, limit prices and arrival quotes), best prices,
spread, depth, every queue in price-time order, every order ever created, and every owner's
orders.
Randomized, but reproducible. Every run uses fixed seeds, so a failure always reproduces. The generator mixes normal orders with the cases that break exchanges: orders that cross the spread, market orders that sweep several levels or drain a side completely, self-trades, every kind of invalid order, cancels of orders that already filled or never existed, partial and full fills, cancel-all, and maximum-size orders. After every order it also checks rules that must always hold: shares in = filled + resting + cancelled, no trader ever trades with itself, limit prices are respected, and the book is never crossed. A coverage guard fails the test if any case happens fewer than 5 times per seed, or if the book or the trade count stays too small, so the random test can never quietly stop testing anything. We also planted seven realistic bugs by hand (one in the order book, six in the matching engine); every one was caught.
Determinism across browsers. The JavaScript spec lets each browser compute Math.log,
Math.exp, Math.pow and the trig functions slightly differently, so the same seed could give a
different market in Safari than in Chrome. The engine therefore uses its own ln, exp and pow
(ports of the fdlibm library, built only from operations every browser must compute exactly), and
the random generator is checked against the authors' reference C program
(scripts/reference/xoshiro128ss.c). Two layers keep it that way: an ESLint rule bans every route
to the inexact functions, the unseeded Math.random and the real clock; and a runtime test
replaces all of them with functions that throw, reruns the engine's full random workloads, and
requires identical results. We confirmed the runtime test catches code the lint rule cannot see.
Mutation testing. Stryker makes hundreds of small deliberate bugs in the engine (flipping <
to <=, deleting a line, changing a constant) and checks that some test fails for each one.
2,019 of 2,110 are caught. We reviewed the survivors one by one: they are safety checks that can
only run if the engine is already broken, comparisons that only differ when a random time lands
exactly on a boundary (probability ≈ 0), or alternate math paths that give bit-identical results.
Benchmark. 100,000 operations per run on an Apple Silicon MacBook Air:
| Scenario | Operations / second |
|---|---|
| Matching engine: limit + market + cancel mix (~33,000 fills) | ~1.5 million |
| Order book: mixed add/cancel, ~200 price levels | ~4.3 million |
| Order book: mixed add/cancel, ~5,000 price levels | ~3.3 million |
| Order book: 100 market makers cancel and requote every tick | ~7.9 million |
A busy tick (hundreds of agents, about 1,000 orders through the matching engine) costs about 0.65 ms, roughly 25× headroom inside a 16 ms frame for a smooth 60 fps simulation.
Requires Node.js 22+.
npm install
npm run dev # http://localhost:3000
| Script | What it does |
|---|---|
npm run dev | Start the dev server |
npm test | Run the Vitest suite once |
npm run test:watch | Run Vitest in watch mode |
npm run lint | ESLint, including the engine import boundary |
npm run typecheck | Generate Next.js route types, then TypeScript type check (works on a fresh clone) |
npm run test:mutation | Stryker mutation testing on src/engine (HTML report in reports/) |
npm run test:e2e | Playwright smoke test (needs npm run build first) |
npm run bench | Order book throughput benchmark |
npm run build | Production build |
src/
app/ Next.js App Router: layout, page, global theme
components/ UI: Panel, and terminal/ (status bar, ticker, GP chart, TAPE, BOOK, useMarket)
worker/ The simulation Web Worker and its message protocol
engine/ Simulation engine: pure TypeScript, no React/DOM (lint-enforced)
orderBook.ts Limit order book (price-time priority)
matchingEngine.ts Matching engine: limit/market orders, fills, arrival quotes
marketRegistry.ts One matching engine per ticker
validation.ts Order validation shared by the book and the engine
types.ts Shared types and reason codes
rng.ts Seeded random numbers (xoshiro128**), named streams per agent
detMath.ts Deterministic ln / exp / pow (same bits in every browser)
simClock.ts Sim time: 100 ms ticks from 09:30:00.000
arrivals.ts Poisson order arrivals per agent
simulation.ts The loop: each tick, agents act at their arrival times
price.ts toTick: the only place a computed price becomes cents
agents/agent.ts The agent interface (act at arrival times, read-only view)
agents/noiseTrader.ts Zero-intelligence noise traders
agents/marketMaker.ts Avellaneda–Stoikov market makers
demoMarket.ts The market every page load opens on (seed 187, 10-minute warm-up)
feed.ts Coalesced frames for the page, and the tick pacer
volatility.ts Realized volatility of the mid (fast and slow EWMA)
*.test.ts Unit, edge-case and limit tests
*.shadow.test.ts Randomized comparison against the naive reference models
orderBook.bench.ts Throughput benchmark
boundary.test.ts Checks the ESLint boundary and determinism rules themselves
determinism.test.ts Runtime backstop: reruns the workloads with banned globals stubbed
testing/ Test-only: shadow models, shared random workloads, fingerprints
scripts/reference/xoshiro128ss.c Reference C generator the RNG tests are checked against
lib/ Shared code: display formatting, the page's market state (Zod schemas next)
e2e/ Playwright smoke test
The engine is strong; the last week is about making everything visible. Each day ends with a working build on the live site.
| Day | Deliverables |
|---|---|
| Done | Repo, deploy, layout shell; order book, matching engine, seeded randomness + sim clock, noise traders; realized volatility + Avellaneda–Stoikov market makers (in review) |
| Sun 10/18 ✅ | Web Worker + terminal UI (status bar, ticker, price chart, time & sales, order book basics) + market alive on load. Milestone: prices moving on the live site |
| Mon 10/19 ✅ | Value traders (fair value), panic sellers (threshold cascade), headline shock = a fair-value jump |
| Tue 10/20 | AI interpret route for headlines → clamped, editable parameters; headline input; desk-chat narrator (deterministic); "who moved the price?" attribution |
| Wed 10/21 | Strategy agent (plain-English strategy via the same route) + glass box + manual buy/sell |
| Thu 10/22 | Execution report (slippage split into spread and impact, P&L), tuning |
| Fri 10/23 | Feature freeze, bug bash, demo script, backup video |
| If time | Sharpe ratio and max drawdown in the execution report |
| Cut unless ahead | Momentum traders, whale, missions, full depth view, realism panel, Learn/Pro modes, rewind, what-if reruns, ask-the-AI, shortcut strip |
Never cut: the market moving on screen, the headline reaction, "who moved the price?", the strategy agent + glass box, the execution report.
How each day runs: one short plan, build, then an independent code review (Codex) at the end
of the day. High and medium findings are fixed immediately; low ones go to
docs/LATER.md. Mutation testing runs on the engine once a day before
committing. CI runs typecheck, lint, unit tests and a browser smoke test (page loads, prices
move, no console errors) on every push and pull request.
Built for the Busch School AI Vibe Coding Contest.
Realized volatility from the mid price (never trade prices, which bounce between bid and ask), sampled every 5 s of sim time, with a fast (30 s) and a slow (120 s) moving average
Two Avellaneda–Stoikov market makers: quotes around an inventory-adjusted price, a spread that widens with volatility, smaller sizes under stress, post-only quotes and inventory limits. Profitable against the noise crowd on 6 of 6 runs, including seeds never used to tune them
720 unit tests, three browser smoke tests in CI, shadow-model comparison, and 96% mutation score (see Testing)
Engine boundary and determinism rules, enforced by ESLint and checked at runtime