What Your Broker CSV Isn't Telling You About Your Real P&L
Most broker CSV exports are fill logs, not trade logs. Here's how the gap between fills and trades quietly distorts your P&L, and what to reconstruct.
By Imperial Analytics
The number on your statement is not the number in your journal
If you have ever run your broker's CSV through a journal and the realized P&L came out a few hundred dollars different from your account statement, you already know this. The export looks complete. It has columns, it has timestamps, it has a P&L field. The journal still gets it wrong.
The reason is almost never bugs. The reason is that most broker CSV exports are fill logs, not trade logs, and the gap between those two ideas is where every meaningful number in your performance review either gets reconstructed correctly or quietly drifts.
Fills vs trades: why the distinction matters
A fill is a single execution: you sent an order, the matching engine matched some or all of it, the broker logged a row. One row, one quantity, one price, one timestamp.
A trade is the round trip a human cares about: opened a position, scaled in, scaled out, exited flat. That is one trade in your head and on your equity curve. In the CSV, it can be anywhere from two rows to a dozen, depending on how the order worked the book.
The journal needs the second view. The export almost always gives you the first. Reconstructing trades from fills is where the integrity of your numbers lives.
The four places the export quietly distorts your P&L
1. Commission and exchange fees as separate rows
On most futures broker exports, commissions, exchange fees, and clearing fees show up as their own line items, separated from the trade rows that produced them. If a journal sums the trade-row P&L without joining the fee rows, the number it reports is gross of commissions, not net.
This is a real spread. On a contract like MES, the round-turn commission plus exchange and clearing fees ranges from roughly $0.74 to $1.40 per round-turn depending on broker and prop firm. On 100 round-turns in a quarter, that is $74 to $140 missing from your reported net P&L per contract per quarter.1
Multiply by contract size and frequency and the gap gets large fast. The fix is to load the fee rows on the same key the trade rows use (instrument plus account plus session) and subtract them at the trade level before any aggregation.
2. Partial fills inflating "trade count"
A 10-contract market order in MNQ at the open often fills across two or three prints. Your broker logs each print as its own fill row. If the journal counts rows as trades, you now have three "trades" where the trader took one. Average win, average loss, expectancy, win rate — all distorted, because the denominator is wrong.
The reconstruction needs to coalesce fills that belong to the same order ID into a single open or close event, then group those events under a single trade entity using net-position logic. Done correctly, the trade count matches what the trader actually did.
3. Scale-outs without a defined accounting method
If you opened 6 MES contracts at one price and closed them in three legs at three different prices, the realized P&L per leg depends on which contracts you assigned to which exit. FIFO (first-in, first-out) is the default the CME and most US futures brokers report against, but some broker exports leave the assignment implicit, and some retail journals default to LIFO or average-cost without telling you.
The result is a P&L per leg that looks plausible but is computed against a different cost basis than the broker statement. The totals usually still tie because the position closed flat, but the per-trade R-multiples and per-trade win/loss tags drift. If your journal disagrees with your broker statement on a per-trade basis but agrees on the period total, this is the most common cause.
For futures, FIFO is the safe default because it matches CME-cleared statements and IRS reporting.2 If your journal lets you pick, pick FIFO and document the choice. The point is consistency, not which method is "right."
4. Instrument multipliers and tick values
A point on MES is $5. A point on ES is $50. A point on MNQ is $2. A tick on CL is $10.3 If the export gives you "P&L in points" rather than dollars, every product needs the right multiplier applied or your dollar P&L is off by a factor of ten or more.
Most exports give you dollars directly, but some give you both, and some give you ticks. The integrity check is simple: pick one trade per instrument per export and recompute its dollar P&L from the fill prices and contract quantity. If the journal's number ties, the multiplier table is correct. If it doesn't, the journal is using a wrong multiplier and the error compounds across every trade in that product.
A worked example
Take a single MES session with 14 fills:
- 2 fills opening a 5-contract long
- 3 fills closing 2 contracts each at a target
- 1 fill closing the final 1 contract at a stop
- 4 commission rows
- 4 exchange/clearing fee rows
That is 14 rows. The trader took one trade.
Without reconstruction, a row-counting journal reports 8 trades and 6 fees as separate events. With FIFO reconstruction, the journal reports one trade with three exit legs, attributes the right fee allocation to that trade, and computes a single dollar P&L net of commissions. The win/loss tag, the R-multiple, the holding time, and the position size are now all referring to the same object the trader has in their head.
This is the difference between a journal that surfaces patterns and one that surfaces noise. The patterns require trades; the export gives you fills.
What to check on your own export this week
Open your most recent CSV export and answer four questions:
- Are commission and fee rows separate from trade rows? If yes, your journal needs to join them on instrument plus account plus session.
- Does a single multi-leg trade appear as multiple rows? If yes, your journal needs net-position reconstruction, not row counting.
- Is the accounting method documented? If your journal does not tell you whether it is using FIFO, LIFO, or average-cost, that is the first thing to lock down. FIFO is the safe default for US futures.
- Does your journal's period total match your broker statement to the cent? If yes, that is necessary but not sufficient. Per-trade tags can still be wrong even when totals tie.
If any answer is unclear, the integrity gap is where you would expect it: between the fill log the broker hands you and the trade log the human takes home.
What we built around this
Imperial Analytics treats the broker CSV as raw input and reconstructs trades from fills before anything else runs. Net-position logic on the order side, FIFO accounting on the close side, fee rows joined at the trade level, instrument multipliers driven by a per-product reference table, and a per-export reconciliation that flags any session where the reconstructed total disagrees with the broker statement by more than a defined tolerance.
The objective is the same one the rest of the product is built around: every number you see is a number you can trust to the cent, and every claim above it is built on data that already passed integrity.
Sources
NinjaTrader® is a registered trademark of NinjaTrader Group, LLC. No NinjaTrader company has any affiliation with the owner, developer, or provider of the products or services described herein, or any interest, ownership or otherwise, in any such product or service, or endorses, recommends or approves any such product or service.
Footnotes
-
NinjaTrader Brokerage — Futures Commissions and Exchange Fees (ninjatrader.com/futures/pricing/) ↩
-
CME Group — Trade Practice and Customer Statement Standards (cmegroup.com/rulebook) ↩
-
CME Group — Contract Specifications, E-mini and Micro E-mini Equity Index (cmegroup.com/markets/equities) ↩