Order Book
StockMarketABM.OrderBookMod combines price levels into a full limit order book with bid/ask maps, indexed order locations, and utilities for depth inspection and liquidity checks. The core structure, LimitOrderBook, contains:
bids/asks:SortedDict{Price,PriceLevel{LiveOrder}}collections from DataStructures.jl. Their ordering guarantees thatfirst/lastgive the best prices without additional sorting.loc: aDict{OrderId,OrderLoc}mapping each resting order to its side and price so cancellation and consumption can jump directly to the correct level.reg: aDict{OrderId,OrderSpec}storing the full specification of resting orders (including the traded instrument) for logging, audit, and reconstruction.
The public API orchestrates the price levels as follows:
add_order!creates a lightweightLiveOrder, inserts it into the correspondingPriceLevel, updatesloc, and records the fullOrderSpec. Market orders are rejected here because they bypass the book entirely.cancel_order!useslocto find the relevant price level and delegates tocancel!inPriceLevelMod. Empty levels are pruned from the sorted map.best_bid,best_ask, andis_crossedread the extremal entries of the sorted dictionaries to surface top-of-book prices and detect crossed states.get_depthiterates levels in price order, aggregatinglevel_qtyuntil an optionaltoplimit is reached. Bids are traversed in reverse so the output is naturally descending.available_qtyscans the opposite side up to aprice_limit, computing how much liquidity is executable for IOC/FOK orders. An optionalstop_atkeyword lets callers short-circuit once enough quantity is found.consume!removes quantity from the best opposing level, returning both the resting order (as aLiveOrder) and the originalOrderSpecso the matching engine can record fills and residuals.
Together these operations provide the matching engine with O(1) access to the best prices and predictable iteration over depth, while deferring per-price mutations to the specialised PriceLevel queue. Complexity highlights:
add_order!/cancel_order!: amortised O(1) for updates, plus O(log N) when inserting or removing entries from the sorted price maps (N= number of price levels).best_bid/best_ask/is_crossed: O(1) lookups of map extremal entries.get_depth: O(min(top, L)) whereLis the number of levels on the queried side; relies onlevel_qtybeing O(1).available_qty: same O(min(levels, requested span)) behaviour, withstop_atallowing early exit once sufficient liquidity is accumulated.consume!: O(1) to fetch the best level and adjust a single order, with an additional O(1) cleanup when a price level becomes empty.
StockMarketABM.OrderBookMod.CancelSpec — Typestruct CancelSpecCanonical representation of a cancel instruction directed at the order book.
StockMarketABM.OrderBookMod.LimitOrderBook — Typemutable struct LimitOrderBookBid and ask sides are stored as SortedDicts keyed by price. Each key maps to a PriceLevel{LiveOrder}. loc maps order IDs to their location for O(1) cancel. reg stores the full order specs for logging/replay.
StockMarketABM.OrderBookMod.LimitOrderBook — MethodLimitOrderBook()Construct an empty limit order book with independent bid/ask maps, cleared order location index, and empty order registry.
StockMarketABM.OrderBookMod.LiveOrder — Typestruct LiveOrderMinimal representation of an order in the live order book. Only fields required by the matching engine are stored here.
StockMarketABM.OrderBookMod.OrderLoc — Typestruct OrderLocLocation of a live order inside the book: which side, which price level and the index in that level.
StockMarketABM.OrderBookMod.OrderSpec — Typestruct OrderSpecFull specification of an order as submitted by a trader. Captures ownership (trader), side/price/size, policy settings (TIF/otype), timing metadata, and the traded instrument. Useful for logging, analysis and reconstructing the book.
StockMarketABM.OrderBookMod.add_order! — Methodadd_order!(ob, spec::OrderSpec) -> BoolInsert a limit order described by spec into the appropriate side of the book. Market orders (spec.price === nothing) are rejected because they bypass the book and should be handled directly by the matching engine.
StockMarketABM.OrderBookMod.available_qty — Methodavailable_qty(ob, side, price_limit; stop_at=zero(Qty)) -> QtyReturn the total executable quantity on the opposite side of the book up to and including price_limit (<= when lifting asks, >= when hitting bids). Setting stop_at > 0 short-circuits the scan once at least that much quantity is accumulated, which keeps FOK-style checks linear in the requested size.
StockMarketABM.OrderBookMod.best_ask — Methodbest_ask(ob) -> Union{Price,Nothing}Return the lowest resting ask price or nothing if no asks are present.
StockMarketABM.OrderBookMod.best_bid — Methodbest_bid(ob) -> Union{Price,Nothing}Return the highest resting bid price or nothing if no bids are present.
StockMarketABM.OrderBookMod.cancel_order! — Methodcancel_order!(ob, id::OrderId) -> BoolRemove the resting order identified by id. Returns true when the order was present, otherwise false.
StockMarketABM.OrderBookMod.consume! — Methodconsume!(ob, side, qty; price_limit=nothing)Remove up to qty from the best resting order on the opposite side of side. Returns nothing when no liquidity matches the optional price_limit constraint, otherwise a named tuple (price, order, spec, filled, remaining) where order is the original resting LiveOrder, spec is the pre-consumption OrderSpec, filled is the executed quantity and remaining the leftover on that order.
StockMarketABM.OrderBookMod.get_depth — Methodget_depth(ob, side; top=0) -> Vector{Tuple{Price,Qty}}Return the aggregated depth for side as (price, qty) tuples ordered from best to worst (bids descending, asks ascending). When top > 0, only that many levels are returned. The reported quantities are the current level_qty for each price level, so cancelled slots that have not yet been compacted are excluded. Runtime scales linearly with the number of traversed levels (O(min(top, n_levels(side)))), making the operation inexpensive for small top and proportional to book depth otherwise.
StockMarketABM.OrderBookMod.get_level — Methodget_level(ob, side, price) -> PriceLevelFetch the price level for side at price, creating a fresh PriceLevel when the level does not yet exist. Subsequent calls reuse the cached instance, so callers can freely push/cancel without re-checking for presence.
StockMarketABM.OrderBookMod.is_crossed — Methodis_crossed(ob) -> BoolReturn true when the best bid is greater than or equal to the best ask, indicating a crossed book that should be matched immediately.