Transaction Costs & Market Impact: Models & Analysis › Market Impact Modeling

Michael BrenndoerferJanuary 8, 202615 min read
Quantitative FinanceAll chapters
Part 14 of 15Strategy Development and Backtesting
Chapter 74Transaction Costs & Market Impact: Models & Analysis › Market Impact Modeling
Reading section 4 of 16 · Market Impact Modeling · 15 minSection 4 of 16 · 15 min

Book contents

Section 4 of 16 · 15 min read

Transaction Costs & Market Impact: Models & Analysis › Market Impact ModelingOne section · Sections in this chapter4 / 16 ↓
Reading tools Definitions & inline links

Choose your expertise level to adjust how many terms are explained. Beginners see more tooltips, experts see fewer to maintain reading flow. Hover over underlined terms for instant definitions.

Article links

Make inline references clickable

Market impact is a critical and complex transaction cost component to model. When you trade, you are not simply paying a fixed cost; you are changing the market price itself. This effect is temporary (prices revert after your trading pressure subsides) and permanent (your trades may convey information that is incorporated into prices). The challenge in modeling market impact lies in its dual nature: part of the price change is a mechanical response to consuming liquidity, which fades as the market rebalances, while another part reflects information conveyed by the trade that permanently updates the market's view of fair value.

Temporary vs. Permanent Impact

Market Impact Components

Temporary impact is the transient price displacement caused by trading pressure that reverts after trading ceases. It reflects the liquidity premium demanded by counterparties for absorbing your order flow.

Permanent impact is the lasting price change that remains after temporary impact has decayed. It reflects the information content of your trades that becomes incorporated into the market price.

The distinction is critical for execution strategy. If impact were purely temporary, you could simply wait for prices to revert before trading again. But permanent impact means that your early trades adversely affect your later trades, as the price has permanently moved against you. Consider a fund liquidating a large position: temporary impact means they pay a premium for immediate execution, but this premium disappears once they stop trading. Permanent impact, however, means that each sale drives down the price level at which subsequent sales occur, creating a compounding cost that cannot be avoided by waiting.

Empirical research, starting with the seminal work of Kyle (1985) and later Almgren and Chriss (2001), has established several stylized facts about market impact:

  • Impact is concave in trade size: doubling the trade size does not double the impact
  • Impact depends on the participation rate (fraction of market volume)
  • Temporary impact decays over time, typically within minutes to hours
  • Permanent impact persists and is related to the information content of trades

These empirical regularities set up the mathematical models we develop next. The concavity of impact in trade size is particularly important: it means that large trades are more efficient per share than small trades in terms of impact cost, but total impact still grows with order size. This creates interesting tradeoffs in execution strategy that we will explore.

The Square-Root Model

The most widely used market impact model in practice is the square-root model. Empirical studies document this relationship in equity, futures, and foreign exchange markets over multiple periods. The model states that market impact scales with the square root of the trade size relative to market volume:

Impact=σ⋅η⋅(QV)γ\text{Impact} = \sigma \cdot \eta \cdot \left(\frac{Q}{V}\right)^{\gamma}

where:

  • Impact\text{Impact}: market impact cost as a fraction of price
  • σ\sigma: daily volatility of the asset
  • QQ: quantity traded (shares or dollars)
  • VV: daily trading volume (in the same units as QQ)
  • η\eta: impact coefficient (market-dependent parameter)
  • γ\gamma: impact exponent, empirically found to be approximately 0.5 (hence "square-root")

Let us examine each component of this formula to understand its economic intuition. The volatility term σ\sigma appears because impact is fundamentally about price uncertainty: in a more volatile market, liquidity providers demand greater compensation for taking the other side of your trade, since the risk of adverse price movement is higher. The participation rate Q/VQ/V captures how much of the market's trading activity your order represents; trading 10% of daily volume creates far more impact than trading 0.1%.

The impact coefficient η\eta is an empirical parameter that varies by market and must be estimated from data. Typical values range from 0.05 to 0.3 depending on the asset class and market conditions. Illiquid markets tend to have higher η\eta values, which reflects the greater difficulty of absorbing large orders without moving prices.

The square-root relationship, captured by the exponent γ≈0.5\gamma \approx 0.5, has been documented across many markets and time periods. It implies that trading 4% of daily volume incurs only about twice the impact of trading 1%, not four times. This sublinearity determines how strategy capacity scales with order size. Mathematically, if you trade four times the volume (4Q4Q instead of QQ), your impact becomes σ⋅η⋅(4Q/V)0.5=2⋅σ⋅η⋅(Q/V)0.5\sigma \cdot \eta \cdot (4Q/V)^{0.5} = 2 \cdot \sigma \cdot \eta \cdot (Q/V)^{0.5}, which is only twice the original impact despite quadrupling the trade size.

In[10]:
Code
import numpy as np


# Square-root impact model implementation
def square_root_impact(quantity, volume, volatility, eta=0.1, gamma=0.5):
    """
    Calculate market impact using square-root model.

    Parameters:
    -----------
    quantity : float or array
        Trade size (shares or dollars)
    volume : float
        Daily trading volume
    volatility : float
        Daily volatility (as decimal, e.g., 0.02 for 2%)
    eta : float
        Impact coefficient (typically 0.05-0.2)
    gamma : float
        Impact exponent (typically ~0.5)

    Returns:
    --------
    impact : float or array
        Market impact as a percentage of price
    """
    participation_rate = quantity / volume
    impact = volatility * eta * (participation_rate**gamma)
    return impact


# Parameters for a typical liquid stock
daily_volume = 10_000_000  # 10 million shares daily
daily_volatility = 0.02  # 2% daily volatility

# Calculate impact for various trade sizes
trade_sizes = np.linspace(10000, 1000000, 100)
impacts = square_root_impact(trade_sizes, daily_volume, daily_volatility)

# Also calculate what linear impact would look like
linear_impacts = daily_volatility * 0.1 * (trade_sizes / daily_volume)

# Annotation coordinate
example_size = 600000
example_impact_bps = (
    square_root_impact(example_size, daily_volume, daily_volatility) * 10000
)
Out[11]:
Visualization
Line chart comparing square-root and linear market impact models across trade sizes.
Market impact comparison showing the square-root model versus a hypothetical linear model. The concave shape of the square-root model means larger trades are more efficient per share than smaller trades, but total impact still grows with size.

The square-root relationship has important practical implications. Consider a fund that has been trading 1% of daily volume with satisfactory performance. If they decide to double their capital, trading 2% of daily volume, their impact costs increase by a factor of 2≈1.41\sqrt{2} \approx 1.41, not 2. This is good news for scaling strategies, but the costs still grow faster than linearly would suggest in absolute dollar terms.

The Almgren-Chriss Framework

For optimal execution of large orders, we need a more sophisticated model that captures the tradeoff between market impact and timing risk. The Almgren-Chriss framework, introduced in their influential 2001 paper, provides exactly this. This framework transformed the field by formalizing the execution problem as a mathematical optimization: how should we balance the certainty of market impact costs against the uncertainty of price movements during execution?

Consider if you must liquidate X shares over a time horizon TT. The key insight is that you face a fundamental dilemma. Trading quickly minimizes your exposure to adverse price movements but concentrates all of the market impact into a short period. Trading slowly spreads out the impact but leaves you vulnerable to volatility risk as prices may move against you while you still hold a large position.

Let the trading trajectory be described by x(t)x(t), the number of shares remaining to be sold at time tt, with x(0)=Xx(0) = X and x(T)=0x(T) = 0. The trading rate is x˙(t)=dxdt\dot{x}(t) = \frac{dx}{dt}. This notation captures the complete execution path: at any moment, we know both how many shares remain and how fast we are trading.

The framework models two sources of cost, corresponding to the temporary and permanent impact we discussed earlier:

Permanent impact: The price reflects the cumulative effect of past trading:

S(t)=S0−∫0tg(x˙(s)) dsS(t) = S_0 - \int_0^t g(\dot{x}(s)) \, ds

where:

  • S(t)S(t): asset price at time tt
  • S0S_0: initial asset price
  • g(⋅)g(\cdot): permanent impact drift function
  • x˙(s)\dot{x}(s): trading rate at time ss
  • tt: current time

This equation captures how the market price drifts downward (for a sell program) as our trading activity reveals information. The function g(⋅)g(\cdot) describes how the trading rate translates into price pressure. The integral accumulates all past trading pressure, which reflects that permanent impact is indeed permanent: the price remembers all our previous trades.

Temporary impact: Additionally, each trade temporarily depresses the price:

S~(t)=S(t)−h(x˙(t))\tilde{S}(t) = S(t) - h(\dot{x}(t))

where:

  • S~(t)\tilde{S}(t): effective execution price
  • S(t)S(t): fundamental asset price
  • h(⋅)h(\cdot): temporary impact function
  • x˙(t)\dot{x}(t): trading rate

While permanent impact accumulates over time, temporary impact depends only on our current trading rate. The function h(⋅)h(\cdot) captures the instantaneous price concession we must offer to attract counterparties. The faster we trade, the larger this concession must be to induce sufficient liquidity providers to take the other side.

We can derive the expected execution cost by calculating the Implementation Shortfall which is the difference between the initial portfolio value and the total proceeds from liquidation. This measure, introduced by Perold in 1988, has become the industry standard for execution cost measurement because it captures the complete cost of implementing an investment decision.

The total proceeds correspond to the integral of the execution price multiplied by the trading rate (negative for sales):

Proceeds=∫0T[−x˙(t)]S~(t) dt=∫0T[−x˙(t)](S(t)−h(x˙(t))) dt=−∫0Tx˙(t)S(t) dt−∫0T∣x˙(t)∣h(x˙(t)) dt\begin{aligned} \text{Proceeds} &= \int_0^T [-\dot{x}(t)] \tilde{S}(t) \, dt \\ &= \int_0^T [-\dot{x}(t)] (S(t) - h(\dot{x}(t))) \, dt \\ &= -\int_0^T \dot{x}(t) S(t) \, dt - \int_0^T |\dot{x}(t)| h(\dot{x}(t)) \, dt \end{aligned}

The first term represents the proceeds if we could execute at the fundamental price S(t)S(t), while the second term represents the additional cost from temporary impact. Note that the trading rate x˙(t)\dot{x}(t) is negative for sales (shares remaining is decreasing), which is why we use the absolute value in the second integral to ensure temporary impact is always a cost.

Using integration by parts on the first term ∫0Tx˙(t)S(t) dt\int_0^T \dot{x}(t) S(t) \, dt, we set u=S(t)u = S(t) and dv=x˙(t)dtdv = \dot{x}(t) dt, which implies du=S˙(t)dtdu = \dot{S}(t) dt and v=x(t)v = x(t). The integration yields:

∫0Tx˙(t)S(t) dt=[x(t)S(t)]0T−∫0Tx(t)S˙(t) dt=(x(T)S(T)−x(0)S(0))−∫0Tx(t)(−g(x˙(t))) dt(boundary conditions and dynamics)=−XS0+∫0Tx(t)g(x˙(t)) dt(using x(T)=0,x(0)=X)\begin{aligned} \int_0^T \dot{x}(t) S(t) \, dt &= [x(t) S(t)]_0^T - \int_0^T x(t) \dot{S}(t) \, dt \\ &= (x(T)S(T) - x(0)S(0)) - \int_0^T x(t) (-g(\dot{x}(t))) \, dt && \text{(boundary conditions and dynamics)} \\ &= -X S_0 + \int_0^T x(t) g(\dot{x}(t)) \, dt && \text{(using } x(T)=0, x(0)=X \text{)} \end{aligned}

The boundary conditions enforce that we start with XX shares and end with zero. The price dynamics equation S˙(t)=−g(x˙(t))\dot{S}(t) = -g(\dot{x}(t)) tells us that the price falls by gg for each unit of trading rate.

Negating this result provides the first term of the proceeds equation:

−∫0Tx˙(t)S(t) dt=XS0−∫0Tx(t)g(x˙(t)) dt-\int_0^T \dot{x}(t) S(t) \, dt = X S_0 - \int_0^T x(t) g(\dot{x}(t)) \, dt

Subtracting the proceeds from the initial value XS0X S_0 yields the total expected cost:

E[Cost]=∫0T[x(t)g(x˙)+∣x˙∣h(x˙)]dtE[\text{Cost}] = \int_0^T \left[ x(t) g(\dot{x}) + |\dot{x}| h(\dot{x}) \right] dt

where:

  • E[Cost]E[\text{Cost}]: expected total execution cost
  • TT: liquidation time horizon
  • g(x˙)g(\dot{x}): permanent impact component
  • h(x˙)h(\dot{x}): temporary impact component
  • x(t)x(t): shares remaining at time tt
  • x˙\dot{x}: trading rate

The integral sums two distinct cost sources:

  1. g(x˙)⋅x(t)g(\dot{x}) \cdot x(t): The cost from permanent price drift, which devalues the entire remaining position x(t)x(t).
  2. h(x˙)⋅∣x˙∣h(\dot{x}) \cdot |\dot{x}|: The cost from temporary impact, which acts as a direct toll on the specific shares ∣x˙∣|\dot{x}| traded at each moment.

Permanent and temporary impact enter this decomposition asymmetrically. Permanent impact costs are amplified by the remaining position: when you have many shares left to sell, each unit of permanent price decline costs you more because it affects more shares. Temporary impact, by contrast, is a local cost that affects only the shares currently being traded.

The variance of execution cost (timing risk) depends on the price volatility and the remaining position:

Var[Cost]=σ2∫0Tx(t)2 dt\text{Var}[\text{Cost}] = \sigma^2 \int_0^T x(t)^2 \, dt

where:

  • Var[Cost]\text{Var}[\text{Cost}]: variance of execution cost
  • σ\sigma: price volatility parameter
  • x(t)x(t): shares remaining at time tt
  • TT: total time horizon

This formula captures the intuition that timing risk is proportional to how much position you hold and for how long. The squared term x(t)2x(t)^2 reflects that larger positions create proportionally more variance. If you liquidate quickly (small x(t) for most of the period), you have low variance, while if you hold a large position until late in the trading period, you have high variance.

You face a tradeoff: trading quickly minimizes timing risk but maximizes market impact; trading slowly minimizes impact but exposes the position to price volatility.

To implement this model, we often assume linear forms for the impact functions, which leads to the closed-form solutions used in the following example:

g(x˙)=γx˙h(x˙)=η∣x˙∣\begin{aligned} g(\dot{x}) &= \gamma \dot{x} \\ h(\dot{x}) &= \eta |\dot{x}| \end{aligned}

where:

  • γ\gamma: permanent impact coefficient (distinct from the exponent γ\gamma in the square-root model)
  • η\eta: temporary impact coefficient
  • x˙\dot{x}: trading rate

The linear assumption is a simplification, but it yields closed-form optimal strategies. More realistic nonlinear impact functions require numerical optimization, but the qualitative insights from the linear case carry over.

Under these assumptions, the total permanent impact cost depends only on the total shares traded, making it path-independent. The optimization problem therefore simplifies to balancing temporary impact costs against volatility risk.

In[12]:
Code
def almgren_chriss_trajectory(X, T, n_periods, sigma, eta, gamma, lambd):
    """
    Calculate optimal trading trajectory using Almgren-Chriss model.

    Parameters:
    -----------
    X : float
        Total shares to liquidate
    T : float
        Time horizon (e.g., 1 for one day)
    n_periods : int
        Number of trading periods
    sigma : float
        Price volatility (per period)
    eta : float
        Temporary impact parameter
    gamma : float
        Permanent impact parameter
    lambd : float
        Risk aversion parameter

    Returns:
    --------
    t : array
        Time points
    x : array
        Shares remaining at each time
    trade_list : array
        Shares to trade in each period
    """
    tau = T / n_periods

    # Almgren-Chriss optimal parameter
    kappa_sq = lambd * sigma**2 / eta
    kappa = np.sqrt(kappa_sq)

    t = np.linspace(0, T, n_periods + 1)

    # Optimal trajectory
    sinh_kappa_T = np.sinh(kappa * T)
    x = X * np.sinh(kappa * (T - t)) / sinh_kappa_T

    # Trade list (shares to trade in each period)
    trade_list = -np.diff(x)

    return t, x, trade_list


# Parameters
X = 100000  # 100,000 shares to sell
T = 1.0  # 1 day
n_periods = 20  # Trade 20 times
sigma = 0.02  # 2% daily vol
eta = 0.0001  # Temporary impact
gamma = 0.0001  # Permanent impact

# Compare trajectories for different risk aversions
risk_aversions = [0.001, 0.01, 0.1]
trajectories = {}

for lambd in risk_aversions:
    t, x, trades = almgren_chriss_trajectory(
        X, T, n_periods, sigma, eta, gamma, lambd
    )
    trajectories[lambd] = {"t": t, "x": x, "trades": trades}
Out[13]:
Visualization
Line chart showing shares remaining over the trading day for three risk aversion levels; the high-aversion curve declines slightly faster than the low-aversion curve.
Optimal liquidation trajectories for three levels of risk aversion. The high-risk-aversion strategy (rose) liquidates somewhat faster to reduce variance, while the low-risk-aversion strategy (blue) retains positions slightly longer to minimize impact costs.
Out[14]:
Visualization
Grouped bar chart showing shares traded per period across 20 intervals for three risk aversion levels; higher aversion front-loads trading while lower aversion spreads volume evenly.
Trading volume per period across different risk aversion levels. The high-risk-aversion schedule (rose) is modestly front-loaded, while the low-risk-aversion schedule (blue) remains nearly uniform.

The key insight from the Almgren-Chriss model is that optimal execution depends critically on the tradeoff between market impact and timing risk. If you are risk-neutral, you would spread execution evenly over time (TWAP), while if you are risk-averse, you front-load execution to reduce exposure to volatility. We'll explore execution algorithms that implement these ideas in detail in the upcoming chapter on execution algorithms and optimal execution.