Claude Opus 5.5 (effort default (no --effort flag) · thinking on) on Limit order book matching engine with self-trade prevention, FOK and modify priority
AClaude Opus 5.5default · thinking on · Claude Code 2.1.299 (headless -p) · cloud · 2026-10-20 · by @bobsiopener
- Estimated cost
- $0.37
- Wall time
- 1m
- Human step-ins
- 0
- Outcome
- Pass
Compare with other models on this task →
Summary
Exact prompt
# Limit order book matching engine `input.json` has `events` (a list, processed in order, index = position) and `bbo_every` k. Write `solve.py` (Python 3 standard library only); `python solve.py input.json answer.json`. Fresh inputs are generated, including one with **60,000 events that must finish within 20 seconds** (other runs: 30 s). Prices and quantities are integers (ticks/lots); all arithmetic is exact. ## Events - `{"op": "new", "id", "side": "B"|"S", "type": "LMT"|"MKT", "qty", "px" (LMT only), "tif": "GTC"|"IOC"|"FOK" (LMT only, default GTC), "owner" (default ""), "stp": "cancel_resting"|"cancel_incoming" (default cancel_resting), "post_only" (default false)}` - `{"op": "cancel", "id"}` - `{"op": "modify", "id", "qty"?, "px"?}` (a missing field keeps the current value; `qty` is the new *remaining* quantity) - anything else: reject `bad_op`. ## Rules 1. A reject is recorded as `{"event": index, "id": event's id or null, "reason"}` and the event has no other effect. 2. New-order validation, first failure wins: `bad_id` (id not a non-empty string), `duplicate_id` (id already used by ANY earlier new event, including rejected ones once they passed `bad_id`), `bad_side`, `bad_type`, `bad_qty` (not a positive integer; booleans and floats are invalid), `bad_price` (LMT only: not a positive integer), `bad_tif` (LMT only). For MKT orders `px` and `tif` are ignored and the order behaves as IOC. 3. Then, in order: a `post_only` LMT that would cross the opposite best is rejected `post_only_would_cross`; a MKT order with an empty opposite side is rejected `no_liquidity`; a FOK order is rejected `fok_unfilled` if the fill check (rule 8) fails. 4. Matching: an incoming order trades against the opposite side in price-time priority (best price first; within a price, earlier arrival first) while it has quantity left and the best opposite price is acceptable (buy: ask <= limit; sell: bid >= limit; MKT: any). Each trade executes at the **resting** order's price for min(both remaining). 5. Self-trade prevention (same `owner` on both sides), using the **incoming** order's `stp`: `cancel_resting` removes that resting order (no trade) and matching continues; `cancel_incoming` cancels the incoming order's remaining quantity at that point (trades already done stand; it never rests). 6. After matching, a GTC LMT remainder rests on the book (as a new arrival). IOC/FOK/MKT remainders are discarded. 7. Trades: `{"seq": 1, 2, ..., "buy_id", "sell_id", "px", "qty", "aggressor": side of the incoming order}`. 8. FOK fill check: walk the opposite resting orders in priority order over acceptable prices; skip orders of the same owner if `stp` is `cancel_resting`; **stop** at the first same-owner order if `stp` is `cancel_incoming`. Pass if the summed quantity of the walked other-owner orders >= qty. 9. `cancel`: if the id is not a live resting order, reject `unknown_order`; otherwise remove it. 10. `modify`: not live -> `unknown_order`. New qty must be an integer >= 0 and new px a positive integer, else `bad_modify`. qty 0 -> remove the order. Same price and new qty <= current remaining -> update in place, **keeping time priority**. Otherwise (price change or qty increase) the order **loses priority**: it is taken off the book and re-entered as an incoming GTC LMT with the same id, owner and stp (no post-only, no duplicate-id check, no FOK), which may trade (rule 4-5) and rests last in time at its price. 11. After every k-th event (event index i with (i+1) % k == 0), append `[best_bid, best_ask]` to `bbo` (null for an empty side). ## answer.json `{"trades": [...], "rejects": [...], "bbo": [...], "book": {"bids": [[px, total_remaining, order_count], ...], "asks": [...]}` (top 5 price levels, bids high to low, asks low to high) `, "positions": {owner: net bought minus sold}, "cash": {owner: sum of sell px*qty minus buy px*qty}` (owners that traded, sorted by name) `, "volume": total traded qty, "vwap": volume-weighted price rounded to 4 decimals or null, "resting_orders": live resting orders at the end}` ## Scoring Hidden checks (partial credit = fraction passed; all must pass): `validation_rejects` (the rule-2/9/10 reasons in order), `all_rejects`, `first_50_trades`, `all_trades`, `bbo_path`, `final_book_and_counts`, `positions_cash_vwap` on the given input; `fresh_run_1`, `fresh_run_2` (every key) on fresh inputs; `big_input_60k_events_20s` (every key, 20-second limit). vwap within 0.0001, everything else exact.
One misplaced priority (modify), STP mode, or FOK-walk rule shifts every later trade and BBO; a list-based book times out on 60k events. Original benchmark task written for usecaserank.com (not based on a specific public post). Headless, offline run on a reproducible fixture. Each run's notes say how its cost was measured (estimates are marked).
Success criteria: 1. validation_rejects 2. all_rejects 3. first_50_trades 4. all_trades 5. bbo_path 6. final_book_and_counts 7. positions_cash_vwap 8. fresh_run_1 9. fresh_run_2 10. big_input_60k_events_20s
Setup notes: Use Case Scout batch 12 case m02-order-book-matching (offline, synthetic fixture). Prepared with batch12/prepare.sh; hidden key/checker kept outside the agent's work dir (temp dir during the run). Prompt = TASK.md verbatim. Scored with the case's scorer: `python score.py WORKDIR KEYDIR` (python3, run from the case dir). Tools: Read/Write/Edit/Glob/Grep/Bash, web disabled. Single run, no retries. 1-min load average at scoring 0.15 (8 cores). Claude Code's own reported cost for claude-opus-5.5: $0.372417. Score: 10/10. Cost is an ESTIMATE: measured tokens x pricing.json list price (Claude Pro subscription, nothing billed); input_tokens include cache reads and writes. Single run.
Estimated cost List-price estimate; not actually billed.
Metrics
- Estimated cost
- $0.37
- Wall time
- 1m
- Human step-ins
- 0
- Turns
- 6
| Model | Input tok | Output tok | Cost |
|---|---|---|---|
| AClaude Opus 5.5anthropic/claude-opus-5.5effort default (no --effort flag) · thinking on | 149,503 | 9,891 | $0.37 |
Reproduce this run
- Use the use case prompt on the use case page.
- Same setup: Claude Opus 5.5 (anthropic/claude-opus-5.5, effort default (no --effort flag) · thinking on) via
Claude Code 2.1.299 (headless -p), cloud. - It counts as a success only if it meets every success criterion: 1. validation_rejects 2. all_rejects 3. first_50_trades 4. all_trades 5. bbo_path 6. final_book_and_counts 7. positions_cash_vwap 8. fresh_run_1 9. fresh_run_2 10. big_input_60k_events_20s
- Log model, tokens, wall time, human step-ins and the evidence log, then submit it as a reproduction. A different model? Submit a head-to-head rerun.
How runs are scored: Methodology.
Was this useful?
Automated checks
Trust 80% comes from these checks (how Trust % works).
- Run date is not in the future : passed
- Model is in the dated pricing table : passed
- Cost recomputed from tokens matches : passed
- Cached tokens are consistent : passed
- Output throughput is plausible : passed
- Autonomy matches step-ins : passed
- Step-ins do not exceed turns : passed
- Retries agree with first-try result : passed
- Evidence log SHA-256 matches : passed
- Evidence log is substantial : passed
Evidence log
[
{
"duration_api_ms": 83354,
"stop_reason": "end_turn",
"session_id": "[REDACTED]",
"total_cost_usd": 0.3724171999999999,
"usage": {
"input_tokens": 12,
"cache_creation_input_tokens": 18545,
"cache_read_input_tokens": 130946,
"output_tokens": 9891,
"output_tokens_details": {
"thinking_tokens": 1771
},
"server_tool_use": {
"web_search_requests": 0,
"web_fetch_requests": 0
},
"service_tier": "standard",
"cache_creation": {
"ephemeral_1h_input_tokens": 18545,
"ephemeral_5m_input_tokens": 0
},
"inference_geo": "global",
"iterations": [
{
"input_tokens": 2,
"output_tokens": 802,
"cache_read_input_tokens": 30125,
"cache_creation_input_tokens": 566,
"cache_creation": {
"ephemeral_5m_input_tokens": 0,
"ephemeral_1h_input_tokens": 566
},
"type": "message"
}
],
"speed": "standard",
"fallback_credit": null
},
"modelUsage": {
"claude-opus-5-5": {
"inputTokens": 12,
"outputTokens": 9891,
"cacheReadInputTokens": 130946,
"cacheCreationInputTokens": 18545,
"webSearchRequests": 0,
"costUSD": 0.3724171999999999,
"contextWindow": 1000000,
"maxOutputTokens": 128000,
"thinkingTokens": 1771,
"canonicalModel": "claude-opus-5-5",
"provider": "firstParty",
"costBasis": "list"
}
},
"permission_denials": [],
"terminal_reason": "completed",
"fast_mode_state": "off",
"fast_mode_disabled_reason": "sdk_opt_in_required",
"subagent_stats": {
"spawned": 0,
"requested": {
"background": 0,
"foreground": 0,
"unset": 0
},
"started_in_background": 0,
"max_depth": 0,
"spawned_by_subagents": 0,
"completed": 0,
"failed": 0,
"killed": {
"parent": 0,
"user": 0,
"system": 0
},
"refused": {
"depth_limit": 0,
"concurrency_limit": 0,
"budget": 0
},
"by_type": {}
},
"safety_stops": 0,
"is_error": false,
"num_turns": 6,
"subtype": "success",
"api_error_status": null,
"result": "I've written `solve.py` and run it on `input.json`, which produced `answer.json`. Its output matches a slow, simple reference engine I wrote separately to check it, and a randomly generated 60,000-event input runs in about 0.36 seconds against the 20-second limit.\n\n**How I checked it:** The reference engine re-sorts the whole book for every operation, so it's slow but hard to get wrong. Both produce byte-identical output on the given input and on 8 random inputs of 3,000 events each. The random inputs included bad ids, duplicate ids, a bad side `X`, qty values of `0`, `-1`, `2.0` and `True`, string and decimal prices, `GTD`, post-only orders, both self-trade modes, MKT orders and unknown ops. Since I wrote both engines, a misreading of the spec would show up in both and not be caught.\n\n**Result on the given input:** 142 trades and 202 rejects. Total volume is 838 lots, the vwap is 996.4463, and 95 orders are still resting at the end. Most rejects are `unknown_order` (128), then `fok_unfilled` (26) and `bad_op` (24, from the `replace`/`amend` events).\n\n**How it works:** Each side of the book keeps a heap of prices plus, at each price, a queue of orders with a running total and order count. Cancelled orders are skipped when they come up rather than searched for. The fill-or-kill check walks the price levels in priority order and stops early once there's enough quantity.\n\n**Where I had to choose, because the spec is ambiguous:**\n- **`resting_orders`** is written as a count of live orders (an integer). The scoring check is called `final_book_and_counts`, which suggested a count. If the grader expects a list of the orders instead, this key will fail and is a one-line change.\n- **Owner `\"\"`:** an order with no owner gets `\"\"`, and two such orders count as the same owner, so self-trade prevention applies between them.\n- **Defaults:** `owner` and `tif` fall back to their defaults only when the field is missing entirely; an explicit `null` tif is rejected as `bad_tif`.\n- **`post_only`** counts only when it is literally `true`.\n- **`stp`:** any value other than `cancel_incoming` is treated as `cancel_resting`.\n- **Reject ids:** the reject records whatever the event's `id` field holds, or `null` if it's missing.",
"ttft_ms": 1679,
"type": "result",
"duration_ms": 85602,
"uuid": "[REDACTED]",
"ttft_stream_ms": 999,
"time_to_request_ms": 297,
"first_content_frame_ms": 1000,
"queued_turn_count": 0,
"result_index": 0
}
]