01Overview
Your submission is a matching engine. The platform sends you orders; you respond with acks and fills. Lower latency, higher throughput, and lower error rate score higher. The platform measures both the wall-clock time of submit() and the correctness of fills under price-time priority.
02The submit() contract
Same shape across every language. Your engine is a container exposing POST /submit that takes an order and returns {acks, fills} — see the Engine contract below.
JavaScript template
// orderbook.js: minimal valid JS submission
const bids = new Map(); // price → [{id, qty}]
const asks = new Map();
let nextFillId = 1;
function bestPrice(book, isBid) {
if (book.size === 0) return null;
let b = null;
for (const p of book.keys()) {
if (b === null || (isBid ? p > b : p < b)) b = p;
}
return b;
}
function match(order) {
const opp = order.side === 'buy' ? asks : bids;
const fills = [];
let qty = order.qty;
while (qty > 0) {
const px = bestPrice(opp, order.side === 'sell');
if (px === null) break;
const crosses = order.type === 'market'
|| (order.side === 'buy' ? px <= order.price : px >= order.price);
if (!crosses) break;
const q = opp.get(px);
while (q.length && qty > 0) {
const rest = q[0];
const m = Math.min(qty, rest.qty);
qty -= m; rest.qty -= m;
fills.push({ id: nextFillId++, price: px, qty: m, makerId: rest.id });
if (rest.qty === 0) q.shift();
}
if (q.length === 0) opp.delete(px);
}
return { qty, fills };
}
module.exports.submit = (order) => {
if (!order || !(order.qty > 0)) return { acks: [{ id: order?.id, status: 'rejected' }], fills: [] };
if (order.type === 'cancel') {
// implement cancel handling here…
return { acks: [{ id: order.id, status: 'cancelled' }], fills: [] };
}
const { qty: remaining, fills } = match(order);
if (order.type === 'limit' && remaining > 0) {
const book = order.side === 'buy' ? bids : asks;
if (!book.has(order.price)) book.set(order.price, []);
book.get(order.price).push({ id: order.id, qty: remaining });
}
return { acks: [{ id: order.id, status: 'accepted', filled: order.qty - remaining }], fills };
};
Python template
Python runs as real CPython compiled to WASM (Pyodide). Cold-start is ~5s; once loaded each submit() typically runs in 100–500µs.
# orderbook.py: minimal valid Python submission
bids = {} # price -> [(id, qty), ...]
asks = {}
_fill_id = [0]
def best_price(book, is_bid):
if not book: return None
return max(book) if is_bid else min(book)
def match(order):
opp = asks if order["side"] == "buy" else bids
fills, qty = [], order["qty"]
while qty > 0:
px = best_price(opp, order["side"] == "sell")
if px is None: break
crosses = order["type"] == "market" or (
order["side"] == "buy" and px <= order["price"]) or (
order["side"] == "sell" and px >= order["price"])
if not crosses: break
q = opp[px]
while q and qty > 0:
rid, rqty = q[0]
m = min(qty, rqty)
qty -= m; q[0] = (rid, rqty - m)
_fill_id[0] += 1
fills.append({"id": _fill_id[0], "price": px, "qty": m, "makerId": rid})
if q[0][1] == 0: q.pop(0)
if not q: del opp[px]
return qty, fills
def submit(order):
if not order or order.get("qty", 0) <= 0:
return {"acks": [{"id": order.get("id"), "status": "rejected"}], "fills": []}
if order["type"] == "cancel":
return {"acks": [{"id": order["id"], "status": "cancelled"}], "fills": []}
remaining, fills = match(order)
if order["type"] == "limit" and remaining > 0:
book = bids if order["side"] == "buy" else asks
book.setdefault(order["price"], []).append((order["id"], remaining))
return {
"acks": [{"id": order["id"], "status": "accepted", "filled": order["qty"] - remaining}],
"fills": fills,
}
WebAssembly ABI (C++/Rust/Go/Zig)
Compile your engine to a .wasm module that exports five symbols. Wire format: JSON-over-linear-memory. Compatible with emcc, wasm-bindgen, TinyGo, AssemblyScript, Zig.
// Required exports
memory: WebAssembly.Memory
alloc(n: i32) -> i32 // allocate n bytes in wasm linear memory
free(ptr: i32) -> void // matching free
submit_bytes(ptr: i32, len: i32) -> i32 // returns response ptr
submit_bytes_len() -> i32 // length of last response
// Optional
env.log_str(ptr: i32, len: i32) // platform logging hook
env.now_ns() -> i64 // monotonic clock
03Order schema
Every call to submit() receives a single order object:
{
"id": 42, // monotonic uint64
"side": "buy" | "sell",
"type": "limit" | "market" | "cancel",
"price": 10000, // integer ticks (price×100); ignored for market
"qty": 5,
"ts": 1735689600000000, // µs since epoch
"targetId": 17 // only on cancel
}
Return value:
{
"acks": [{ id, status, filled, remaining, message? }],
"fills": [{ id, price, qty, takerId, makerId }]
}
04Scoring formula
Composite score per run (0–100):
// each component is normalised to [0, 100]
speedScore = max(0, 100 - p99_µs / 5) // 0µs = 100, 500µs = 0
throughputScore = min(100, tps / 30_000) // 3M ops/s = 100
correctnessScore = max(0, 100 - err_rate × 5000) // 2% err = 0
composite = 0.40 × speedScore
+ 0.40 × throughputScore
+ 0.20 × correctnessScore
Weights are tunable by an operator (see the Judge Console). The platform recomputes scores using new weights when a re-score is triggered.
05Engine contract
Your engine is a container exposing POST /submit (port 9001 by convention) and GET /healthz. Prices are integer ticks (price × 100) — no floats in the matching path.
POST /submit
$ curl -X POST http://<engine>:9001/submit \
-H "Content-Type: application/json" \
-d '{"id":1,"clientId":7,"side":"buy","type":"limit","price":10000,"qty":5}'
// 200 OK
{"acks":[{"id":1,"status":"filled","filled":5}],"fills":[...]}
type ∈ limit · market · cancel (cancel targets a resting targetId). side ∈ buy · sell. GET /healthz returns {"status":"ok"}.
06Live telemetry (platform WebSocket)
While a run is in flight the platform streams rolling metrics over a WebSocket — this is exactly what the Console dashboard consumes.
ws://<host>:8080/ws/runs/<runId>
// every 1s while running
{ "type":"metrics", "orders":.., "tps":.., "avgLatMs":.., "errPct":.. }
// on finish
{ "type":"final", "p50":..,"p99":..,"p99_9":..,"p99_99":..,"tps":..,"score":.. }
07Run & leaderboard REST
GET /api/leaderboard // ranked teams: score, p50, p99, tps
POST /api/runs // {submissionId,profile,durationSec,botsPerFleet,targetRatePerBot}
GET /api/runs/<id> // status + composite score
POST /api/runs/<id>/baseline // promote a regression baseline
GET /api/runs/<id>/regression // diff vs baseline → OK | REGRESSION
08Sandbox limits
cpu: 1 vCPU (pinned, no oversubscription)
memory: 256 MB hard cap (RLIMIT_AS + cgroup memory.max)
disk: 100 MB ephemeral, mounted RW only on /tmp
network: inbound only · gateway-mesh only
syscalls: seccomp default-deny + curated allowlist
build budget: 60s · failures recorded
run budget: 300s per stress test
09Codebase map
For anyone (human or agent) editing this platform, here's what each file does:
/
├─ index.html // public landing page
└─ platform/
├─ dashboard.html // developer home: subs + runs + team
├─ submit.html // upload + hash + sandbox-build · multi-language
├─ run.html // stress test · runtime workers · profiles · feed
├─ correctness.html // validation suite (17 tests · 6 categories)
├─ leaderboard.html // public rankings + CSV export
├─ architecture.html // system diagram
├─ judge.html // admin · re-score · DQ · platform state
├─ docs.html // you're reading it
└─ assets/
├─ tokens.css // design tokens - colors, type, spacing
├─ platform.css // shared layout + components
├─ store.js // localStorage + IDB + BroadcastChannel
├─ layout.js // sidebar/topbar injector + toast helper
├─ engine.js // reference matching engine (price-time)
├─ bot-worker.js // fallback in-process bot fleet
├─ tdigest.js // streaming percentiles (p50/p99 sketch)
├─ rng.js // seeded RNG · xoshiro128** · deterministic
├─ runtime.js // multi-language runtime adapter (main thread)
├─ runtime-js.js // JS runtime worker
├─ runtime-py.js // Python via Pyodide worker
├─ runtime-wasm.js // .wasm instantiate worker
├─ runtime-judge0.js // remote Judge0 CE adapter
├─ correctness.js // validation tests · severity-weighted score
└─ market-feed.js // optional Binance WS for realistic flow
10Adversarial test inputs
The correctness suite probes these: your engine must handle them without crashing or producing impossible output. Run correctness.html to see the full list.
// Inputs your engine WILL receive in adversarial mode
{ qty: -5 } // negative quantity
{ qty: 0 } // zero quantity
{ qty: 1e15 } // astronomical quantity
{ price: NaN } // not-a-number price
{ price: Infinity }
{ type: "fok" } // unknown order type
{ type: "cancel", targetId: 99999 } // cancel of unknown id
// All must be rejected gracefully · no crashes · no phantom resting orders