Learn · 18 of 21

Transaction costs: why they decide whether a strategy is real

Commissions, slippage tiers by liquidity, the square-root impact model, and turnover times cost.

A backtest that trades for free is a description of the past, not a strategy. Every purchase pays the ask, not the last price; every sale gets the bid; and an order large relative to a stock's daily volume moves the price against itself. These costs are small per trade and large per year, and they fall hardest on the strategies that look best on paper: frequent trading in small, cheap, illiquid stocks. Stoxa turns costs on by default for that reason.

Three kinds of cost

  • Commissions: a fee per trade or a percentage of value. Near zero at most US retail brokers today; the simulator lets you set dollars per trade and a percentage.
  • Spread: the gap between bid and ask. You lose half of it on each side of a round trip. A few basis points for a mega cap, a percent or more for a small company.
  • Market impact: the price moving because you are trading. Negligible for a $5,000 order in Apple, decisive for a $500,000 order in a stock that trades $1M a day.

Stoxa models slippage (spread plus impact) as a percentage of trade value per side, taken from cash, which is the same as a worse fill price.

The variable model: tiers by liquidity (default)

The default charges a percentage per side that depends on the stock's average daily dollar volume over the 20 trading days up to the trade (close × volume, point in time). The table is Portfolio123's:

20-day average dollar volumeCost per side
up to $40,0004.00%
up to $55,0003.00%
up to $80,0002.00%
up to $125,0001.25%
up to $225,0000.80%
up to $450,0000.50%
up to $900,0000.30%
up to $2,000,0000.20%
up to $7,500,0000.12%
above $7,500,0000.08%

A trade with no volume data pays the worst tier, 4%, and is counted in the result, so missing data never makes a strategy look cheaper. There is also a fixed model (one percentage for every trade) and none, for comparison.

The square-root model

Studies of real institutional orders find that impact grows roughly with the square root of the order's size relative to volume: four times the size costs about twice as much per dollar, not four times. Stoxa's sqrt model, per side, is

cost=K σ20QL+Ls⋅spread,spread=L−0.4\text{cost} = K\,\sigma_{20}\sqrt{\frac{Q}{L}} + L_s \cdot \text{spread}, \qquad \text{spread} = L^{-0.4}

σ20\sigma_{20} is the standard deviation of the last 20 daily log returns, LL the median daily dollar volume over those days, QQ the trade value (capital × equity so far ÷ number of holdings), KK = 2 and LsL_s = 0.5 by default. There is no bid-ask data in the store, so the spread term uses Portfolio123's proxy L−0.4L^{-0.4}. The model depends on your capital, which the tiered model does not: the same strategy costs more at $1M than at $100,000.

Worked example

$100,000 in 20 positions, so each trade is $5,000. A stock with $1M median daily volume and 2% daily volatility: impact = 2 × 0.02 × √(5,000 / 1,000,000) = 0.28%; spread = 1,000,000−0.4 = 0.40%, times 0.5 = 0.20%; total 0.48% per side. The same trade in a stock with $10M volume: 0.09% + 0.08% = 0.17%. At $1M of capital the first stock's impact term grows by √10 to 0.89%.

Treat this as an order of magnitude for capacity, not a fill estimate: the spread is a proxy and the coefficients are averages over very different markets.

Turnover times cost

The annual cost of a strategy is approximately

annual cost≈turnover per period×2×c×p\text{annual cost} \approx \text{turnover per period} \times 2 \times c \times p

where turnover is the share of the portfolio replaced each period, cc the cost per side (each replacement is a sale and a purchase) and pp the periods per year.

Worked example

A monthly strategy in liquid large caps replaces 20% of the portfolio a month at 0.12% per side: 0.2 × 2 × 0.12% × 12 = 0.6% a year. Noticeable, survivable.

A weekly strategy in small caps trading $300,000 a day (0.50% per side) replaces 20% a week: 0.2 × 2 × 0.5% × 52 = 10.4% a year. An excess return of 8% a year before costs becomes a loss after them. This is why weekly rebalancing of illiquid names dies on costs, and why a backtest without costs flatters exactly the strategies that trade the most.

Reading cost drag

The backtest reports the annual cost drag (gross CAGR minus net CAGR) and the number of trades charged the worst tier for lack of volume data. Three checks:

  • Compare the cost drag with the excess return. If costs eat more than a third of it, the edge is fragile; a slightly worse fill than modelled would erase it.
  • Rerun with costs off. If the ranking of your variations changes (the high-turnover variant wins without costs and loses with them), believe the version with costs.
  • Reduce turnover before abandoning an idea: a quarterly instead of monthly schedule, a hold tolerance (keep a holding while it stays within the top N + tolerance), or a sell rule on rank rather than re-forming the basket.
In the appThe cost model selector on the Backtest and Simulate pages (variable, fixed, square root, none), the cost drag lines in the statistics, and, in the simulator, the cost of every trade in the trade list.

Go deeper