Avellaneda-Stoikov Market Making: Inventory Risk, Reservation Price and System Architecture (2026)

Avellaneda-Stoikov Market Making: Inventory Risk, Reservation Price and System Architecture (2026)

Avellaneda-Stoikov Market Making: Inventory Risk, Reservation Price and System Architecture (2026)

A market maker does not get paid for predicting prices. It gets paid for standing in the book, and it pays for that privilege in inventory. Every fill on the bid leaves you longer, every fill on the ask leaves you shorter, and the price you hold that risk through is not yours to choose. The question that decides whether a quoting desk survives is therefore not “where is fair value?” but “how far should I lean my quotes to get back to flat?”

The 2008 paper by Marco Avellaneda and Sasha Stoikov gave that question a clean, closed-form answer, and Avellaneda Stoikov market making has been the default starting point for quoting logic ever since. It is also widely misused: people copy two formulas into a bot and skip the assumptions that make them valid.

What this covers: the derivation in plain steps, a fully worked numeric example, the Guéant-Lehalle-Fernandez-Tapia inventory-bounded extension, the system architecture around the formulas (quote engine, risk gate, kill switch, latency budget), backtest pitfalls, and the failure modes that actually hurt. This is systems analysis, not trading advice.

Non-advisory disclaimer. This article is an engineering and mathematical analysis of a published model. It is not investment advice, a recommendation to trade, or a claim that any strategy is profitable. Numeric examples are illustrative unless attributed to a cited source.

Context and Background

Electronic markets are run as continuous double auctions on a limit order book: resting buy orders (bids) and sell orders (asks) ranked by price and then time. A market maker posts both sides and earns the spread when both are hit. The older economics literature, notably Ho and Stoll (1981) and Glosten and Milgrom (1985), explained the spread as compensation for inventory cost and adverse selection. Avellaneda and Stoikov did something different: they turned the inventory story into a stochastic control problem with a computable answer.

The paper, “High-frequency trading in a limit order book”, appeared in Quantitative Finance 8(3), pages 217 to 224 (2008; DOI 10.1080/14697680701381228). It models a dealer who maximizes exponential utility of terminal wealth, trades only through passive quotes, and sees fills arrive at a rate that decays exponentially with how far the quote sits from the mid-price. The output is two things a quote engine can use directly: a reservation price that moves against inventory, and an optimal spread around it.

Three follow-on lines of work matter in practice. Guéant, Lehalle and Fernandez-Tapia (arXiv 1105.3115, published 2013 in Mathematics and Financial Economics; DOI 10.1007/s11579-012-0087-0) removed the approximations and added hard inventory bounds. Cartea, Jaimungal and co-authors added drift, adverse selection and jump terms (see their 2015 book Algorithmic and High-Frequency Trading; I cite it from memory of the literature and have not re-verified page-level claims). And a large practitioner ecosystem implemented the model; the open-source Hummingbot project, for instance, ships an Avellaneda-based market making strategy with its own documentation.

The tension to hold onto is this. The model is analytically beautiful and operationally naive. It assumes Brownian mid-prices, independent Poisson fills, no queue priority, no fees, no latency and no informed counterparties. A real system is the model plus everything required to survive those assumptions failing. If you also want the venue side of the story, our piece on exchange matching engine architecture covers how the other end of your quotes actually behaves.

The remainder of this article builds the model from the ground up, then wraps an architecture around it. I keep the algebra honest about which steps are exact and which are approximations, because that distinction decides where the model breaks.

The Avellaneda-Stoikov Model: Reservation Price and Optimal Quoting

In the Avellaneda-Stoikov model, a market maker quotes symmetrically around a reservation price r = s − qγσ²(T − t), not around the mid-price s. The reservation price shifts down when inventory q is positive and up when it is negative, so quotes lean toward flattening. The total spread is γσ²(T − t) + (2/γ)·ln(1 + γ/k).

Avellaneda Stoikov market making architecture: quote engine, risk gate and exchange loop

Figure 1: Reference architecture around the Avellaneda-Stoikov quoting formulas. The formulas live in one box; everything else exists to feed it clean inputs and to stop it when its assumptions fail.

Figure 1 shows the system view: market data builds a local book and mid-price, estimators supply σ (volatility) and the fill-intensity parameters, the position tracker supplies inventory q, and the quote engine turns them into a bid and an ask. A risk gate and an order manager sit between the engine and the gateway, and a kill switch can cut both. The mathematics is the small box in the middle; the rest of this article shows why the other boxes are not optional.

The setup: four assumptions that carry everything

The model has four ingredients, and each one is a lever you can later relax.

First, the mid-price follows arithmetic Brownian motion without drift: dS = σ dW, with S_t = s. There is no interest rate, and the paper also gives a geometric variant. The no-drift assumption is crucial; it says you have no view, so inventory is pure risk and never an opportunity.

Second, the dealer has constant absolute risk aversion (CARA, exponential) utility of terminal wealth: maximize E[−exp(−γ(x + qS_T))], where x is cash, q is the signed inventory and γ is the risk-aversion parameter. CARA matters because it makes the value function factor, so wealth drops out of the optimal quotes. The quotes depend on inventory and time, not on how much money you already made.

Third, fills arrive as Poisson events with intensity λ(δ) = A·exp(−kδ), where δ is the distance of the quote from the mid-price. The farther you quote, the fewer fills you get, and k sets how fast liquidity vanishes with distance. The paper derives this form from a power-law order-size distribution combined with logarithmic price impact; it also notes a power-law alternative, λ(δ) = B/δ^β.

Fourth, the horizon T is finite and fixed. The remaining time τ = T − t appears in both main formulas, which is why the original model has quotes converging toward the mid as the session end approaches.

Step 1: indifference prices give the reservation price

The paper first asks a simpler question: ignoring fills, what price would make the dealer indifferent to holding one more (or one fewer) unit? With CARA utility and no trading, the value function has the closed form −exp(−γx)·exp(−γqs)·exp(½γ²σ²q²(T − t)). Comparing the value at inventory q with the value at q ± 1 after paying a price gives a bid-side and an ask-side indifference price. Their average is the reservation price:

r(s, q, t) = s − q·γ·σ²·(T − t)

Read this as a risk charge. Holding q units for the remaining time exposes you to a price variance of q²σ²τ. The marginal cost of the q-th unit scales as qσ²τ, and γ converts variance into utility. A long dealer values the asset below the mid-price, so every quote shifts down; a short dealer shifts up. Nothing about expected profit enters, because there is no drift.

Step 2: the HJB equation and the spread

Now include fills. The dealer chooses bid distance δ^b and ask distance δ^a at each instant to maximize expected utility, which gives a Hamilton-Jacobi-Bellman (HJB) equation. The paper’s trick is an exponential ansatz, u = −exp(−γx)·exp(θ(s, q, t)), which removes the cash variable and leaves a PDE for θ with terminal condition θ(s, q, T) = qs.

Avellaneda Stoikov derivation from HJB equation to reservation price and optimal spread

Figure 2: The derivation path. The model is exact up to the expansion in q and the linearization of the exponential fill term; those two steps are where the closed form is bought.

The first-order conditions in δ give implicit equations for each side: s − r^b = δ^b + (1/γ)·ln(1 − γδ^b·λ^b / ∂λ^b/∂δ), and symmetrically for the ask. For exponential intensities these simplify nicely. The authors then expand θ in powers of inventory, θ = θ₀ + qθ₁ + ½q²θ₂ + …, and linearize the fill term. Solving order by order yields θ₁ = s and a quadratic term that reproduces the reservation price above, plus the spread:

δ^a + δ^b = γσ²(T − t) + (2/γ)·ln(1 + γ/k)

Two facts are worth memorizing. The spread does not depend on inventory; inventory moves the center of the quote, not its width. And the spread has two parts: a volatility term that shrinks to zero at the horizon, and a liquidity term, (2/γ)·ln(1 + γ/k), that remains. As γ → 0 the liquidity term approaches 2/k, which is the optimum for a risk-neutral dealer facing exponential fills.

Why the liquidity term is 2/k when you are not afraid

A risk-neutral dealer picks δ to maximize δ·A·exp(−kδ), the expected spread capture per unit time. Differentiating gives δ = 1/k per side, so a total spread of 2/k. The risk-averse term (2/γ)·ln(1 + γ/k) is a smooth deformation of that: for small γ/k, a Taylor expansion of ln(1 + x) ≈ x − x²/2 gives (2/γ)(γ/k − γ²/(2k²)) = 2/k − γ/k². So risk aversion narrows the liquidity part slightly, while the σ²τ term widens the total. These two forces are the whole spread dynamic.

Quotes are centered on r, not on the mid

Once r and the spread are known, the bid is r − spread/2 and the ask is r + spread/2. The effect is subtle. With inventory q > 0, r < s, so your ask moves closer to the mid and your bid moves farther away. You become more likely to sell and less likely to buy, which is exactly mean reversion of inventory. No explicit inventory controller is needed; the lean is the controller. This is the property that makes the model attractive for market making inventory risk management compared with ad hoc skewing rules.

Worked Example: Avellaneda Stoikov Market Making by Hand

Abstract formulas hide magnitudes, so let us compute. The parameters below are the ones Avellaneda and Stoikov used in their own simulations (s = 100, T = 1, σ = 2, k = 1.5, A = 140) with γ = 0.1. The quote values are my own arithmetic from the published formulas and are illustrative, not market data.

Spread at the start of the session (τ = 1). The volatility term is γσ²τ = 0.1 × 4 × 1 = 0.40. The liquidity term is (2/0.1)·ln(1 + 0.1/1.5) = 20 × ln(1.0667) = 20 × 0.06454 = 1.2908. Total spread: 1.6908, or about 1.69 price units.

Reservation price with inventory q = +3. r = 100 − 3 × 0.1 × 4 × 1 = 98.80. Half-spread is 0.8454, so the bid sits at 97.955 and the ask at 99.645. Note that the ask, 99.645, is now below the mid of 100: the model is willing to sell slightly under the mid to shed inventory. With q = −3, the mirror image holds: r = 101.20, bid 100.355 (above mid), ask 102.045.

Same inventory late in the session (τ = 0.1). The volatility term falls to 0.04, so the spread is 1.3308. The reservation shift falls to 3 × 0.1 × 4 × 0.1 = 0.12, so r = 99.88, with bid 99.215 and ask 100.545. The lean has nearly vanished because there is little time left for the price to move against you.

At the horizon (τ = 0). The spread equals the pure liquidity term, 1.2908, and r equals the mid-price for every q. This is a known artifact: the model has no terminal liquidation penalty, so inventory carries no risk once time runs out. Real desks do not behave like this, and that is the first hint that T is a modelling device, not a trading-day clock.

Remaining time τ Inventory q Reservation r Spread Bid Ask
1.0 0 100.000 1.691 99.155 100.845
1.0 +3 98.800 1.691 97.955 99.645
1.0 −3 101.200 1.691 100.355 102.045
0.1 +3 99.880 1.331 99.215 100.545
0.0 +3 100.000 1.291 99.355 100.645

Table 1: Illustrative Avellaneda-Stoikov quotes for s = 100, σ = 2, γ = 0.1, k = 1.5. Computed from the published closed-form expressions.

What fill rates do those quotes imply?

With A = 140 and k = 1.5, a quote at distance 0.85 fills at λ = 140·exp(−1.5 × 0.85) ≈ 39 events per unit time, while a quote at 0.5 fills at about 66 and a quote at 1.2 at about 23. In the paper’s convention, time runs from 0 to 1, so these are fill-rate scales per session, not per second. The point is relative: moving a quote by 0.35 reduces its fill rate by roughly 40 percent. That elasticity is exactly what k encodes, and it is why estimating k badly gives you the wrong spread even if every other input is perfect.

What the original simulation reported

The paper reports Monte Carlo results from 1,000 runs per setting, with mid-price steps of σ√dt times a standard normal draw and fills drawn with probability λ·dt, where dt = 0.005. For γ = 0.1, the inventory strategy produced a mean profit of about 65 with a standard deviation of 6.6 and a standard deviation of final inventory of 2.9. The benchmark, a symmetric strategy with the same average spread around the mid, produced about 68.4 profit with a standard deviation of 12.7 and a final-inventory standard deviation of 8.4. For γ = 1 the spread widened to about 3.0 and mean profit fell to roughly 31 against 44 for the symmetric strategy, with the standard deviation of profit at 5.0 versus 11.0.

The reading is not “the model makes money”. The reading is that the inventory-aware version trades a little mean profit for a large cut in variance of both profit and terminal inventory, and that as γ → 0 the two strategies converge. These are simulation results inside the model’s own assumptions, taken from the paper’s reported table; they say nothing about live performance.

Extensions: Inventory Bounds, Stationary Quotes and Adverse Selection

The original model has two practical defects. It relies on a finite horizon that does not exist for a desk that quotes all day, every day. And it places no hard limit on inventory, so a bad run can accumulate a position far beyond what a risk manager would tolerate. The Guéant-Lehalle-Fernandez-Tapia paper (GLFT), “Dealing with the Inventory Risk: a solution to the market making problem”, fixes both.

GLFT: constrain q to a box and solve exactly

GLFT keeps the same dynamics and the same exponential intensities, but restricts inventory to q ∈ {−Q, …, Q}. At q = Q the dealer never posts a bid; at q = −Q it never posts an ask. With the substitution u(t, x, q, s) = −exp(−γ(x + qs))·v_q(t)^(−γ/k), the nonlinear HJB system becomes a linear system of ordinary differential equations, v̇ = −M·v with v_q(T) = 1. The optimal quotes are then ratios of adjacent components:

δ^b*(t, q) = (1/k)·ln(v_q / v_{q+1}) + (1/γ)·ln(1 + γ/k)

δ^a*(t, q) = (1/k)·ln(v_q / v_{q−1}) + (1/γ)·ln(1 + γ/k)

Notice what changed. There is no linearization in q and no assumption that inventory is small. The quote at each inventory level comes from an exact solution of a finite linear system, which is a matrix exponential you can compute in microseconds for a modest Q.

The stationary solution that desks actually use

Letting T → ∞, the paper shows that v_q(0) is dominated by the eigenvector f⁰ of M associated with its smallest eigenvalue. The quotes become time-independent functions of inventory: δ^b∞(q) = (1/γ)·ln(1 + γ/k) + (1/k)·ln(f⁰_q / f⁰_{q+1}), and the matching ask expression. Approximating f⁰ by a Gaussian gives a closed form that I recomputed from the paper’s formula:

δ^b∞(q) ≈ (1/γ)·ln(1 + γ/k) + ((2q + 1)/2)·c, δ^a∞(q) ≈ (1/γ)·ln(1 + γ/k) − ((2q − 1)/2)·c

where c = √(σ²γ/(2kA))·(1 + γ/k)^((1 + k/γ)/2). The paper notes the approximation is good for small |q| and can be poor near the bounds, where the exact eigenvector should be used.

For the same illustrative parameters (σ = 2, γ = 0.1, k = 1.5, A = 140) I get c ≈ 0.0517 and a base distance of (1/γ)·ln(1 + γ/k) ≈ 0.645. At q = 0 the bid and ask are both about 0.671 from the mid, a spread of 1.342. At q = +3 the bid sits 0.826 below the mid and the ask 0.516 above it. At q = +5 the numbers are 0.930 and 0.413.

Compare the lean. Under the original model with τ = 1, each unit of inventory shifts the reservation price by γσ²τ = 0.4. Under the stationary GLFT approximation each unit shifts the quote asymmetry by only c ≈ 0.05 on each side. The two are not contradictory: they answer different problems. The finite-horizon model treats inventory risk as accumulating variance up to a deadline; the stationary model treats it as a long-run balance between the penalty and the fill-rate elasticity captured by A and k. But the gap shows how sensitive quote skew is to which formulation you pick, which is why you must be explicit about it in a design review.

Choosing γ: it is a risk dial, not a physical constant

In both formulations γ is a free parameter with no observable counterpart. The practical way to set it is to pick the inventory standard deviation you can tolerate, simulate or compute the distribution of q for a few γ values, and choose the one that meets the target. Avellaneda and Stoikov’s own table shows the trend: raising γ from 0.01 to 1 cut the standard deviation of final inventory from about 5.1 to 1.7 while widening the average spread from about 1.35 to 3.0. In the stationary GLFT form the same story appears as a larger c, hence steeper skew per unit of inventory.

Adverse selection: the term the base model leaves out

Fills are not random. A bid is more likely to be hit when the price is about to fall, because informed or faster traders pick off stale quotes. The base model treats fills as independent of the next price move, so it systematically overestimates the value of a fill. The literature models this by giving the arrival of market orders a dependence on a signal, or by adding a jump in the mid-price at each fill.

Operationally, the simplest honest correction is to shift the fair price the engine quotes around by a short-horizon prediction, and to widen the liquidity term when flow looks toxic. A good source of short-horizon prediction is the book itself; our analysis of order book imbalance features shows how best-bid/best-ask depth ratios feed that signal. The key point is architectural: the signal enters as a modification of s and of k, so the Avellaneda-Stoikov core stays untouched and testable.

From Formulas to Production: System Architecture

A market maker is a control loop with a hard real-time constraint and a hard safety constraint. Figure 1 gave the block diagram; here is what each block must guarantee.

The quote engine: pure function, no side effects

The engine should be a pure function from (mid or fair price, inventory, σ, k, A, γ, remaining time or session mode) to (bid price, bid size, ask price, ask size). Purity buys three things: deterministic replay in a backtest, easy unit tests against the hand-computed numbers in Table 1, and the ability to run the same code in simulation and production. Prices must be rounded to the tick: bid down, ask up, so rounding never narrows the spread. Sizes must respect lot size and minimum notional.

It must also handle the degenerate cases explicitly. If q is at or beyond the inventory bound, suppress the side that would increase exposure. If the computed bid crosses the best ask (possible when r is far below the mid), clip it to the best bid or to one tick inside the touch, depending on whether you are allowed to cross. If σ or k estimates are stale or invalid, fall back to a conservative preset spread rather than a number computed from garbage.

Estimators: where the model meets the data

Three parameters need estimating, and each fails differently.

  • σ (volatility). An exponentially weighted estimate of squared mid-price returns over a window of seconds to minutes works. The risk is lag: in a volatility jump, the estimate lags and the spread is too tight exactly when it should be wide. Use a fast and a slow estimate and take the maximum.
  • k (fill-rate decay). Regress log fill rate on quote distance. For each distance bucket, count how often a resting order at that distance would have been filled; the slope of log(rate) against δ is −k and the intercept is ln A. This needs trade-and-book data at the granularity of your own quotes and is noisy; shrink toward a long-run prior.
  • A (baseline intensity). Estimated jointly with k. A is also the quantity that scales the stationary GLFT skew, because c contains 1/√A: a busier market means you can lean less per unit of inventory because inventory turns over faster.

Re-estimate on a rolling basis, but rate-limit how fast parameters can move, otherwise the quotes themselves become a noisy signal and you will churn orders.

Order management: quote diffing and cancel/replace discipline

The engine produces a new theoretical quote on every market-data event, but sending that to the exchange would be wasteful and, on many venues, penalized by message-rate limits and fees. The order manager compares the target with the live quote and replaces it only if the price differs by at least a tick (or a configurable threshold) or the size changed. This is the cancel/replace discipline sketched in Figure 3.

Avellaneda Stoikov market making quote cycle with risk gate, fill handling and kill switch

Figure 3: One quote cycle. Notice that the kill switch acts on the order manager directly, bypassing the quote engine, so a bug in the engine cannot disable its own safety net.

Figure 3 walks through a cycle: a book update arrives, the engine recomputes r and the spread, the risk gate approves or rejects, and the order manager sends a replace only when the quote has moved. When a fill comes back, inventory updates, and the next cycle lowers or raises the reservation price. The kill switch path is deliberately independent.

The risk gate and kill switch

The model’s control of inventory is soft: it lowers the incentive to accumulate but does not forbid it. Risk limits must be hard, and they must live outside the quote engine. A typical pre-trade gate checks per-order size, per-side notional, absolute position, price bands relative to a reference price (the “fat finger” check), message rate, and open order count. Post-trade checks track realized and unrealized P&L against a daily loss limit.

A kill switch cancels all resting orders and blocks new ones. It should trip automatically on: loss limit breach, position beyond a hard cap, feed staleness (no market data for N milliseconds), gateway disconnect, sequence-gap detection, and a divergence between internal and exchange-reported position. Regulators expect such controls in the EU under MiFID II’s algorithmic trading rules (RTS 6) and in the US under the SEC’s Market Access Rule (Rule 15c3-5); I am citing these as the relevant regimes from general knowledge, not as legal advice, and a compliance review should confirm the specifics for any jurisdiction.

The latency budget

The latency that matters is the time from a market-data event that changes your fair price to the moment your replaced quote is live at the exchange. Break it into stages and give each a budget: wire-to-application (network and feed decode), book update, estimator read, quote computation, risk gate, order encoding, wire-out, and exchange acknowledgment. The Avellaneda-Stoikov computation itself is a handful of floating-point operations and a logarithm that can be precomputed; it is never the bottleneck. The expensive parts are garbage collection pauses, lock contention between the market-data and order threads, and serialization.

Why does latency matter to the model’s economics? Because adverse selection grows with it. If your quotes are stale by L seconds, you are exposed to a price move of roughly σ√L before you can cancel. With σ = 2 per unit time (the paper’s convention) and L = 0.01 of a time unit, that exposure is 2 × 0.1 = 0.2, which is about 24 percent of the half-spread of 0.845 computed earlier. This is an illustrative scaling, not a measurement, but it shows how slow a plain implementation can be before the spread no longer covers picking-off risk.

On the venue side, whether your cancel can win a race against an incoming aggressive order depends on matching-engine sequencing, which is why architecture decisions on both sides matter; see the earlier discussion of matching engine design.

Backtesting Avellaneda-Stoikov Market Making Without Fooling Yourself

A backtest of Avellaneda-Stoikov market making is harder than a directional one, because the strategy’s P&L depends on whether its own orders would have been filled, and that depends on the queue. A bar-based or trade-based simulation that assumes “my bid at 99.95 fills whenever a trade prints at or below 99.95” will be too optimistic, often by a wide margin. The architecture for doing this properly is covered in our post on event-driven backtesting engine architecture; here are the specific traps for this model.

Queue position. On a price-time priority book, your resting order is behind everyone who arrived earlier. A trade at your price does not fill you unless it consumes the volume ahead of you first. Model queue position explicitly: record the displayed size ahead of you at placement, decrement it by trades and by cancellations (which you can only estimate, for example by assuming a proportion of cancels occur ahead of you), and fill only when the queue reaches zero. Run the backtest under a pessimistic and an optimistic cancel assumption and report both.

Self-impact and latency. Your orders are not free to the order flow. In replay, a quote you post changes what other participants would have done, and a simulation using recorded data cannot capture that. Add the latency budget from the previous section as a delay between decision and live quote, and between market event and your knowledge of it. A zero-latency backtest is a different strategy from the one you will run.

Fill-model circularity. If you estimate k and A from the same data you backtest on, you are fitting the answer. Estimate on one period and test on another, and keep an eye on whether k drifts between regimes. The exponential intensity is an approximation that tends to fit near the touch and fail far from it.

Fees and rebates. The spread you capture is net of exchange fees or rebates. A maker rebate of a fraction of a tick can be a large share of expected profit, and its removal or change can flip the strategy’s sign. Model it explicitly, and keep the fee schedule as a versioned input.

Survivorship in parameters. A grid search over γ, the volatility window and the re-estimation rate will find a combination that looks good in sample. Prefer a coarse grid, report the whole surface rather than the best cell, and favor settings in a flat, stable region. Total P&L is a poor selection metric; also look at the inventory distribution, maximum drawdown, and the P&L conditional on large mid-price moves.

The terminal-time artifact. Because the original model’s quotes collapse onto the mid at τ = 0, a backtest that mimics “T = end of session” will show the strategy dumping inventory at the close for free. Either use the stationary GLFT form, or add an explicit liquidation cost and a rule for the overnight position.

Failure cascade for Avellaneda Stoikov market making from stress event to inventory runaway and risk limits

Figure 4: How a stress event turns into an inventory runaway, and the two layers of hard controls that cut the chain.

Trade-offs, Gotchas, and What Goes Wrong

Figure 4 summarizes the failure chain. A stress event hits through one of four doors: a volatility jump the estimator has not seen yet, toxic order flow, a latency spike, or a bad feed. The first two make the spread too tight; the last two make your quotes stale. Both ends converge on the same outcome, inventory that builds fast in one direction, which is the very thing the reservation-price lean was supposed to prevent.

The lean is weak when you need it most. The reservation-price shift is proportional to γσ²τ times q. If the mid-price trends against you, the model reacts by moving your quotes closer to the touch on the side that reduces inventory. In a one-way market, that is exactly where informed traders hit you repeatedly. The no-drift assumption means the model sees a trend as noise, and it will keep selling into a rally if it is short.

Poisson fills understate clustering. Real trades arrive in bursts, and a burst consumes your quote on one side several times in quick succession before you can update. Exponential intensity with independent increments gives a thin tail on inventory; the real inventory distribution has a fat tail. Size your hard limits against the empirical worst case, not against the model’s standard deviation.

γ is not stable across regimes. A γ chosen for a calm market is too small when volatility doubles, because the volatility term in the spread scales with σ² and the lean scales with σ². In theory that is the model working as intended. In practice the σ estimate lags, so an explicit volatility regime switch that scales γ or widens the spread is cheaper than trusting the estimator alone.

Parameter feedback loops. If your k estimate is derived from your own fill history and your quotes depend on k, then a lucky streak of fills lowers the estimated k, widens your spread, and reduces fills further. Smooth the estimators, and bound each parameter by a prior range.

Multi-asset and hedging. The single-asset model has no notion of correlated inventory. A desk quoting several related instruments must either extend the model to a multivariate form or hedge net exposure in a liquid proxy. Treating each instrument independently double counts risk in some cases and misses it in others.

Latency asymmetry. The model has no competitor. Against faster participants, the quotes at the touch are picked off because the competitor’s information arrives first. Quoting a few ticks off the touch reduces adverse selection at the cost of fill rate, which is a point on the same A·exp(−kδ) curve and can be chosen explicitly.

What not to do. Do not treat the model’s σ²τ term as a stop-loss. Do not rely on the kill switch to substitute for sizing. Do not tune γ on P&L alone. And do not quote in a market whose tick size is large relative to your computed half-spread: when the minimum tick exceeds the model’s optimal spread, the quote lands on the tick grid, and the model is no longer optimal because the discretization dominates.

Practical Recommendations

For any Avellaneda-Stoikov market making deployment, start with the separation of concerns. Keep the quoting formula a pure, tested function; keep estimators, risk limits and order management as independent components with their own tests and their own failure behavior. This is the single design decision that most reduces operational risk.

Choose the formulation to match the use case. If you quote through a defined session with a known end, the finite-horizon form is reasonable but treat the vanishing lean near T as an artifact. If you quote continuously, prefer the GLFT inventory-bounded, stationary form; the hard bound Q also gives risk a natural number to approve.

Treat the three market parameters as living quantities with guardrails: rolling estimates, a maximum rate of change, and a conservative fallback. Add a short-horizon fair-price signal to correct for adverse selection rather than editing the core formula. Run every change through a queue-aware backtest, then through paper trading, then at minimal size, and compare realized fill rates with the model’s λ at each stage.

  • Unit-test the engine against Table 1 style hand calculations.
  • Round prices to the tick in the safe direction; never let rounding narrow the spread.
  • Put hard inventory, notional, price-band and message-rate limits in a gate independent of the engine.
  • Trip the kill switch on stale data, position mismatch and loss limit, and rehearse it.
  • Estimate σ with fast and slow windows and use the larger.
  • Bound and smooth k and A; log every parameter change.
  • Backtest with queue position, latency and fees; report the inventory distribution, not only P&L.
  • Review the design against the regulatory regime of the venue with your compliance team.

Frequently Asked Questions

What is the Avellaneda-Stoikov model in simple terms?

It is a stochastic-control model for a dealer who posts a bid and an ask and wants to maximize utility of terminal wealth while managing inventory. It outputs a reservation price, the dealer’s inventory-adjusted valuation, and an optimal spread around it. When inventory is positive, quotes shift down to encourage selling; when negative, they shift up. The result is an inventory-aware, closed-form quoting rule from the 2008 paper in Quantitative Finance.

How is the reservation price calculated?

In the original model the reservation price is r = s − q·γ·σ²·(T − t), where s is the mid-price, q the signed inventory, γ the risk-aversion parameter, σ the volatility of the mid-price and T − t the remaining time. It is the price at which the dealer is indifferent about holding the marginal unit. A larger position, higher volatility, more risk aversion or longer remaining time all push it further from the mid-price.

What do the parameters gamma and k mean?

The parameter γ is the dealer’s risk aversion: higher values mean stronger inventory penalty, a steeper lean, and a wider spread. The parameter k describes how fast the probability of being filled decays as a quote moves away from the mid-price, in the intensity λ(δ) = A·exp(−kδ). A large k means liquidity concentrates at the touch, so the optimal spread narrows. Both must be calibrated or chosen deliberately, and k can be estimated from data.

Does Avellaneda-Stoikov market making work in live markets?

It works as a structural prior, not as a turnkey profit engine. Its assumptions (no drift, Poisson fills, no queue priority, no latency, no informed traders) are violated in live books. Practitioners use it as the skeleton for quoting and then add queue modelling, an adverse-selection signal, hard risk limits and parameter guardrails. Whether any given implementation is profitable depends on fees, latency and competition, none of which the model addresses.

How does the GLFT extension differ?

Guéant, Lehalle and Fernandez-Tapia bound inventory to a box from −Q to Q, turn the nonlinear HJB equation into a linear ODE system, and derive exact quotes with a stationary (infinite-horizon) limit. That removes the finite-horizon artifact and the small-inventory expansion, and it supplies a hard cap that fits real risk management. The paper also gives a closed-form approximation of the stationary quotes that is accurate for small inventories.

Can I use it for crypto or equities?

The mathematics is venue-agnostic, and open-source projects such as Hummingbot implement an Avellaneda-based strategy for crypto exchanges. The venue details, however, change the answer: tick size, fee and rebate structure, queue priority rules, latency to the matching engine and the presence of informed flow all determine whether the model’s fill assumptions are reasonable. Validate those inputs per venue before relying on the formulas.

Further Reading

By Riju — about

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply

Your email address will not be published. Required fields are marked *