← Back to Learn
III AdvancedWeek 20 • Lesson 59Duration: 35 min

TCA Transaction Cost Analysis

The silent killer — how costs turn profitable strategies into losers

Learning Objectives

  • Understand the full cost structure of trading: spread, commission, slippage, market impact
  • Quantify how costs erode strategy profitability
  • Adjust strategy design to minimize cost friction

Explain Like I'm 5

Every trade has costs you can't avoid: the bid-ask spread, broker commissions, slippage from delayed fills, and market impact from moving the price against yourself. A strategy that makes 0.3R per trade in backtest might only make 0.1R live after costs — or worse, lose money. Transaction cost analysis (TCA) forces you to model these costs honestly and build strategies that survive them.

Think of It This Way

Transaction costs are like friction in physics. In a frictionless world, a ball rolls forever. In reality, friction slows it down. A strategy that backtests with zero costs is like simulating in a vacuum — it doesn't reflect reality. TCA measures the friction. If friction exceeds your engine's power, you're going nowhere.

1The Full Cost Stack

Most people think trading costs = commissions. That's maybe 20% of the story. Here's the complete picture: 1. Bid-ask spread — The biggest cost for most retail traders. On EUR/USD you might pay 0.8 pips per round trip. On exotics, 5-10 pips. This cost is incurred on EVERY trade, no exceptions. 2. Commission — Broker charges per lot. Usually $3-7 per lot round trip on FX. Relatively small but adds up. 3. Slippage — The difference between your intended price and actual fill price. Slippage is a function of: - Market volatility (higher vol = more slippage) - Order size relative to liquidity - Speed of execution 4. Market impact — Your order moves the price against you. Irrelevant for retail size but crucial to understand conceptually because it limits scalability. For stat arb specifically, costs are doubled because you're executing TWO legs. A pairs trade on EUR/USD and GBP/USD costs you spread + slippage on BOTH instruments. Factor this in or you'll be disappointed.

2Impact on Strategy Design

Here's the uncomfortable math: costs create a minimum edge requirement. If your total round-trip cost is 0.1R per trade, your strategy must generate more than 0.1R per trade just to break even. Many stat arb strategies generate 0.3-0.5R per trade — meaning costs consume 20-33% of gross profits. What this means for strategy selection: - Fewer, higher-conviction trades beat many small trades (lower cost burden per R earned) - Longer holding periods amortize entry costs over more R captured - Wider entry thresholds (z > 2.5 instead of z > 1.5) filter for bigger moves that justify the costs - Pair selection must consider liquidity — a great pair with 5-pip spreads may be worse than a decent pair with 0.8-pip spreads The rule of thumb: if costs exceed 30% of your gross per-trade profit, the strategy is fragile and will likely fail live. Redesign to reduce trade frequency or increase per-trade expectancy.

Key Formulas

Implementation Shortfall

The difference between the price when you decided to trade and the price actually achieved, times quantity. Captures spread, slippage, and market impact in one metric.

Hands-On Code

Transaction Cost Estimator

python
def estimate_costs(spread_pips, commission_per_lot, volume_lots, atr_pips, risk_pips):
    """Estimate total round-trip cost in R-multiples."""
    spread_cost = spread_pips * volume_lots * 10  # in USD (standard lot)
    commission_cost = commission_per_lot * volume_lots * 2  # round trip
    slippage_est = 0.5 * spread_pips * volume_lots * 10  # estimate: 50% of spread
    
    total_cost_usd = spread_cost + commission_cost + slippage_est
    risk_usd = risk_pips * volume_lots * 10
    cost_in_r = total_cost_usd / risk_usd if risk_usd > 0 else float('inf')
    
    print(f"=== TRANSACTION COST ANALYSIS ===")
    print(f"Spread cost:     ${spread_cost:.2f}")
    print(f"Commission:      ${commission_cost:.2f}")
    print(f"Slippage (est):  ${slippage_est:.2f}")
    print(f"Total cost:      ${total_cost_usd:.2f}")
    print(f"Risk per trade:  ${risk_usd:.2f}")
    print(f"Cost as R:       {cost_in_r:.3f}R")
    print(f"")
    if cost_in_r > 0.30:
        print(f"[WARN] Costs exceed 30% of 1R. Strategy viability is questionable.")
    elif cost_in_r > 0.15:
        print(f"[NOTE] Moderate cost burden. Need high win rate to compensate.")
    else:
        print(f"[PASS] Reasonable cost structure.")
    
    return cost_in_r

Estimates the full round-trip cost of a trade in R-multiples, including spread, commission, and slippage, to determine feasibility of a strategy.

Knowledge Check

Q1.Your backtest shows +100R over 500 trades (0.2R/trade avg). Each trade costs 0.1R in execution costs. What is the realistic net expectancy?

Assignment

Calculate the full cost structure for your preferred instruments. What is the minimum per-trade expectancy your strategy needs to remain profitable after costs?