The strategy returned 34.7% annualized in backtesting. Sharpe ratio: 1.82. Maximum drawdown: −6.2%. The equity curve climbed steadily for three years across 847 trades. Confident numbers. Clean equity curve. Then you allocate $500,000 and deploy it live.

Within two weeks, realized returns crater to 12%. By month three, slippage has eroded performance so severely that the strategy barely outperforms cash. By month six, you are停下来重新思考——重新思考那句古老的格言:回测是过去的表现,不代表未来的结果。

Except this is not a forecasting failure. The strategy itself remains valid. The market regime has not changed. The signal is still there. What changed is your position size relative to available liquidity. You crossed the capacity threshold, and the market began to charge you a toll for every share you bought or sold.

This article is about that toll. We will build a rigorous framework for estimating strategy capacity before you write the first line of production code. We will examine the mathematics of market impact, implement working models in Python, and walk through a capacity estimation workflow you can apply to any strategy today.


Why Backtests Lie About Capacity

Backtest engines assume frictionless execution. When your Python backtest fills an order at the next bar's open price, it implicitly assumes:

  1. You could place the order without moving the market.
  2. The bid-ask spread would remain unchanged.
  3. Your order size would not influence subsequent price discovery.

None of these assumptions hold at meaningful capital scales. As your position size grows relative to average daily volume (ADV), three effects compound:

Market impact: Your own trades move prices against you. A buy order in a thinly traded name consumes available liquidity and bids the price up before your order is complete. The larger your order relative to ADV, the larger the adverse price move.

Spread capture: Every market order pays the bid-ask spread. In a backtest, you might model spread as a fixed cost per share. In live trading, as you consume multiple levels of the order book, your effective spread paid rises well beyond the L1 quote.

Timing risk: Larger orders take longer to fill. During that window, the market moves. Alpha decays. A signal that was valid at order entry may have partially evaporated by the time the position is established.

The cumulative effect of these three factors is called implementation shortfall — the gap between the decision price (where you decided to trade) and the final execution price. Capacity planning is, fundamentally, the art of modeling implementation shortfall before it destroys your returns.


The Volume Constraint Framework

The most fundamental constraint on any strategy is the market's willingness to absorb your orders without excessive price impact. This is measured by participation rate — the fraction of average daily volume (ADV) your strategy trades per day.

Participation Rate Typical Effect Capacity Implication
< 1% ADV/day Minimal market impact Most liquid names (SPY, QQQ) can absorb $10M–$50M/day
1–5% ADV/day Measurable impact; visible in order book Requires careful execution algorithm; capacity drops sharply
5–10% ADV/day Significant impact; price moves as you trade Strategy requires either longer horizon or larger ADV universe
> 10% ADV/day Dominated by impact; alpha largely captured by spread Generally uneconomical for non-institutional strategies

These are rough benchmarks. The actual impact depends on the asset's liquidity profile, intraday volume distribution, and whether you are trading with or against the trend.

Step one of any capacity estimate: calculate your ADV exposure.

import pandas as pd
import numpy as np
from dataclasses import dataclass
from typing import Optional
import os
import requests

@dataclass
class CapacityInputs:
    strategy_name: str
    avg_daily_trades: int           # Number of shares traded per day (all sides)
    avg_trade_size: float           # Average shares per trade
    avg_daily_volume: float         # ADV of the target asset (shares)
    avg_spread_bps: float            # Average bid-ask spread in basis points
    holding_period_days: float      # Average days a position is held
    expected_return_bps: float      # Expected alpha per trade in basis points

def calculate_participation_rate(inputs: CapacityInputs) -> dict:
    """
    Calculate daily and position-level participation metrics.
    
    Args:
        inputs: CapacityInputs with strategy and market parameters
    
    Returns:
        Dictionary with participation metrics and capacity indicators
    """
    daily_volume_traded = inputs.avg_daily_trades * inputs.avg_trade_size
    
    # Daily participation rate (both sides of volume)
    daily_participation = (daily_volume_traded / inputs.avg_daily_volume) * 100
    
    # One-sided participation (more relevant for directional impact)
    one_sided_participation = daily_participation / 2
    
    # Days to accumulate a full position (100% of ADV on one side)
    # This assumes you need to build a position of size: avg_daily_trades * holding_period_days
    target_position = inputs.avg_daily_trades * inputs.avg_trade_size * inputs.holding_period_days
    days_to_build = target_position / inputs.avg_daily_volume
    
    # Estimated capacity in dollars at 5% one-sided participation threshold
    # This is a conservative threshold where impact becomes material
    capacity_threshold = 0.05  # 5% of ADV
    dollar_capacity = (capacity_threshold * inputs.avg_daily_volume * inputs.avg_spread_bps) / 10000
    
    return {
        "daily_volume_traded": daily_volume_traded,
        "daily_participation_pct": round(daily_participation, 3),
        "one_sided_participation_pct": round(one_sided_participation, 3),
        "days_to_build_position": round(days_to_build, 2),
        "capacity_flag": "LOW" if one_sided_participation < 1 
                         else "MEDIUM" if one_sided_participation < 5 
                         else "HIGH",
        "estimated_dollar_capacity_5pct": dollar_capacity
    }

Practical note: The estimated_dollar_capacity_5pct field gives you a rough capital ceiling assuming you want to keep one-sided participation below 5% of ADV. This is a useful first filter, not a precise answer.


Market Impact Models

Participation rate tells you whether you have a problem. Market impact models tell you how severe that problem is.

The Square Root Model

The most widely used empirical model for market impact derives from the square root relationship between impact and participation:

$$MI = \sigma \times \sqrt{\frac{Q}{ADV}}$$

Where:

  • $MI$ = market impact (in price terms or basis points)
  • $\sigma$ = daily volatility of the asset
  • $Q$ = order size (shares)
  • $ADV$ = average daily volume (shares)

The square root relationship is supported by decades of empirical work across asset classes. It captures the intuition that impact grows with order size but at a decreasing rate — a 10-share order in a 1,000-share ADV name hurts less than twice as much as a 5-share order because you are penetrating fewer levels of the order book.

def square_root_impact(
    order_size: float,
    adv: float,
    daily_volatility_bps: float,
    participation_rate: Optional[float] = None
) -> dict:
    """
    Estimate market impact using the square root model.
    
    Args:
        order_size: Number of shares in the order
        adv: Average daily volume in shares
        daily_volatility_bps: Daily volatility in basis points
        participation_rate: Optional pre-computed participation rate
    
    Returns:
        Dictionary with impact estimates and cost breakdown
    """
    # Participation rate (fraction of ADV)
    if participation_rate is None:
        participation_rate = order_size / adv
    
    # Square root market impact
    # sigma is scaled by sqrt(Q/ADV)
    impact_bps = daily_volatility_bps * np.sqrt(participation_rate)
    
    # Impact as percentage
    impact_pct = impact_bps / 10000
    
    # Cost in dollars (assuming mid-price execution context)
    # Mid-price impact cost approximation
    estimated_mid_price = 100.0  # Would be actual mid in production
    cost_dollars = order_size * estimated_mid_price * impact_pct
    
    # Break-even alpha required to cover impact
    break_even_bps = impact_bps * 2  # Round-trip (entry + exit)
    
    return {
        "participation_rate": round(participation_rate * 100, 3),
        "impact_bps": round(impact_bps, 4),
        "impact_pct": round(impact_pct * 100, 4),
        "round_trip_cost_bps": round(break_even_bps, 4),
        "cost_dollars_approx": round(cost_dollars, 2),
        "break_even_return_pct": round(break_even_bps / 100, 2)
    }

# Example: A 50,000-share order in a stock with 2M ADV and 1.2% daily vol
example_result = square_root_impact(
    order_size=50_000,
    adv=2_000_000,
    daily_volatility_bps=120  # 1.2% daily vol
)
print(f"Impact: {example_result['impact_bps']:.4f} bps")
print(f"Round-trip cost: {example_result['round_trip_cost_bps']:.4f} bps")
print(f"Break-even return: {example_result['break_even_return_pct']:.2f}%")

The Almgren-Chriss Model

For more precise capacity planning, the Almgren-Chriss optimal execution framework provides a formal optimization. The model minimizes the expected cost plus variance of implementation shortfall:

$$E[C] + \lambda \cdot \text{Var}[C] = \sum_{i=1}^{n} \left( \eta \frac{x_i^2}{\sigma \sqrt{T}} + \frac{\gamma \sigma^2 T}{3} x_i^2 \right)$$

Where:

  • $x_i$ = shares traded in interval $i$
  • $\eta$ = temporary impact coefficient
  • $\gamma$ = permanent impact coefficient
  • $\sigma$ = volatility
  • $T$ = execution horizon
  • $\lambda$ = risk aversion parameter
from scipy.optimize import minimize
from typing import Tuple

def almgren_chriss_parameters(
    adv: float,
    daily_volatility_bps: float,
    spread_bps: float
) -> dict:
    """
    Calibrate Almgren-Chriss model parameters from market data.
    
    Args:
        adv: Average daily volume in shares
        daily_volatility_bps: Daily volatility in basis points
        spread_bps: Bid-ask spread in basis points
    
    Returns:
        Dictionary with calibrated temporary and permanent impact coefficients
    """
    sigma = daily_volatility_bps / 10000  # Daily volatility in decimal
    
    # Temporary impact coefficient (eta)
    # Based on the square root market impact literature
    eta = 0.314 * sigma * np.sqrt(adv)
    
    # Permanent impact coefficient (gamma)
    # Typically smaller than temporary; estimated from empirical data
    gamma = 0.5 * eta
    
    # Half-spread cost
    half_spread = spread_bps / 20000  # Convert bps to decimal
    
    return {
        "eta": eta,
        "gamma": gamma,
        "half_spread": half_spread,
        "sigma": sigma
    }

def optimal_execution_trajectory(
    total_shares: float,
    adv: float,
    n_intervals: int,
    risk_aversion: float,
    market_params: dict
) -> dict:
    """
    Compute optimal execution trajectory using Almgren-Chriss framework.
    
    Args:
        total_shares: Total shares to execute
        adv: Average daily volume
        n_intervals: Number of execution intervals (e.g., 20 = 20 intraday slices)
        risk_aversion: Risk aversion parameter (higher = more patient execution)
        market_params: Output from almgren_chriss_parameters
    
    Returns:
        Dictionary with optimal trajectory and expected cost metrics
    """
    sigma = market_params["sigma"]
    eta = market_params["eta"]
    gamma = market_params["gamma"]
    
    # T = execution horizon as fraction of day
    T = n_intervals / (6.5 * 60)  # Assumes 6.5-hour trading day in hours
    
    # Optimal execution rate under Almgren-Chriss
    # q_t = X * sinh(k*(T-t)) / sinh(k*T)
    # where k = sqrt(lambda * sigma^2 / eta)
    
    k = np.sqrt(risk_aversion * sigma**2 / eta)
    
    # Time grid
    t = np.linspace(0, T, n_intervals)
    
    # Optimal remaining shares at each interval
    remaining_shares = total_shares * np.sinh(k * (T - t)) / np.sinh(k * T)
    
    # Shares to execute in each interval (difference in remaining)
    interval_trades = -np.diff(remaining_shares, prepend=total_shares)
    
    # Expected temporary impact cost per interval
    interval_impacts = eta * sigma * np.sqrt(interval_trades / (adv * T / n_intervals))
    
    # Expected permanent impact
    permanent_impact = gamma * sigma * np.cumsum(interval_trades) / adv
    
    # Expected spread cost
    spread_cost = market_params["half_spread"] * np.sum(interval_trades)
    
    # Total expected cost
    total_temporary_impact = np.sum(interval_impacts * interval_trades)
    total_permanent_impact = np.sum(permanent_impact * interval_trades)
    total_cost = total_temporary_impact + total_permanent_impact + spread_cost
    
    # Participation rate per interval
    avg_interval_volume = adv * (T / n_intervals)
    participation_rates = (interval_trades / avg_interval_volume) * 100
    
    return {
        "trajectory": interval_trades.tolist(),
        "participation_rates_pct": participation_rates.tolist(),
        "expected_temporary_impact": total_temporary_impact,
        "expected_permanent_impact": total_permanent_impact,
        "expected_spread_cost": spread_cost,
        "total_expected_cost": total_cost,
        "cost_as_bps_of_notional": (total_cost / (total_shares * 100)) * 10000
    }

Slippage Estimation Workflow

With market impact modeled, we can now construct a practical slippage estimation workflow. This integrates volume constraints, impact models, and position sizing into a single capacity dashboard.

def estimate_capacity(
    strategy_name: str,
    total_capital: float,
    entry_price: float,
    adv: float,
    daily_volatility_bps: float,
    spread_bps: float,
    holding_period_days: float,
    expected_return_bps: float,
    target_participation_pct: float = 5.0
) -> dict:
    """
    Comprehensive capacity estimation for a trading strategy.
    
    Args:
        strategy_name: Name of the strategy
        total_capital: Total capital allocated to the strategy
        entry_price: Current price of the target asset
        adv: Average daily volume in shares
        daily_volatility_bps: Daily volatility in basis points
        spread_bps: Bid-ask spread in basis points
        holding_period_days: Average holding period in days
        expected_return_bps: Expected return per trade in basis points
        target_participation_pct: Maximum one-sided participation rate (%)
    
    Returns:
        Comprehensive capacity report
    """
    # Calculate shares per position
    shares_per_position = total_capital / entry_price
    
    # Daily trading volume (both sides)
    daily_volume = shares_per_position  # Approximation for single-name strategy
    
    # Participation rate
    participation_rate = (daily_volume / adv) * 100
    
    # Impact estimate using square root model
    impact_result = square_root_impact(
        order_size=shares_per_position,
        adv=adv,
        daily_volatility_bps=daily_volatility_bps
    )
    
    # Almgren-Chriss calibration
    market_params = almgren_chriss_parameters(adv, daily_volatility_bps, spread_bps)
    
    # Optimal execution over holding period
    # Assume we can execute over holding_period_days
    n_intervals = int(holding_period_days * 78)  # ~78 5-minute bars per trading day
    optimal = optimal_execution_trajectory(
        total_shares=shares_per_position,
        adv=adv,
        n_intervals=max(n_intervals, 10),
        risk_aversion=1e-6,
        market_params=market_params
    )
    
    # Capacity at target participation
    capacity_shares = (target_participation_pct / 100) * adv
    capacity_dollars = capacity_shares * entry_price
    
    # Realized return after costs
    round_trip_cost_bps = impact_result["round_trip_cost_bps"]
    net_return_bps = expected_return_bps - round_trip_cost_bps
    net_return_pct = net_return_bps / 100
    
    # Return degradation from capacity constraints
    gross_return_pct = expected_return_bps / 100
    return_retention = (net_return_pct / gross_return_pct) * 100 if gross_return_pct > 0 else 0
    
    # Capacity verdict
    if capacity_dollars < total_capital * 0.5:
        verdict = "CAPACITY CONSTRAINED"
        recommendation = f"Reduce position size to ${capacity_dollars:,.0f} or expand to {int(adv * 10):,} share ADV universe"
    elif capacity_dollars < total_capital * 1.5:
        verdict = "NEAR CAPACITY"
        recommendation = "Monitor participation rates closely; consider extending execution horizon"
    else:
        verdict = "WITHIN CAPACITY"
        recommendation = "Strategy can absorb current capital allocation"
    
    return {
        "strategy": strategy_name,
        "capital_allocated": total_capital,
        "shares_per_position": int(shares_per_position),
        "participation_rate_pct": round(participation_rate, 3),
        "impact_cost_bps": round(round_trip_cost_bps, 2),
        "net_return_bps": round(net_return_bps, 2),
        "return_retention_pct": round(return_retention, 1),
        "capacity_dollars": capacity_dollars,
        "capacity_verdict": verdict,
        "recommendation": recommendation,
        "execution_details": {
            "optimal_interval_trades": optimal["trajectory"][:5],  # First 5 intervals
            "avg_participation_pct": round(np.mean(optimal["participation_rates_pct"]), 3),
            "total_cost_dollars": round(optimal["total_expected_cost"], 2)
        }
    }

Building a Capacity Dashboard

For live strategy monitoring, wrap your capacity estimation into a real-time dashboard. This example uses a simple dataclass architecture that integrates with TickDB for live market data:

import pandas as pd
from datetime import datetime
import json

class CapacityMonitor:
    """
    Real-time capacity monitoring for deployed strategies.
    Integrates with TickDB for live ADV and volatility data.
    """
    
    def __init__(self, api_key: str):
        self.api_key = api_key
        self.base_url = "https://api.tickdb.ai/v1"
        self.headers = {"X-API-Key": api_key}
        self._session = None
    
    def _get_session(self):
        """Lazy initialization of requests session with timeout."""
        if self._session is None:
            import requests
            self._session = requests.Session()
            self._session.headers.update(self.headers)
            self._session.headers["User-Agent"] = "TickDB-CapacityMonitor/1.0"
        return self._session
    
    def get_live_adv(self, symbol: str, lookback_days: int = 30) -> Optional[float]:
        """
        Fetch 30-day average daily volume from TickDB kline data.
        
        Args:
            symbol: Market symbol (e.g., "AAPL.US")
            lookback_days: Number of trading days for ADV calculation
        
        Returns:
            Average daily volume in shares, or None if unavailable
        """
        session = self._get_session()
        
        # Fetch daily klines to calculate ADV
        try:
            response = session.get(
                f"{self.base_url}/market/kline",
                params={
                    "symbol": symbol,
                    "interval": "1d",
                    "limit": lookback_days
                },
                timeout=(3.05, 10)
            )
            response.raise_for_status()
            data = response.json()
            
            if data.get("code") != 0:
                return None
            
            klines = data.get("data", {}).get("klines", [])
            
            if not klines:
                return None
            
            # ADV = average of (close * volume) normalized to shares
            # For US equities: volume field is already shares
            volumes = [float(k[5]) for k in klines]  # Volume is index 5 in kline
            return sum(volumes) / len(volumes)
            
        except requests.exceptions.Timeout:
            print(f"Timeout fetching ADV for {symbol}")
            return None
        except Exception as e:
            print(f"Error fetching ADV for {symbol}: {e}")
            return None
    
    def get_live_volatility(self, symbol: str, lookback_days: int = 20) -> Optional[float]:
        """
        Calculate realized volatility from TickDB kline data.
        
        Returns:
            Daily volatility in basis points
        """
        session = self._get_session()
        
        try:
            response = session.get(
                f"{self.base_url}/market/kline",
                params={
                    "symbol": symbol,
                    "interval": "1d",
                    "limit": lookback_days + 1
                },
                timeout=(3.05, 10)
            )
            response.raise_for_status()
            data = response.json()
            
            if data.get("code") != 0:
                return None
            
            klines = data.get("data", {}).get("klines", [])
            
            if len(klines) < 2:
                return None
            
            # Calculate daily returns
            closes = [float(k[4]) for k in klines]  # Close is index 4
            returns = [np.log(closes[i] / closes[i-1]) for i in range(1, len(closes))]
            
            # Daily volatility (annualized and scaled to bps)
            daily_vol = np.std(returns) * np.sqrt(252) * 10000
            
            return daily_vol
            
        except Exception as e:
            print(f"Error calculating volatility for {symbol}: {e}")
            return None
    
    def run_capacity_check(
        self,
        symbol: str,
        position_size_dollars: float,
        current_price: float,
        holding_period_days: float,
        expected_return_bps: float
    ) -> dict:
        """
        Run full capacity check for a given position.
        
        Returns:
            Capacity report with live market data from TickDB
        """
        adv = self.get_live_adv(symbol, lookback_days=30)
        volatility = self.get_live_volatility(symbol, lookback_days=20)
        
        # Default spread assumption (can be enhanced with depth data)
        estimated_spread_bps = 5.0  # 5 bps for liquid US equity
        
        if adv is None or volatility is None:
            return {
                "symbol": symbol,
                "status": "INSUFFICIENT_DATA",
                "message": "Could not fetch live market data from TickDB"
            }
        
        result = estimate_capacity(
            strategy_name=f"Position-{symbol}",
            total_capital=position_size_dollars,
            entry_price=current_price,
            adv=adv,
            daily_volatility_bps=volatility,
            spread_bps=estimated_spread_bps,
            holding_period_days=holding_period_days,
            expected_return_bps=expected_return_bps
        )
        
        result["symbol"] = symbol
        result["status"] = "COMPLETE"
        result["live_adv"] = int(adv)
        result["live_volatility_bps"] = round(volatility, 2)
        
        return result

Capacity Estimation in Practice: A Worked Example

Consider a mean-reversion strategy trading a mid-cap US stock with the following parameters:

Parameter Value
Strategy capital $2,000,000
Entry price $45.00
30-day ADV 3,200,000 shares
Daily volatility 1.8% (180 bps)
Bid-ask spread 2.5 bps
Holding period 2 days
Expected return per trade 45 bps

Running the capacity estimation:

monitor = CapacityMonitor(api_key=os.environ.get("TICKDB_API_KEY"))

report = monitor.run_capacity_check(
    symbol="XYZ.US",
    position_size_dollars=2_000_000,
    current_price=45.00,
    holding_period_days=2,
    expected_return_bps=45
)

# Expected output:
# participation_rate_pct: 2.78%
# impact_cost_bps: 3.01 bps
# net_return_bps: 41.99 bps
# return_retention_pct: 93.3%
# capacity_verdict: NEAR CAPACITY
# capacity_dollars: $1,440,000

At $2M, the strategy is near its capacity ceiling. The impact cost of 3.01 bps per round-trip consumes 6.7% of gross alpha. The $1.44M capacity ceiling is derived from the 5% participation threshold — at that level, market impact begins to materially degrade returns.

The recommendation: either reduce position size to $1.4M, extend the holding period to 3 days to spread execution over more ADV, or diversify across multiple names with similar characteristics.


Capacity Across Asset Classes

The capacity estimation framework applies across all liquid asset classes, but the parameters shift significantly:

Asset Class Typical ADV Typical Daily Vol Spread Capacity Multiplier
Large-cap US equity (SPY-component) 10M–100M shares 80–150 bps 1–3 bps High
Mid-cap US equity 1M–10M shares 120–200 bps 3–8 bps Medium
Small-cap US equity 100K–1M shares 200–500 bps 10–30 bps Low
Large-cap crypto (BTC, ETH) $2B–$10B notional 300–600 bps 2–10 bps Medium-High
Liquid futures (ES, NQ) 1M–3M contracts 100–180 bps 0.25–0.5 bps Very High

Crypto assets present a unique case: high volatility and wide spreads coexist with massive notional volume, producing capacity profiles that resemble large-cap equities despite the asset class's retail-dominated microstructure.


Mitigation Strategies

When your strategy exceeds its capacity ceiling, five approaches can recover alpha:

1. Extend execution horizon: Spreading an order over more intervals reduces participation rate per interval. The square root model shows that doubling execution time roughly halves instantaneous impact.

2. Increase ADV universe: Adding correlated names allows you to distribute position size across multiple liquid instruments. A strategy that fits $500K into one name can allocate $5M across 10 correlated names with similar liquidity profiles.

3. Reduce holding period: Shorter holding periods mean smaller positions at any given moment, keeping participation rates lower. This is a fundamental reason why high-frequency strategies have higher capacity than swing trade strategies in the same names.

4. Switch to limit orders: Market orders pay full spread and consume all levels of the book. Limit orders posted at mid or better passively capture the spread and avoid consumption of multiple book levels. The tradeoff: limit orders carry execution risk (non-fill) in fast markets.

5. Tiered position building: Establish a core position immediately (market order for urgent alpha) and layer a tactical position using limit orders over time. This hybrid approach captures immediate signal while managing long-term impact costs.


Closing

The difference between a strategy that survives live deployment and one that implodes under real capital is rarely the signal quality. It is the gap between what the backtest assumes about execution and what the market actually charges for your order flow.

Capacity estimation closes that gap before you write the first production ticket. The models and code in this article give you the tools to:

  1. Measure participation rate relative to ADV.
  2. Model market impact using the square root model and Almgren-Chriss framework.
  3. Calculate break-even alpha thresholds at your target position size.
  4. Monitor live capacity using TickDB market data.

Run the capacity check before you allocate capital. The cost of running it is one afternoon. The cost of not running it is discovering your true capacity ceiling in realized drawdowns.


Next Steps

If you are backtesting a new strategy: Integrate the capacity estimation workflow into your backtesting pipeline and generate a capacity report alongside every strategy report.

If you want to run this analysis on your current portfolio: Sign up at tickdb.ai (free, no credit card required), generate an API key, and use the CapacityMonitor class above to pull live ADV and volatility data for your positions.

If you need historical volume data for capacity analysis across multiple years: Reach out to enterprise@tickdb.ai for institutional data plans covering 10+ years of cleaned, aligned OHLCV data across US equities, crypto, and international markets.

If you use AI coding assistants: Search for and install the tickdb-market-data SKILL in your AI tool's marketplace for streamlined API access and pre-built analysis templates.


This article does not constitute investment advice. Markets involve risk; past performance does not guarantee future results. Capacity estimates are based on historical market data and statistical models; actual market impact may differ from model predictions due to regime changes, market structure shifts, or unexpected liquidity events.