Class HftOrderBook
java.lang.Object
com.quantfinlib.orderbook.HftOrderBook
Venue-grade price-time-priority matching engine: the zero-allocation
sibling of
OrderBook, built the way exchange cores are actually
built. Where OrderBook favors clarity (TreeMap, per-order objects)
for research, this class favors the disciplines of a matching venue:
- Dense integer-tick price ladder — one array slot per tick per
side over a configured band; no tree, no comparator, no boxing.
Prices are
intticks (convert once at the edge, e.g. viamicrostructure.TickSizeSchedule); - Occupancy bitmaps — one bit per price level per side, so
advancing the best price over emptied levels is a word scan
(
Long.numberOfTrailingZeros), not a tree walk; - Pooled intrusive order nodes — every order lives in preallocated parallel primitive arrays, linked into its level's FIFO queue by index; placing, filling and cancelling recycle pool slots and allocate nothing (proven by the allocation-counter test, like every hot-path claim in this library);
- Primitive open-addressing id map — order-id → node lookup by
linear probing over
long[]/int[], with backward-shift deletion so cancel churn never degrades into tombstone soup; - No iterators, no listeners list — a single primitive
HftOrderBook.TradeSinkcallback.
Correctness is enforced two ways: the price-time semantics are asserted
directly, and a model-based equivalence test drives this book and the
reference OrderBook with identical randomized operation streams
and demands identical books — the readable implementation is the
executable specification of this one.
Threading: single-threaded by design, like real matching cores —
one engine thread owns the book; fan orders in via
trading.OrderRingBuffer and trades out via the sink. Rejections
are return codes, never exceptions, because a venue must not unwind its
matching loop over a bad order.
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic interfacePrimitive fill callback: maker is the resting order, taker the incoming one. -
Field Summary
FieldsModifier and TypeFieldDescriptionstatic final longstatic final longstatic final longAccepted-order ids are positive; these are the rejection codes.static final longPost-only order would have crossed the spread and taken liquidity. -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionlongintBest ask in absolute ticks;Integer.MAX_VALUEwhen no asks.longintBest bid in absolute ticks;Integer.MIN_VALUEwhen no bids.booleancancel(long orderId) Cancels a resting order.longlongopenQuantity(long orderId) Open (unfilled, uncancelled) quantity of an order; 0 when gone.longlongResting quantity at an absolute tick (0 when off-band or empty).intOrders currently resting in the book (pool slots in use).intDepth snapshot into caller-provided arrays (absolute ticks + level quantities, best-first): zero allocation.longFill-or-kill: executes the full quantity within the limit price or does nothing at all.longImmediate-or-cancel: a price-limited taker — matches while it crosses, and the remainder expires instead of resting.longsubmitLimit(Side side, int priceTick, long quantity, long timestampNanos) Limit order: matches against the opposite side while it crosses, rests any remainder atpriceTick.longsubmitMarket(Side side, long quantity, long timestampNanos) Market order: matches against the whole opposite book, never rests.longsubmitPostOnly(Side side, int priceTick, long quantity, long timestampNanos) Post-only (add-liquidity-only) limit order: rests atpriceTick, or is rejected withREJECT_WOULD_CROSSwhen it would trade on arrival — the maker-fee-preserving order type.longvoidInstalls the (single) trade callback; call before trading.
-
Field Details
-
REJECT_POOL_FULL
public static final long REJECT_POOL_FULLAccepted-order ids are positive; these are the rejection codes.- See Also:
-
REJECT_OUT_OF_BAND
public static final long REJECT_OUT_OF_BAND- See Also:
-
REJECT_INVALID
public static final long REJECT_INVALID- See Also:
-
REJECT_WOULD_CROSS
public static final long REJECT_WOULD_CROSSPost-only order would have crossed the spread and taken liquidity.- See Also:
-
-
Constructor Details
-
HftOrderBook
public HftOrderBook(int minPriceTick, int maxPriceTick, int maxOrders) - Parameters:
minPriceTick- lowest representable price, in ticks (inclusive)maxPriceTick- highest representable price, in ticks (inclusive)maxOrders- resting-order capacity (pool size, fixed forever)
-
-
Method Details
-
tradeSink
Installs the (single) trade callback; call before trading. -
submitLimit
Limit order: matches against the opposite side while it crosses, rests any remainder atpriceTick. Returns the positive order id on acceptance (also the taker id in emitted trades — even a fully filled order was accepted), or a negative rejection code. Zero allocation. -
submitMarket
Market order: matches against the whole opposite book, never rests. Returns the filled quantity (0 when the opposite side is empty). -
submitIoc
Immediate-or-cancel: a price-limited taker — matches while it crosses, and the remainder expires instead of resting. Returns the filled quantity (0 when nothing crossed). Zero allocation. -
submitFok
Fill-or-kill: executes the full quantity within the limit price or does nothing at all. Returnsquantityon fill, 0 on kill — a killed order emits no trades and consumes no id/counters, like a venue rejecting pre-match. Zero allocation (the liquidity probe walks the same occupancy bitmaps as matching). -
submitPostOnly
Post-only (add-liquidity-only) limit order: rests atpriceTick, or is rejected withREJECT_WOULD_CROSSwhen it would trade on arrival — the maker-fee-preserving order type. Returns the positive order id on acceptance. -
cancel
public boolean cancel(long orderId) Cancels a resting order. False when unknown/already gone — never throws. -
bestBidTick
public int bestBidTick()Best bid in absolute ticks;Integer.MIN_VALUEwhen no bids. -
bestAskTick
public int bestAskTick()Best ask in absolute ticks;Integer.MAX_VALUEwhen no asks. -
bestBidSize
public long bestBidSize() -
bestAskSize
public long bestAskSize() -
qtyAtTick
Resting quantity at an absolute tick (0 when off-band or empty). -
openQuantity
public long openQuantity(long orderId) Open (unfilled, uncancelled) quantity of an order; 0 when gone. -
snapshot
Depth snapshot into caller-provided arrays (absolute ticks + level quantities, best-first): zero allocation. Returns levels written (bounded by the shorter array). -
orderCount
public long orderCount() -
cancelCount
public long cancelCount() -
tradeCount
public long tradeCount() -
restingOrders
public int restingOrders()Orders currently resting in the book (pool slots in use).
-