I got into this because a strategy of mine looked great on paper and mediocre in the account, and I could not figure out where the money went. The signals were fine. The win rate matched the backtest closely enough. But the equity curve was consistently a notch below what the tester promised, and the gap did not look like fees. So I started logging every trade the way an institutional desk would, and the answer turned out to be embarrassingly simple. My execution was quietly costing me more than my fees, and I had never once measured it.
Transaction cost analysis is the boring institutional practice of measuring what it actually cost to get in and out of a position, versus what it should have cost. Big desks run whole teams on this because a few basis points across billions of dollars is real money. At retail scale the dollars are smaller, but the percentages are often worse, because you are trading less liquid stuff, at worse times, with slower hands. The good news is you do not need their infrastructure. A spreadsheet and a little discipline about what you write down at the moment you decide to trade will get you most of the way there.
Log the arrival price, not the fill price
The single habit that makes all of this work is capturing the arrival price. That is the market price at the exact moment you decide to trade, before you send anything. Not the price you got filled at, not the price when the order finally went in after you finished your coffee. The price when the decision was made.
This matters because the arrival price is your honest benchmark. Once you have it, every cost you care about is just a comparison against that number. Most people never record it, so they end up comparing their fill to their fill, which tells you nothing. If you decide to buy at 100 and get filled at 100.30, that 30 cents is a real cost, and it does not show up anywhere in your broker statement. It is buried in the entry price itself.
So the first column in your log is the arrival price with a timestamp. The second is your average fill price with a timestamp. From those two, plus the direction and size, everything else falls out.
Implementation shortfall is the number that matters
Implementation shortfall is the gap between the return you would have gotten if you had transacted instantly and frictionlessly at the arrival price, and the return you actually got. It is the total cost of turning a decision into a position and then back into cash. Fees, spread, market impact, and the drift that happens while you dither are all inside it.
For a single trade you can approximate it in a few steps. Take the arrival price when you decided to buy. Take your actual average fill. The difference, times shares, is your entry cost in dollars. Do the same on the exit, comparing the arrival price when you decided to sell against your actual sell fill. Add fees and commissions. That total, divided by the notional value of the trade, gives you shortfall in basis points, which is the unit that lets you compare a small trade to a large one fairly.
Here is the workflow I actually use, kept deliberately simple:
- At decision time, write down the mid price and the timestamp. The mid, not the bid or the ask, because the mid is the fairest reference.
- Record every fill and its price. If the order fills in pieces, use the size-weighted average.
- Compute entry slippage as fill minus arrival, signed so that paying up is always a positive cost.
- Repeat the same three steps on the exit.
- Add fees, then divide the whole thing by notional and express it in basis points.
Run twenty or thirty trades through this and a distribution appears. You will find your median shortfall, and more usefully, you will find the fat tail of trades where it blew out. Those tail trades are where the lesson lives.
Effective spread, and why your fills are worse than the screen
The quoted spread is what the screen shows, the distance between the best bid and best ask. The effective spread is what you actually paid, measured as twice the distance between your fill and the mid at the time you traded. If the mid was 100 and you bought at 100.30, your effective spread on that trade is 60 cents, whether or not the screen ever displayed a spread that wide.
Tracking effective spread separately from total shortfall is worth the extra column, because it isolates one specific failure mode. If your effective spread is consistently much wider than the quoted spread, you are crossing the book aggressively, chasing with market orders, or trading in a name too thin to absorb your size without moving it. Those are all fixable behaviors. Widening spreads that only show up around news or the open are a scheduling problem, not an order-type problem.
Cost of delay versus cost of impact
This is the split that changed how I trade, so I will be specific about it. Total shortfall has two main sources and they call for opposite fixes, which is exactly why lumping them together leaves you stuck.
Cost of delay is the price drift between the moment you decided and the moment your order actually reached the market. If you decided at 100, hesitated, and the market was already at 100.20 before your order went in, that 20 cents is delay. It has nothing to do with how you executed. It is the tax on being slow, on second-guessing, on manual workflows that put minutes between decision and action.
Cost of impact is what your own order did to the price once it hit the book. You decided at 100, the market was still at 100 when you fired, and you walked it up to 100.15 filling your size. That 15 cents is impact. It is a function of your size relative to available liquidity and how aggressively you took it.
To separate them, add one more price snapshot to your log, the mid at the instant your order actually reaches the market. Now you have three reference points instead of two. Arrival-to-submission is delay. Submission-to-fill is impact. When I first did this I assumed my problem was impact, that I was too big and clumsy. It was almost entirely delay. I was slow, and the slowness was compounding across hundreds of trades in a way no single fill ever made obvious.
The two fixes are genuinely different. Delay is solved by tightening the path from decision to order, which for a lot of retail traders means pre-setting orders, using alerts, or automating execution so a signal fires without a human in the loop. Impact is solved by slicing size, using limit orders, and simply not trading names too thin for you. If you skip the split you will keep applying the wrong fix and wonder why nothing improves.
What to do with the numbers
Once you have thirty or forty trades logged, the point is to put shortfall next to your strategy's expected edge and see how much of the edge survives. If the tester says the average trade should make roughly forty basis points and your median shortfall is roughly fifteen, you are handing back a large slice of your edge at the door, and no amount of signal tuning fixes that. That is an execution problem wearing a strategy costume.
I bake this into how I build strategies now. When I backtest something on Blockcircle, I try to keep a realistic cost assumption in the model rather than testing on frictionless fills, because a strategy that only works at zero cost is not a strategy I can trade. But the backtest is an estimate. The trade log is the truth, and the two should be checked against each other regularly.
Start with the arrival price. If you only change one thing, write down the mid and the timestamp the moment you decide, and keep the log for a month. The number that comes out is usually larger than you expected and almost always fixable once you can see it.