Skip to content

Transaction Cost-Aware Portfolio Optimization

Gârleanu & Lasry-Maggi-Pedersen turnover models. How to bake transaction costs into MVO. The math and the practice of not destroying your returns with rebalancing.

11 of 12 ~14 min

Markowitz’s optimization assumes frictionless trading. You can rebalance to the optimal weights at any frequency with zero cost. This is roughly true for institutional investors trading the S&P 500 in $10M clips. It is brutally false for everyone else.

A long-only equity portfolio that rebalances monthly has annual turnover around 50-150%. At 10 basis points of round-trip transaction costs, that’s 50-150 bps of annual drag. For a portfolio earning 8%, this is a 6-19% reduction in net returns.

A long-short equity portfolio rebalancing weekly can have 1000%+ annual turnover. At 50 bps round-trip, that’s 500 bps of drag. Half your alpha, gone.

Transaction cost-aware optimization adds turnover penalties to the standard MVO objective. The result: portfolios that don’t try as hard to hit the unconstrained optimum, but produce better net-of-cost returns.

This article covers the Gârleanu & Lasry-Maggi-Pedersen turnover model, the Almgren-Chriss market impact model, and practical implementation.

The Cost Structure

Trading costs have three components.

Commissions and fees: fixed per share or per dollar. For institutional equity trading, often near zero in major markets. For less liquid assets, can be 1-5 bps.

Bid-ask spread: the cost of crossing the spread to trade. Half-spread per side, full spread round-trip. For large-cap US equities, 1-5 bps. For small-cap, 10-50 bps. For less liquid markets, much more.

Market impact: the cost of moving the price by trading. Larger trades move prices more. This is the dominant cost for institutional sizes. Roughly σ⋅Q/ADV\sigma \cdot \sqrt{Q/ADV} where QQ is trade size, ADVADV is average daily volume, σ\sigma is daily vol.

Total transaction cost for a round-trip trade of size QQ:

TC(Q)=cfixed+cspread+cimpact⋅(QADV)α\text{TC}(Q) = c_{\text{fixed}} + c_{\text{spread}} + c_{\text{impact}} \cdot \left(\frac{Q}{ADV}\right)^\alpha

For institutional equity trading, the dominant term is cimpact⋅(Q/ADV)αc_{\text{impact}} \cdot (Q/ADV)^\alpha with α\alpha around 0.5-0.7. This is the square-root law of market impact.

The Square-Root Law

A massive empirical literature (Barra, Bloomberg, ITG, Virtu, and many academic papers) finds that market impact scales roughly as the square root of trade size relative to ADV:

Impact(Q)≈Y⋅σ⋅QADV\text{Impact}(Q) \approx Y \cdot \sigma \cdot \sqrt{\frac{Q}{ADV}}

where YY is a constant around 0.1-1.0 (depending on the asset and the trading venue), σ\sigma is daily volatility, and ADVADV is average daily volume.

For an asset with σ=2%\sigma = 2\% daily, ADV = \10M$, and a $$1M$trade: impact is$0.5 \cdot 0.02 \cdot \sqrt{0.1} = 0.3%$. That’s 30 bps of market impact for one-way, 60 bps round-trip. Significant.

For a \100K$trade in the same asset: impact is$0.5 \cdot 0.02 \cdot \sqrt{0.01} = 0.1%$. Round-trip 20 bps. Less significant, but still real.

Gârleanu’s Continuous-Time Model

Gârleanu (2009) and Gârleanu & Pedersen (2013) developed a continuous-time portfolio optimization model with proportional transaction costs.

The setup: at each instant, the investor can rebalance the portfolio by trading. Trading incurs a cost proportional to the trade size:

TC(t)=c⋅∥w(t)−w(t−)∥1\text{TC}(t) = c \cdot \|w(t) - w(t^-)\|_1

where cc is a constant proportional cost (e.g., 10 bps per side) and the L1 norm is the sum of absolute trade sizes.

The investor maximizes expected utility of terminal wealth net of integral transaction costs:

max⁡wE[U(WT)−∫0Tc∥dw(t)∥1]\max_w \mathbb{E}\left[U(W_T) - \int_0^T c \|dw(t)\|_1 \right]

This is a stochastic control problem. The solution involves a “no-trade region” — a band around the optimal weights within which rebalancing is too expensive to justify.

Specifically, the optimal policy is:

  • If wiw_i is within a band around wi⋆w_i^\star (the frictionless optimum), don’t trade.
  • If wiw_i drifts outside the band, trade back to the band edge (not all the way to the new optimum).

The width of the band scales with c/λσ2\sqrt{c / \lambda \sigma^2}, where λ\lambda is risk aversion and σ2\sigma^2 is return variance. Higher transaction costs widen the band. Higher risk aversion or volatility narrows it.

This is the formal reason why “rebalance monthly” is a sensible default for most institutional portfolios. The optimal rebalancing frequency falls out of the math.

Almgren-Chriss Market Impact

Almgren & Chriss (2000) is the canonical reference for optimal execution with market impact. They consider a trader who needs to liquidate (or acquire) a position over a horizon TT, minimizing total cost:

E[TC]=∑tImpact(Qt)+λ⋅Var(TC)\mathbb{E}[\text{TC}] = \sum_t \text{Impact}(Q_t) + \lambda \cdot \text{Var}(\text{TC})

where QtQ_t is the trade size at time tt, Impact(Qt)\text{Impact}(Q_t) is the temporary market impact, and the variance term captures timing risk.

The optimal execution trajectory is approximately:

Qt=Q0⋅sinh⁡(κ(T−t))/sinh⁡(κT)Q_t = Q_0 \cdot \sinh(\kappa (T - t)) / \sinh(\kappa T)

where κ\kappa depends on the risk aversion λ\lambda and the impact parameters. For low risk aversion, the trajectory is roughly linear (VWAP). For high risk aversion, it’s front-loaded (trade quickly to reduce timing risk).

This model is widely used in execution algorithms. Most sell-side execution platforms (Goldman Sachs Redi, JPMorgan’s algo suite, etc.) are built on Almgren-Chriss or one of its descendants.

Incorporating Costs Into MVO

Back to portfolio optimization. Add transaction costs to the standard MVO objective:

min⁡w12w⊤Σw−λw⊤μ+c∥w−w0∥1s.t.1⊤w=1,w≥0\begin{aligned} \min_{w} \quad & \frac{1}{2} w^\top \Sigma w - \lambda w^\top \mu + c \|w - w_0\|_1 \\ \text{s.t.} \quad & \mathbf{1}^\top w = 1, \quad w \geq 0 \end{aligned}

where w0w_0 is the current portfolio and cc is the cost per unit of trade. The L1 norm captures the proportional transaction cost structure.

This is a quadratic program with an L1 penalty. It’s convex, so solve with any standard QP solver.

The key parameter is cc. Set it too low and you’ll rebalance too often, paying excessive transaction costs. Set it too high and you’ll trade too little, drifting away from the optimum.

A reasonable starting point: cc equal to one-way transaction costs in basis points converted to the same scale as λw⊤μ\lambda w^\top \mu. So if expected excess return is 5% annualized and one-way costs are 10 bps, cc is about 2% of the expected return.

In code:

import cvxpy as cp

w = cp.Variable(n_assets)
w_current = np.array([...])  # Current weights
mu = np.array([...])
Sigma = np.array([...])
lam = 2.5  # Risk aversion
c = 0.001  # One-way cost, 10 bps

objective = cp.quad_form(w, Sigma) - lam * (mu @ w) + c * cp.norm1(w - w_current)
constraints = [cp.sum(w) == 1, w >= 0]

problem = cp.Problem(cp.Minimize(objective), constraints)
problem.solve()

w_new = w.value
turnover = np.abs(w_new - w_current).sum() / 2  # One-way turnover

The solution will trade off variance reduction against transaction costs. The optimal portfolio is closer to w0w_0 than the frictionless optimum would be.

Multi-Period Optimization

A more sophisticated approach: optimize over multiple periods jointly, accounting for future rebalancing.

The Gârleanu-Lasry-Maggi-Pedersen framework (subsequently refined by Abad, Gârleanu, Hörter, and others) sets up a multi-period optimization where the investor knows they’ll rebalance at future dates and pays transaction costs at each.

The solution is “forward-looking”. The optimal trade today accounts for the cost of trading tomorrow, and the cost of trading tomorrow accounts for trading the day after, etc.

Implementation is via dynamic programming:

Vt(w)=max⁡w′[U(w′⋅rt)+E[Vt+1(w′)]−c∥w′−w∥1]V_t(w) = \max_{w'} \left[ U(w' \cdot r_t) + \mathbb{E}[V_{t+1}(w')] - c \|w' - w\|_1 \right]

The state is the current weights ww. The control is the new weights w′w'. The transition is stochastic (depends on returns rtr_t). The cost is the L1 trade.

For tractability, the value function Vt(w)V_t(w) is often approximated by a quadratic in ww around the frictionless optimum. This gives closed-form (or near-closed-form) solutions that are easy to implement.

In production: most multi-period optimizers use this approach. Axioma’s portfolio optimizer, Bloomberg’s PORT, and BarraOne all have variants.

Practical Tips

Five things that matter in production.

Tip 1: Estimate costs accurately. Use TCA (transaction cost analysis) reports from your execution desk. Don’t use textbook values. Spreads and impacts vary enormously across assets, time of day, and market regime.

Tip 2: Don’t optimize costs at the expense of the alpha model. If your alpha signal is strong, you’ll want to trade. Penalizing turnover too heavily will make you miss alpha. The cost penalty should be tuned to your specific alpha decay profile.

Tip 3: Use separate models for different asset classes. Equity costs are different from bond costs, which are different from futures costs. A unified cost model loses too much information.

Tip 4: Account for the closed period. Many institutional portfolios have a “closed period” before quarter-end when trading is restricted for compliance reasons. The optimizer should know this and front-load trades.

Tip 5: Include a liquidity budget. Some shops have a maximum amount they can trade per day across the firm. The optimizer needs to respect this aggregate constraint, not just per-asset constraints.

The Turnover Tax

Even with cost-aware optimization, most active portfolios have meaningful turnover. The “turnover tax”, total annual transaction costs, is real.

For a long-short equity hedge fund with 200% annual turnover and 25 bps round-trip costs, turnover tax is 50 bps. Pre-fee alpha needs to exceed 50 bps just to break even.

For a long-only institutional manager with 50% turnover and 5 bps costs, turnover tax is 2.5 bps. Small enough to ignore.

The turnover tax is the silent killer of active management. Cost-aware optimization doesn’t eliminate it, but it manages it. The alternative, running the unconstrained Markowitz solution, is much worse.

When Cost-Aware Optimization Matters Most

Three regimes where it really matters:

  1. High-turnover strategies: short-horizon alpha, market-neutral equity, statistical arbitrage. These can have 1000%+ annual turnover. Cost-aware optimization is essential.

  2. Illiquid assets: small-cap equities, emerging market debt, private credit. Spreads and impacts are large. The cost of rebalancing is a meaningful fraction of the alpha.

  3. Capacity-constrained strategies: as AUM grows, trades move prices more. Cost-aware optimization is how you manage the capacity curve.

In contrast, for low-turnover long-only institutional portfolios (pension funds, sovereign wealth funds), cost-aware optimization is nice-to-have but not critical. The default unconstrained MVO may be fine.

What the Literature Says

  • Almgren & Chriss (2000). “Optimal Execution of Portfolio Transactions.” Journal of Risk 3(2): 5-39. The execution model.
  • Gârleanu (2009). “Portfolio Choice and Pricing in Discrete-Time Markets with Proportional Transaction Costs.” Journal of Economic Theory 144(4): 1629-1662.
  • Gârleanu & Pedersen (2013). “Dynamic Trading with Predictable Returns and Transaction Costs.” Journal of Finance 68(6): 2309-2340.
  • Lasry, Maggi, Pedersen & Gârleanu (2007). “Dynamic Trading and Asset Prices: Keynes vs. Hayek.” Review of Finance 11(3): 397-425.
  • Bertsimas & Lo (1998). “Optimal Control of Execution Costs.” Journal of Financial Markets 1(1): 1-50. Early execution optimization.
  • Kissell, Glantz & Malamut (2003). “Optimal Trading Strategies.” Quantitative Finance 3(5): 375-387. Practical guide.
  • Frazzini, Israel & Moskowitz (2018). “Trading Costs of Asset Pricing Anomalies.” SSRN Working Paper. The trading cost of harvesting factors.
  • Abad, Gârleanu & Hörter (2019). “A Tractable Production-Based Asset Pricing Model with Transaction Costs.” Journal of Finance 74(4): 1653-1699.

Almgren-Chriss in Detail

The Almgren-Chriss (2000) model considers a trader who needs to liquidate QQ shares over a horizon TT. The trader chooses a trajectory x(t)x(t) of remaining shares to liquidate, x(0)=Qx(0) = Q and x(T)=0x(T) = 0.

The execution is broken into discrete trades. At each time tt, the trader sells n(t)=x(t−1)−x(t)n(t) = x(t-1) - x(t) shares. The cost of each trade has two components:

Temporary impact: prices move against the trader during execution. For a trade of size nn, the temporary impact cost is:

h(n)=η⋅nVh(n) = \eta \cdot \frac{n}{V}

where VV is the rate of trading volume (shares per unit time) and η\eta is a constant. Temporary impact is paid on every trade.

Permanent impact: prices move permanently after large trades. For a trade of size nn, the permanent impact is:

g(n)=γ⋅ng(n) = \gamma \cdot n

where γ\gamma is a constant. Permanent impact is a one-time cost per trade.

Total expected cost:

E[C]=∑t(h(nt)+g(nt))⋅P0\mathbb{E}[C] = \sum_t (h(n_t) + g(n_t)) \cdot P_0

where P0P_0 is the initial price.

Total variance of cost (timing risk):

Var[C]=σ2∑t(t⋅nt)2\text{Var}[C] = \sigma^2 \sum_t (t \cdot n_t)^2

The trader minimizes a weighted sum of expected cost and variance:

min⁡xE[C]+λ⋅Var[C]\min_x \mathbb{E}[C] + \lambda \cdot \text{Var}[C]

The solution is a trajectory of the form:

x(t)=Q⋅sinh⁡(κ(T−t))sinh⁡(κT)x(t) = Q \cdot \frac{\sinh(\kappa(T-t))}{\sinh(\kappa T)}

where κ=λσ2/η\kappa = \sqrt{\lambda \sigma^2 / \eta} depends on the risk aversion λ\lambda and the impact parameter η\eta.

For κ\kappa small (low risk aversion), the trajectory is roughly linear: VWAP. For κ\kappa large (high risk aversion), the trajectory is front-loaded: trade quickly to reduce timing risk.

The Square-Root Law in More Detail

The square-root law of market impact:

Impact(Q)≈Y⋅σdaily⋅QADV\text{Impact}(Q) \approx Y \cdot \sigma_{\text{daily}} \cdot \sqrt{\frac{Q}{ADV}}

is one of the most robust empirical regularities in trading. Almgren, Thum, Hauptmann & Li (2005) and others have documented it across markets and asset classes.

The constants depend on the market:

  • US large-cap equities: Y≈0.1Y \approx 0.1 to 0.30.3
  • US small-cap equities: Y≈0.3Y \approx 0.3 to 1.01.0
  • US Treasuries: Y≈0.05Y \approx 0.05 to 0.150.15
  • FX: Y≈0.1Y \approx 0.1 to 0.30.3
  • Crypto: Y≈0.5Y \approx 0.5 to 2.02.0 (much higher)

For institutional trading, the square-root law is a useful first approximation. For more precise impact estimates, you need transaction-cost-analysis (TCA) data from your own execution.

Continuous-Time Trading with Costs

Gârleanu & Pedersen (2013) formulated continuous-time portfolio choice with proportional transaction costs. The investor maximizes:

max⁡wE0[U(WT)−∫0Tc⋅∥w˙(t)∥1dt]\max_w \mathbb{E}_0\left[ U(W_T) - \int_0^T c \cdot \|\dot{w}(t)\|_1 dt \right]

where w˙(t)\dot{w}(t) is the rate of trading and cc is the cost per unit.

The first-order condition for the optimal trading rate gives:

w˙i(t)=1c⋅(value of wi at frictionless optimum−current wi)+\dot{w}_i(t) = \frac{1}{c} \cdot \left( \text{value of } w_i \text{ at frictionless optimum} - \text{current } w_i \right)^+

In words: trade if and only if the deviation from the frictionless optimum exceeds a threshold proportional to cc. The threshold depends on risk aversion and return volatility.

The result is a “no-trade region” around the frictionless optimum. The investor trades only when the portfolio drifts far enough from the optimum to justify the cost.

This is the formal justification for “rebalance quarterly” type rules. The optimal rebalancing frequency falls out of the math.

The Cost-Aware Black-Litterman

A natural combination: Black-Litterman expected returns with transaction cost penalty.

The objective:

max⁡ww⊤μBL−γ2w⊤Σw−c∥w−w0∥1\max_w w^\top \mu_{\text{BL}} - \frac{\gamma}{2} w^\top \Sigma w - c \|w - w_0\|_1

subject to long-only and budget.

This is a QP with an L1 penalty. Solvable with standard tools. The result is a portfolio that:

  • Anchors to market (via Black-Litterman prior)
  • Tilts by views (scaled by confidence)
  • Penalizes turnover (via cost term)
  • Respects constraints

This is a workhorse institutional allocation model. Used by many large asset managers.

Turnover Targets

Many institutional mandates have turnover limits. “Maximum 50% annual turnover” is a common constraint.

Implementing turnover limits in optimization:

∑t∥w(t)−w(t−1)∥1≤Tmax\sum_t \|w^{(t)} - w^{(t-1)}\|_1 \leq T_{\text{max}}

This is a linear constraint. Adds to the QP.

In practice, turnover limits interact with the cost penalty. The cost penalty discourages all turnover; the turnover limit forbids large turnover. They’re complementary.

Some shops use only the turnover limit (no cost penalty in the objective). Others use only the cost penalty (no turnover limit). The combination is rare but defensible.

Market Impact in Practice

Most institutional traders have a market impact model calibrated to their own trading data. The models vary, but most are based on:

  • The square-root law (Almgren et al., 2005)
  • The I-star model (Kissell, Glantz & Malamut, 2003)
  • Proprietary models based on TCA data

For a backtest, the simple square-root law with conservative YY is usually good enough. For production execution, you want a more detailed model.

The standard implementation:

def estimate_impact(Q, ADV, sigma, Y=0.3):
    """Square-root market impact."""
    return Y * sigma * np.sqrt(Q / ADV)

def optimal_trade_schedule(Q, T, ADV, sigma, lambda_param, eta):
    """Almgren-Chriss optimal trajectory."""
    kappa = np.sqrt(lambda_param * sigma**2 / eta)
    t = np.arange(T + 1)
    x = Q * np.sinh(kappa * (T - t)) / np.sinh(kappa * T)
    n = -np.diff(x)  # Trade sizes
    return n

This gives you the optimal execution trajectory. Implement with a VWAP algorithm or a more sophisticated execution algo.

When Cost-Aware Optimization Loses

Three regimes where cost-aware optimization produces bad portfolios.

Regime 1: Cost parameters too high. If you set cc too high, the optimizer doesn’t trade even when it should. The portfolio drifts away from the optimum and never rebalances.

Regime 2: Cost parameters too low. If you set cc too low, the optimizer trades too aggressively. High turnover, high costs, low net returns.

Regime 3: Wrong cost model. If the actual cost structure is non-linear (e.g., increasing in trade size due to liquidity constraints), the linear cost penalty misses this.

The fix for all three: calibrate cc to your actual costs via TCA analysis. Run sensitivity analysis on cc. Test the optimizer on historical data and check realized costs.

What to Remember

Transaction costs are real and they’re significant. Markowitz’s frictionless MVO ignores them and can lose money by rebalancing too much.

Two model families: Almgren-Chriss (optimal execution with market impact) and Gârleanu-Pedersen (multi-period portfolio choice with proportional costs). Both are tractable and well-implemented in production tools.

Add cost to the MVO objective as an L1 penalty on turnover. Tune the cost parameter to your specific alpha decay profile. The Almgren-Chriss trajectory is the optimal execution path; the Gârleanu-Pedersen model gives the no-trade region for continuous rebalancing.

The square-root law of market impact is a robust empirical regularity. It depends on ADV, volatility, and a market-specific constant.

The turnover tax is the silent killer of active management. Cost-aware optimization is a tool, not a substitute for good alpha. The combination with Black-Litterman gives a defensible institutional allocation model.

Turnover targets are common in institutional mandates. They’re complementary to cost penalties but not always both used.

Next article: robust portfolio optimization. Optimize the worst case over an uncertainty set.