6.2.5Backtesting Frameworks

Understand transaction cost modeling

2,994 words14 min readdifficulty · medium2 backlinks

What Are Transaction Costs?

Transaction costs are the real money you lose beyond the quoted market price when executing trades. They have three main components:

Why Each Component Exists

Commissions: Brokers charge for providing infrastructure, routing orders, regulatory compliance. Why it matters: even "zero-commission" brokers make money via payment-for-order-flow, which often results in worse execution (hidden slippage).

Slippage: Markets move between when you decide to trade and when your order fills. Why it matters: in volatile markets or with slow execution, slippage can exceed0.5% per trade. A market order during low liquidity might fill 2-3 ticks away from the midpoint.

Market Impact: Large orders move prices against you—buying pushes prices up, selling pushes them down. Why it matters: for big positions relative to daily volume, your order becomes visible and other traders adjust. A 1Mbuyinastockwith1M buy in a stock with 10M daily volume creates measurable impact.

Deriving the Total Cost Formula

Let's build the transaction cost model from first principles.

Step 1: Commission Model

Why this formula? Brokers charge the greater of a minimum fee or a percentage. For small trades, you hit the minimum. For large trades, the percentage kicks in.

Example:

  • Trade: Buy 100 shares at $50
  • Broker: $1 fixed or 0.1% of trade value
  • Trade = 50×100=50 × 100 = 5,000
  • Percentage fee = 0.001 × 5,000=5,000 = 5
  • Commission = max(1,1, 5) = $5

Why this step? We take the maximum because broker always charges at least the fixed fee, but switches to percentage for bigger trades to earn more.

Step 2: Slippage Model

Why this formula?

  1. Spread component (α×spread×Q\alpha \times \text{spread} \times Q): Market orders cross the spread. You pay the ask when buying (instead of the mid), so you lose half the spread per share as baseline.
  2. Volatility component (β×σ×Q\beta \times \sigma \times \sqrt{Q}): In volatile markets, prices move while your order fills. The Q\sqrt{Q} captures that larger orders take longer to fill (more time = more price drift). This is empirically observed in order execution data.

Example:

  • Bid: 49.95,Ask:49.95, Ask: 50.05, Spread: $0.10
  • Volatility σ: $0.20 per 5 minutes
  • Buy 500 shares with market order
  • α = 0.5, β = 0.1

Spread cost = 0.5 × 0.10×500=0.10 × 500 = **25** Volatility cost = 0.1 × 0.20×500=0.1×.20×22.360.20 × √500 = 0.1 × .20 × 22.36≈ **0.45** Total slippage ≈ $25.45

Why this step? The spread cost dominates because we're crossing from bid to ask. The volatility term is small here but grows in fast markets or with larger orders.

Step 3: Market Impact Model

Why this formula? This is the Almgren-Chriss market impact model, derived from empirical observations:

  1. Square-root of order fraction: Impact isn't linear. A 1% order doesn't cause 10× the impact of a 0.1% order—liquidity pools absorb small orders better. The square root models diminishing marginal impact.
  2. Volatility scaling: In volatile stocks, price moves are already large, so your order's contribution blends in. In calm stocks, your order stands out more.
  3. Proportional to order value: Bigger dollar amounts = more impact.

Derivation intuition: Think of market depth as a resource that gets "used up" by your order. The first100 shares barely move the price (lots of resting orders at the best bid/ask). The next 1,000 shares eat through several price levels. The rate of price change per share increases as you go deeper—but sublinearly (square root).

Example:

  • Stock price P=P = 100
  • Daily volume V=1,000,000V = 1,000,000 shares
  • Your order Q=10,000Q = 10,000 shares (1% of daily volume)
  • Daily volatility σ=0.02\sigma = 0.02 (2%)
  • Impact coefficient γ=0.5\gamma = 0.5

Cimpact=0.5×0.02×(10,0001,000,000)0.5×100×10,000C_{\text{impact}} = 0.5 \times 0.02 \times \left(\frac{10{,}000}{1{,}000{,}000}\right)^{0.5} \times 100 \times 10{,}000 =0.5×0.02×(0.01)0.5×1,000,000= 0.5 \times 0.02 \times (0.01)^{0.5} \times 1{,}000{,}000 =0.5×0.02×0.1×1,000,000= 0.5 \times 0.02 \times 0.1 \times 1{,}000{,}000 =0.001×1,000,000=$1,000= 0.001 \times 1{,}000{,}000 = \textbf{\$1,000}

Why this step? We're computing how much the price moves against us as we execute. The square root (0.01)0.5=0.1(0.01)^{0.5} = 0.1 shows that a 1% order causes 10% of the impact you'd naively expect from linear scaling.

Step 4: Total Transaction Cost

Combining the example above:

  • Commission: $5
  • Slippage: $25.45
  • Impact: $1,000
  • Total: **1,030.45ona1,030.45** on a 1,000,000 trade
  • Cost: 0.103%

Common Mistakes and Why They Feel Right

Recall Explain to a 12-Year-Old

Imagine you're trading Pokémon cards at school. You want to buy a Charizard.

Commission = The $2 you pay the card shop owner to let you use his table and inventory system.

Slippage = The Charizard was listed at 50,butwhileyouweregettingyourmoney,someoneelseboughtit.Nowthecheapestoneis50, but while you were getting your money, someone else bought it. Now the cheapest one is 52. You lost $2 to timing.

Market Impact = You want to buy 10Charizards. The first one is 50.Buttheshopownerseesyoubuyingalot,andheraisesthepriceto50. But the shop owner sees you buying a lot, and he raises the price to 51for the next one, $52 for the one after that. Your big order pushed the price up.

So you thought'd spend10 × 50=50 = 500, but you actually spent 2(commission)+2 (commission) + 2 (slippage) + 15(impact)extra=15 (impact) extra = **519**. That extra $19 is what transaction costs mean—the hidden costs of actually doing the trade.

Implementation in Backtesting

def calculate_transaction_cost(
    side: str,  # 'buy' or 'sell'
    quantity: float,
    price: float,
    bid: float,
    ask: float,
    daily_volume: float,
    volatility: float,  # daily
    commission_fixed: float = 1.0,
    commission_rate: float = 0.0005,
    impact_coeff: float = 0.5,
    spread_fraction: float = 0.5,
    vol_sensitivity: float = 0.1
) -> float:
    """
    Calculate total transaction cost for a trade.
    Returns: Total cost in dollars (positive = cost to trader)
    """
    trade_value = price * quantity
    
    # 1. Commission
    commission = max(commission_fixed, commission_rate * trade_value)
    
    # 2. Slippage
    spread = ask - bid
    spread_cost = spread_fraction * spread * quantity
    vol_cost = vol_sensitivity * volatility * (quantity ** 0.5)
    slippage = spread_cost + vol_cost
    
    # 3. Market Impact
    order_fraction = quantity / daily_volume
    impact = impact_coeff * volatility * (order_fraction ** 0.5) * trade_value
    total_cost = commission + slippage + impact
    return total_cost

Why this implementation?

  • All three components separated for transparency
  • Parameters exposed for calibration (don't hard-code!)
  • Returns dollar cost (easier to audit than percentage)
  • Can be called for every simulated trade in backtest

Calibration and Parameter Selection

How to calibrate:

  1. Collect real execution data from paper trading or small live trades
  2. Compare actual vs. expected costs using your model
  3. Adjust parameters to minimize error
  4. Use conservative estimates (round up costs) to avoid overfitting backtest

Connections

  • 6.2.01-Choose-backtesting-platform - Your platform must support custom cost models
  • 6.2.03-Implement-realistic-order-fills - Transaction costs couple with fill assumptions
  • 6.2.04-Handle-corporate-actions-splits-dividends - Costs change around corporate actions (wider spreads)
  • 6.3.02-CalculateSharpe-Sortino-ratios - Returns must be net of transaction costs
  • 6.4.01-Paper-trade-validate-backtest - Paper trading reveals if your cost model was accurate
  • 5.1.03-Set-position-size-limits - Position sizing affects market impact costs

#flashcards/stock-market

What are the three components of transaction costs? :: Commission (broker fees), Slippage (price movement during execution), Market Impact (price movement caused by your order)

Why does the market impact formula use a square root instead of linear scaling?
Because liquidity absorbs small orders easily but depletes for large orders at diminishing rate. A 1% order doesn't cause 10x the impact of a 0.1% order—empirically it follows (Q/V)0.5(Q/V)^{0.5}
If a backtest shows 2% monthly return but the strategy trades 100 times/month with 0.1% cost per trade, what is the real return?
Net return = 2% - (100 trades × 0.1%) = 2% - 10% = -8% per month. The strategy is actually losing money after costs.
Why is using midpoint prices for backtest execution wrong?
Because market orders don't execute at the midpoint—you buy at the ask and sell at the bid. Using midpoint ignores the spread cost, which is a guaranteed loss on every trade.
A stock has 10Mdailyvolume.Youwanttobuy10M daily volume. You want to buy 500k worth. Is market impact significant?
Yes. 500k/500k / 10M = 5% of daily volume. At this size, the square-root law predicts measurable impact: (0.05)0.5=0.224(0.05)^{0.5} = 0.224 relative to a 1% baseline. You'll move the price noticeably.
Why do high-frequency strategies fail most often in live trading after successful backtests?
Because they generate many trades with small edge per trade. If your edge is 10/tradebuttransactioncostsare10/trade but transaction costs are 8/trade, you lose 80% of your profit. Backtests that ignore costs dramatically overestimate profitability.

Concept Map

component 1

component 2

component 3

max of fixed or rate

spread and volatility

large orders move price

sum into

sum into

sum into

reduces

if ignored

Transaction Costs

Commission Fees

Slippage

Market Impact

C comm = max Cfixed, Crate x P x Q

C slip formula

Order Size vs Daily Volume

Total Cost per Trade

Real Profit vs Paper Profit

Backtest Disappointment

Hinglish (regional understanding)

Intuition Hinglish mein samjho

Transaction cost modeling stock market backtesting ka sabse important part hai, kyunki ye bata hai ki paper pe jo profit dikh raha hai, real trading mein kitna kam ho jayega. Jab ap ek backtest run karte ho aur strategy dikhati hai ki "100 trades mein $5,000 profit," lekin ap transaction costs add nahi kiye, toh ye realistic nahi hai. Real mein har trade pe apko teen tarah ke costs face karne padte hain: pehla commission (broker ko fee), dusra slipage (jis price pe sochte the utne pe execute nahi hota), aur tesra market impact (apka bada order khud price ko move kar deta hai).

Agar apki strategy high-frequency hai—matlab bahut zyada trades kar rahi hai—toh transaction costs apka sara profit kha jayenge. Example ke liye,agar har trade pe 10edgehailekincost10 edge hai lekin cost 8 aa raha hai, toh net profit sirf 2pertrade.Paperpeye2 per trade. Paper pe ye 10 lag raha tha! Isliye modelling mein realistic parameters use karna zaruri hai: liquid stocks mein impact kam hoga, illiquid stocks mein zyada. Calibration bhi zaroori hai—real execution data se compare karke apne model ko tune karo. Ye effort karne se aapki backtest live trading ke results keareb ayegi, aur ap over-optimistic strategies se bach jaoge jo paper pe to superhit lagte hain par real mein flop ho jate hain.

Test yourself — Backtesting Frameworks

Connections