Skip to main content
Ultra Feature. Requires an Ultra subscription. Get started at api.mathematicalcompany.com
What is this? When you place a limit order, you join a queue. The queue model estimates your probability of getting filled by tracking how many orders are ahead of you and how fast orders arrive, cancel, and fill. Use it to decide whether to stay in the queue or cross the spread, and to set realistic fill expectations for your limit orders.

Queue Position Modeling

Horizon provides a queue position model for estimating fill probabilities and expected fill times for limit orders in prediction market order books. The model tracks your position in the queue, accounts for order arrivals, cancellations, and executions ahead of you, and provides real-time probability estimates. All computation runs in Rust.

Queue Tracking

Track your position in the limit order book queue with order arrival and cancellation updates.

Fill Probability

Estimate the probability of your order being filled within a time horizon.

Expected Fill Time

Compute the expected time until your order reaches the front of the queue and gets filled.

Pipeline Integration

hz.queue_tracker() provides live queue analytics within hz.run().

Why Queue Position Matters

In prediction markets with limit order books, fill probability depends critically on your position in the queue. Market makers who post limit orders need to know:
  1. Fill probability: Will this order execute before I need to cancel it?
  2. Expected fill time: How long will I wait? Is it worth the spread?
  3. Queue dynamics: Are cancellations ahead of me improving my position, or are new arrivals pushing me back?
The queue model answers these questions by combining Poisson arrival/cancellation processes with your observed queue position.
Queue position modeling is most valuable on markets with deep order books and significant queue depth. On thin markets where you are at or near the front of the queue, the model reduces to simple arrival-rate estimation.

API

hz.QueueModel

Create a queue position model for a specific price level.
import horizon as hz

model = hz.QueueModel(
    initial_queue=500.0,     # total queue size at your price level
    orders_ahead=200.0,      # contracts ahead of you in the queue
)
print(f"Queue position: {model.queue_position()}")
print(f"Position ratio: {model.queue_position() / 500.0:.2%}")
ParameterTypeDescription
initial_queuefloatTotal queue depth at the price level (positive)
orders_aheadfloatVolume ahead of your order in the queue (non-negative, must not exceed initial_queue)

QueueModel Methods

update_book(total_queue, orders_ahead)

Update the model with a new book snapshot. Call this each time the order book changes at your price level.
import horizon as hz

model = hz.QueueModel(initial_queue=500.0, orders_ahead=200.0)

# Book update: some orders ahead cancelled, new orders arrived behind
model.update_book(total_queue=480.0, orders_ahead=150.0)
print(f"Updated position: {model.queue_position()}")
ParameterTypeDescription
total_queuefloatNew total queue depth (positive)
orders_aheadfloatNew volume ahead of your order (non-negative)

fill_probability(time_horizon)

Estimate the probability of your order being filled within a given time horizon, based on observed arrival and cancellation rates.
import horizon as hz

model = hz.QueueModel(initial_queue=500.0, orders_ahead=200.0)

# After several book updates, estimate fill probability
prob = model.fill_probability(time_horizon=60.0)  # 60 seconds
print(f"Fill probability (60s): {prob:.2%}")
ParameterTypeDescription
time_horizonfloatTime horizon in seconds (positive)
Returns a FillProbResult.

expected_fill_time()

Compute the expected time until your order is filled, based on the current arrival rate and queue position.
eft = model.expected_fill_time()
print(f"Expected fill time: {eft:.1f} seconds")
Returns float: expected fill time in seconds. Returns float('inf') if the arrival rate is zero or the queue is stalled.

arrival_rate()

Return the estimated order arrival rate (fills per second) at your price level, computed from observed book updates.
rate = model.arrival_rate()
print(f"Arrival rate: {rate:.4f} fills/sec")
Returns float.

cancel_rate()

Return the estimated cancellation rate (cancels per second) ahead of your position.
rate = model.cancel_rate()
print(f"Cancel rate: {rate:.4f} cancels/sec")
Returns float.

queue_position()

Return your current position in the queue (volume ahead of you).
pos = model.queue_position()
print(f"Orders ahead: {pos:.0f}")
Returns float.

FillProbResult Type

Returned by fill_probability().
FieldTypeDescription
probabilityfloatEstimated fill probability in [0, 1]
expected_fillsfloatExpected number of fills at this price level in the time horizon
queue_positionfloatCurrent queue position (orders ahead)
arrival_ratefloatEstimated arrival rate used in the calculation
cancel_ratefloatEstimated cancellation rate used in the calculation

Standalone Fill Probability

hz.queue_fill_prob

One-shot fill probability calculation without maintaining a stateful model.
import horizon as hz

result = hz.queue_fill_prob(
    queue_ahead=200.0,
    arrival_rate=5.0,       # fills per second
    cancel_rate=1.0,        # cancels per second (ahead of you)
    time_horizon=60.0,      # seconds
)
print(f"Fill probability: {result.probability:.2%}")
print(f"Expected fills: {result.expected_fills:.1f}")
ParameterTypeDescription
queue_aheadfloatVolume ahead of your order (non-negative)
arrival_ratefloatFill arrival rate at this price level (positive)
cancel_ratefloatCancellation rate ahead of you (non-negative)
time_horizonfloatTime horizon in seconds (positive)
Returns a FillProbResult.
The model uses a Poisson process for fill arrivals and an independent Poisson process for cancellations. The effective queue depletion rate is arrival_rate + cancel_rate, and the probability of reaching the front of the queue is computed via the CDF of the Poisson distribution.

Pipeline Integration

hz.queue_tracker

Pipeline function that maintains queue position models for all active orders and injects analytics into ctx.params["queue"].
import horizon as hz

def queue_aware_strategy(ctx):
    queue = ctx.params.get("queue")
    if queue is None:
        return []

    mid = ctx.feed.price
    spread = 0.02

    # Check fill probability for existing orders
    for order_id, q in queue.get("orders", {}).items():
        prob = q["fill_probability_60s"]
        if prob < 0.1:
            # Very unlikely to fill, consider canceling and re-posting
            print(f"Order {order_id}: fill prob {prob:.1%}, consider re-posting")

    # Only post new orders if expected fill time is reasonable
    avg_eft = queue.get("avg_expected_fill_time", float("inf"))
    if avg_eft > 300:  # more than 5 minutes expected wait
        spread *= 0.5  # tighten spread to improve queue position

    return [
        hz.quote(ctx, hz.Side.Yes, hz.OrderSide.Buy, mid - spread, 10),
        hz.quote(ctx, hz.Side.Yes, hz.OrderSide.Sell, mid + spread, 10),
    ]

hz.run(
    name="queue-aware-mm",
    markets=["0xcondition..."],
    pipeline=[
        hz.queue_tracker(),
        queue_aware_strategy,
    ],
    interval=1.0,
)
The ctx.params["queue"] dict contains:
KeyTypeDescription
ordersdict[str, dict]Per-order queue analytics keyed by order ID
avg_expected_fill_timefloatAverage expected fill time across all active orders
total_queue_aheadfloatSum of queue depth ahead across all active orders
best_fill_probfloatHighest fill probability (60s) among active orders
Each order dict in orders contains:
KeyTypeDescription
queue_positionfloatVolume ahead of this order
fill_probability_60sfloatFill probability over 60 seconds
expected_fill_timefloatExpected time to fill in seconds
arrival_ratefloatEstimated fill arrival rate

Mathematical Background

The model assumes fills arrive at the price level according to a Poisson process with rate mu, and cancellations ahead of you occur with rate delta. The effective queue depletion rate is lambda = mu + delta.Your order fills when the cumulative depletion exceeds your queue position Q. The probability of this in time T is:P(fill) = P(Poisson(lambda * T) >= Q)This is computed via the regularized incomplete gamma function for numerical stability.
Arrival and cancellation rates are estimated from observed book updates using exponentially weighted moving averages. This adapts to changing market conditions while filtering out noise from individual book updates.The model requires at least 2 book updates with non-zero time deltas to produce meaningful rate estimates. Before that, fill_probability() returns conservative estimates.
The Poisson assumption treats arrivals as independent and memoryless. In practice, order flow exhibits clustering (modeled separately by ACD duration models). The queue model provides a first-order approximation that is most accurate over medium time horizons (30-300 seconds) and less reliable for very short or very long horizons.
Queue position estimates are only as accurate as the book data fed to update_book(). On markets with infrequent book snapshots, the arrival and cancellation rate estimates may be noisy. Increase the update frequency or use larger time horizons for more stable estimates.