Reported September 2026
IMC Tradingsimulation

Pro-Rata Order Book

Reported by candidates from IMC Trading's online assessment. Pattern, common pitfall, and the honest play if you blank under the timer.

Get StealthCoderRuns invisibly during the live IMC Trading OA. Under 2s to a working solution.
Founder's read

IMC Trading reportedly put the Pro-Rata Order Book in front of candidates in September 2026, and the input size is the first thing to read. Up to 50000 operations, plus caps on orders inspected and fills emitted, means you can't rescan the whole book on every MATCH. It's a simulation with sorted price levels and per-level queues, and the pro-rata rounding rule is where people lose points. If you blank mid-assessment, StealthCoder runs invisibly on your desktop and can hand you the structure while the proctor sees nothing. Know the shape before you open the invite.

The problem

Maintain a finite two-sided limit-order book for one asset and execute immediate-or-cancel aggressor requests using pro-rata allocation. Each operation has one of these forms:
["ADD", side, orderId, price, quantity]
["CANCEL", orderId]
["MATCH", side, limitPrice, quantity]
An ADD operation places a resting order at the back of its price level. A CANCEL operation removes the unfilled remainder of the named resting order; an unknown, filled, or already cancelled ID is a no-op.
A MATCH operation is an incoming immediate-or-cancel request. A BUY request visits sell prices from lowest to highest while the price is at most its limit. A SELL request visits buy prices from highest to lowest while the price is at least its limit. Any unmatched aggressor quantity is discarded rather than added to the book.
At one visited price level, let need be the smaller of the remaining aggressor quantity and the total resting quantity at that level. For each resting order with quantity q, first assign floor(need * q / total). Assign any leftover units one at a time in arrival order to orders that still have unfilled quantity. Emit positive fills in arrival order, reduce the resting quantities, and remove fully filled orders. A partially filled resting order keeps its original position.
Return every fill in execution order as "restingOrderId|price|quantity". ADD and CANCEL operations produce no output.

Function
executeProRata(operations: String[][]) → String[]

Examples
Example 1
operations = [["ADD","SELL","s1","100","6"],["ADD","SELL","s2","100","3"],["ADD","SELL","s3","100","1"],["MATCH","BUY","100","5"],["MATCH","BUY","100","3"]]
return = ["s1|100|4","s2|100|1","s1|100|2","s2|100|1"]
The first request allocates base quantities [3,1,0] and gives the leftover unit to s1. The remaining quantities are [2,2,1]. The second request allocates base quantities [1,1,0] and again gives the leftover unit to the earliest eligible order, s1.
Example 2
operations = [["ADD","SELL","s1","99","2"],["ADD","SELL","s2","100","4"],["ADD","SELL","s3","100","2"],["MATCH","BUY","100","5"]]
return = ["s1|99|2","s2|100|2","s3|100|1"]
The request consumes all two units at the better sell price 99. At price 100, the remaining three units split proportionally as two for s2 and one for s3.
Example 3
operations = [["ADD","BUY","b1","101","5"],["ADD","BUY","b2","101","5"],["ADD","BUY","b3","100","8"],["CANCEL","b1"],["MATCH","SELL","100","6"]]
return = ["b2|101|5","b3|100|1"]
Cancellation removes b1. The sell request first fills all five units of b2 at the best buy price, then fills one unit of b3 at the next eligible price.

Constraints
1 <= operations.length <= 50000
Every operation has one of the three forms described above.
side is BUY or SELL.
orderId contains only ASCII letters, digits, hyphens, and underscores, has length from 1 through 40, and does not contain |.
Every ADD order ID is unique and is never reused.
1 <= price, quantity <= 10^6, written as base-10 integers.
The total resting quantity at one price level never exceeds 10^9.
Across all MATCH operations, at most 200000 resting orders are inspected and at most 200000 positive fills are emitted.

Reported by candidates. Source: FastPrep

Pattern and pitfall

Keep two sorted structures, one per side, keyed by price. Each price level holds an arrival-ordered list of orders plus a running total quantity. BUY matches pull the lowest sell price, SELL matches pull the highest buy price, so use a heap or a sorted map. For CANCEL, keep an orderId map to the order and mark it dead, then lazily skip dead entries. At a level, need = min(remaining, total). Give each order floor(need*q/total), then hand leftover units one at a time in arrival order to orders with unfilled quantity left. Use 64-bit math, since need*q can reach about 10^15. The classic pitfall is giving leftovers to orders already fully filled, or reordering a partially filled order. The inspection and fill caps are your promise that walking a level is affordable. StealthCoder is the hedge if the leftover loop or lazy deletion trips you live.

If this hits your live OA and you blank, StealthCoder solves it in seconds, invisible to the proctor.

If this hits your live OA

You can drill Pro-Rata Order Book cold, or you can hedge it. StealthCoder runs invisibly during screen share and surfaces a working solution in under 2 seconds. The proctor sees the IDE. They don't see what's behind it. Built by an Amazon engineer who would have shipped this the night before his JPMorgan OA if he'd had it.

Get StealthCoder

Related leaked OAs

⏵ The honest play

You've seen the question. Make sure you actually pass IMC Trading's OA.

IMC Trading reuses patterns across OAs. Built by an Amazon engineer who would have shipped this the night before his JPMorgan OA if he'd had it. Works on HackerRank, CodeSignal, CoderPad, and Karat.

Pro-Rata Order Book FAQ

How hard is the Pro-Rata Order Book really?+

The algorithm is simple, the details are not. There's no clever trick, just a careful simulation with sorted levels, queues, and rounding. Most failures come from the leftover-unit rule, integer overflow, and cancel handling. Expect to spend your time on edge cases, not on discovering an approach.

What's the trick to the pro-rata allocation step?+

Compute total once for the level, then need = min(remaining, total). Give each order floor(need*q/total) first. Then walk orders in arrival order and give one extra unit to each order that still has unfilled quantity until the leftover runs out. Only emit positive fills, in arrival order.

Which data structures should I use?+

Use a sorted map or heap of prices per side, a queue or list of orders per level with a cached total, and a hash map from orderId to its order for cancels. Lazy deletion of cancelled or filled orders keeps operations cheap and avoids shifting arrays.

Why does overflow matter here?+

Level totals can reach 10^9 and a single order quantity is up to 10^6, so need*q can hit around 10^15. That overflows 32-bit integers. Use 64-bit longs in Java, C++, or similar. Python is safe by default.

How do I prepare for this in 48 hours?+

Write a small order book from scratch twice. Hand-trace Example 1, where leftovers go to s1, and Example 3 with the cancel. Test a cancel of an unknown ID, a MATCH that empties a level, and a MATCH with no eligible price. Those cases catch most bugs.

Problem reported by candidates from a real Online Assessment. Sourced from a publicly-available candidate-aggregated repository. Not affiliated with IMC Trading.

OA at IMC Trading?
Invisible during screen share
Get it