Matching

The matcher determines how limit orders get filled. Two implementations are available.

Simple matcher

SimpleMatcher: deterministic immediate fill at BBO. If the limit price crosses the BBO (e.g. a buy priced above the ask), the order fills immediately at the BBO price.

Fast and predictable. Use for:

  • Low-frequency strategy evaluation.
  • PnL attribution.
  • When fill probability is not the focus of the test.

Stochastic matcher

StochasticMatcher: three-pronged fill model per the Avellaneda-Stoikov framework. On each tick, every resting order is evaluated:

1. Aggressive crossing

The order's limit price is on the wrong side of the current BBO. Condition (buy): limit >= best_ask. Condition (sell): limit <= best_bid. Fill price: BBO price. Immediate fill with no randomness.

2. Deterministic mid-price sweep

The limit was placed passively, but the mid-price path from $S_t$ to $S_{t+1}$ moved through the limit level. Because the price crossed the order, every market-order arriving during the interval would have filled it. Fill probability: 1.0 (guaranteed). Fill price: limit price.

3. Probabilistic Poisson arrival

The mid has not swept through the limit. Random incoming market orders may still hit the resting order during $[t, t+1]$. The Poisson intensity is computed using the distance from the post-move mid $S_{t+1}$:

$$\lambda = a \cdot e^{-k \cdot \delta}, \quad \delta = |limit - mid_{t+1}|$$

$$p_{fill} = 1 - e^{-\lambda \cdot dt}$$

Fill price: limit price.

The Poisson arrival rate decays exponentially with distance from mid, modeling the fact that a resting order far from the mid is much less likely to be hit by a random market order. The parameters a and k are configurable.