PROPSURVIVAL

A file of fills is not a list of trades.

The same 91 rows give a win rate of 51.5% read as trades and 65.2% read as rows, over one realised total that never moves. Every step from a statement to the three numbers a simulator asks for is a choice, and each of them is arithmetic you can check on your own file.

Citable answer · extract this block

A file of fills is not a list of trades. Between leaving flat and returning to flat, the money paid out and taken in is fixed by the fills; matching conventions change how the total is split across partial exits, not the trade total. Free path: /app?src=broker-export-to-expectancy.

Source: https://propsurvival.com/articles/broker-export-to-expectancy · free path: /app?src=broker-export-to-expectancy

What this establishes

Working backwards: free path — 91 fill rows read 51.5% as trades and 65.2% as rows; group fills before you feed a win rate to the engine.

Run the free path — turns fills into trades →

  • 01One file of 91 fills is 34 trades or 47 results, and the two readings disagree about the win rate by 13.7 percentage points while agreeing on every dollar.
  • 0228.8% of the sample's gross profit sits in one trade; removing it moves expectancy from $18.35 a trade to -$7.64.
  • 03The arithmetic mean is the only centre for which the three numbers rebuild the file's own total — $605.50 against a median-based -$164.33.
01

How many trades is a file of fills?

THE UNIT

A broker export is a list of fills. A row appears every time some quantity was matched — a partial entry, a partial exit, a stop that filled in two pieces because the book was thin. A trade is a different object: the span between the moment a position leaves flat and the moment it comes back. One trade is often four rows. One row is sometimes two trades.

The definition that resolves it needs no judgement and no timestamp. Take one symbol at a time and track the net position. When it leaves zero a trade opens; when it returns to zero that trade closes; everything in between belongs to it. Three ordinary situations break any reading that skips this step:

  • ReversalA single row sells more than the position held. It closes the trade that was open and opens the opposite one. The row belongs to both, and its money belongs only to the first.
  • Two at oncePositions in two instruments overlap in the file. They are two ledgers, and their interleaving is not a flat crossing — a grouper watching one combined position invents a trade boundary that never happened.
  • Still openThe file ends with a position on. It has no result yet, and averaging it in as a zero is an assertion about a trade that has not finished.
Illustrative

The fill log in this article is constructed, not collected: figures.data.js lays out 34 trades across 2 invented instruments at seed 7314, rounds every price to the tick and then recomputes what those rounded rows are worth. It ships beside this page and prints what it emits when run.

No real contract, broker or firm is described. What one point of a symbol is worth is knowledge the file does not contain.

LONG FLAT SHORT +1-1-2-2+4-2+2-4+4-1-2+1+2 TRADE 1 TRADE 2 TRADE 3 TRADE 4 TRADE 5 LONG FLAT SHORT 1 2 3 4 5
The line is the number of contracts held in one instrument, fill by fill. It leaves the flat line when a trade opens and touches it again when the trade closes; a scaled entry and a partial exit are steps within a trade, not trades. Below the flat line the position is short.
ONE FILE, TWO COUNTS
13rows in this excerpt
6of them reduce the position, so a row-by-row reading calls each one a trade
5trades, counting flat to flat
91rows in the whole sample, which is 47 results by rows and 34 by trades

The consequence is arithmetic rather than opinion. Reading the sample flat to flat gives 34 trades, a win rate of 51.5%, an average win of $173.85 and an average loss of $146.88. Reading the same rows one at a time gives 47 results, a win rate of 65.2% — 13.7 percentage points higher — and an average win of $103.53, barely more than half as large.

Neither reading is a mistake in arithmetic. Both add up to the same realised money: $605.50, to the cent, because every closing row's result belongs to exactly one trade whichever way they are grouped. What changes is the denominator, and the three numbers are all quotients.

A file has one total and two of everything else. The win rate is not a property of your trading; it is a property of your trading and your definition of a trade, and the second one is a choice you make in a spreadsheet.

The inflation has a direction, and it is not random. Scaling out of a position banks the piece that is furthest in your favour first, so partial exits manufacture small winners; the remainder carries whatever is left, which on a losing trade is the whole loss and more. A file where every position is taken off in one piece shows no gap at all. A file where the good ones are trimmed and the bad ones are held shows a large one.

02

What do your own rows say?

THE INSTRUMENT

Below is the grouper, the matcher and the arithmetic, running in this page. The box holds a sample so that the readouts mean something before anyone types; clear it and paste your own rows over the top. Reduce your export to four fields in file order — symbol, side, quantity, price — and add a line for what one point of each symbol is worth, since the file does not know.

The parser refuses anything that is not exactly four fields, and says how many rows it refused and what the first one was. That strictness is the point. A parser that guesses which column is the price will succeed on a file it has misunderstood, and hand back three numbers with no indication that anything went wrong.

What it will not guess

The multiplier, because a symbol is not a contract specification. The stop, because a fills export does not carry the risk you intended, only the money you made. The account balance, because it is not in the file either — which is why every number here is money per trade and none of them is a percentage of anything.

The three numbers, from rows you supply

Replace the sample with your own rows. Nothing is uploaded: this document contains no network call of any kind, and the build refuses to ship one.

Count a trade as

To the right, the largest winners come out — the outlier test. To the left, the worst losers do, which is the edit that makes a record look like the system you meant to trade.

Share of the wins dropped from each end before the trimmed average is taken.

Charged on every contract in and every contract out, so a round turn is two of these. Leave it at nothing if your prices are already net of cost.

Reading the sample.

Results
what the file is counted as
Win rate %
over decided results; scratches excluded
Average win
arithmetic mean of the winners
Average loss
arithmetic mean of the losers, as a magnitude
Expectancy
per decided result, from the three numbers
Median win
the middle winner, not an input
Trimmed win
mean of the wins that are left after trimming
Top win share %
of gross profit, in one trade

Readouts are in whatever currency the multipliers are denominated in; the file itself carries prices, not money.

Nothing you paste leaves the browser, and that is a structural claim rather than a promise: this document contains no script, style, font or image loaded from anywhere else, and no code path that can open a network connection. A build gate refuses to publish the page if one appears.

The four controls are the four decisions the rest of this article is about. The first is what a trade is. The second removes results from the extremes, in either direction. The third replaces the average win with a trimmed one. The fourth charges cost per contract per side, which matters here more than it looks: cost is levied on fills, and a scaled entry with two partial exits pays it four times while producing one trade.

03

Which single trade is your average win?

THE CENTRE

An average is a claim about a set. When one member of the set is several times larger than any other, the average is mostly a claim about that member, and the usual way to find out is to take it away and look again.

Definitional

The identity in this section is arithmetic, not simulation, and is reproducible by hand from any list of results. It is asserted on every build against the shipped sample, together with the fact that the median and trimmed substitutions break it — a check that would pass vacuously if they happened to agree.

$173.85 $131.59 WHOLE FILE THE LARGEST WIN, REMOVED SMALLEST $173.85 $131.59 EACH DOT: ONE WIN REMOVED
Each dot is the average win of the same file with one winning trade taken out, largest first. Every removal but the first moves the average by at most $8.24. The first moves it by $42.26.
HOW MUCH IS ONE TRADE WORTH?
$173.85average win, whole file
$131.59with the largest win removed, a fall of 24.3%
28.8%of gross profit sits in that one trade

In the sample, 28.8% of all gross profit sits in one trade. Remove it and the average win falls from $173.85 to $131.59, a drop of 24.3%; expectancy per decided trade goes from $18.35 to -$7.64, which is to say the sign of the edge is carried by one row out of 34. Every other removal moves the average by a few dollars.

The instinct at this point is to reach for a robust centre — the median, or a trimmed mean — and there is a real reason not to.

MEAN WITHOUT THE LARGEST WIN $131.59 MEDIAN $133.75 THE MEAN $173.85 $850 ONE WIN, AND THE WHOLE GAP LARGEST OUT $131.59 MEDIAN $133.75 MEAN $173.85 $850 ONE WIN
Every win in the file on one axis. Take the largest away and the mean lands within $2.16 of the median — on the same pixel at this scale. The whole distance between the two centres, $40.10, is one trade.
WHICH CENTRE IS THE AVERAGE WIN?
$605.50the file's realised total
$605.50rebuilt from the mean-based three numbers
-$164.33rebuilt from the median-based ones

The drawing makes the arithmetic visible. The median of the wins is $133.75 and the mean of the wins is $173.85, a gap of $40.10 that looks like a fact about the distribution. Take the largest win out and the mean lands at $131.59 — within $2.16 of the median. The gap between the two centres was never a property of the shape. It was one trade.

Expectancy is defined on this site's expectancy page as the win rate times the average win, less the loss rate times the average loss. With arithmetic means in those two slots the expression is not a model of anything: it is the file's own realised total divided by its decided trades, exactly, by cancellation. Multiply it back out and you get $605.50, which is what the file made.

Substitute the medians and the same multiplication returns -$164.33 — a file that lost money, described by the same trades that made $605.50. The trimmed pair returns -$36.67. Neither substitution is a computation error; the median is a perfectly good statistic. It is simply not the input this particular machine takes, because a simulator handed an average win multiplies it by a trade count, and only the arithmetic mean survives that multiplication.

The median is not a better average win. It is a measurement of how much of your record lives in a few trades — and the distance between the two expectancies, $18.35 against -$4.98, is more informative than either number on its own.

That distance is the honest reading of this file: an edge that survives its own arithmetic and does not survive the removal of one trade. A record whose mean and median expectancies nearly agree is telling you something quite different from one where they disagree in sign, and no single summary number can carry that difference.

04

Are you averaging money, points, or risk?

THE UNITS

A fills export contains prices. Prices are not money, and the step between them is a number the file does not carry. In the sample one instrument is worth $2 a point and the other $5, so the same price move is worth two and a half times as much in one as the other. Averaging the price differences as though a point were a unit of money gives an average win of $67.47 against a true $173.85 — and the error is not a constant factor you could correct for later, because it depends on which instruments you happened to trade and in what size.

Can R be recovered from the file?

Not from fills alone. An R-multiple is a result divided by the risk that was actually taken, and the risk taken is the stop distance at entry times the size times the multiplier. An export records what filled, not what you intended; the stop that never filled leaves no row. Any R computed from this file is therefore reconstructed from an assumption, and the assumption is usually that the average loss is one R.

That assumption is worse than it sounds, because it is self-confirming. Define R as the average loss and the average loss becomes exactly one R by construction, whatever the losses actually did. In the sample they run from $68.50 to $203 — the largest is nearly three times the smallest — and a simulator handed one average loss draws every loss at that size. That is not a guess about simulators in general: the engine behind this site sets out in its own FAQ that it draws each trade from a win rate, an average win in R, an average loss in R and a trading cost in R, and states plainly that it uses those averages rather than the full distribution. The spread is discarded at the input, before any simulation has run, and no amount of simulation puts it back. If you want R, the place to record it is at entry, in a journal, not afterwards from a statement.

And percentages?

Averaging percentages of different balances is a different operation from averaging money, and it is not a matter of units. A gain of 2% on one balance and a loss of 2% on a balance twice as large average to nothing as percentages, while costing 2% of the smaller balance as money. The mean of ratios is not the ratio of sums, and an export does not carry the balance at the time of each trade, so whichever you use is a declaration rather than a measurement.

Gross or net?

One last unit question decides whether a cost is charged once or twice. If your export's prices are raw, the results here are gross and a cost term belongs somewhere. If your platform already reports each fill net of commission, the results are net, and handing them to a model that subtracts a cost per trade charges you the same money again. The cost is a separate input precisely so that it can be set; numbers derived by this method from an already-net export belong in it at zero.

Where this disagrees

Simulated pages on this site carry a trading cost among the trader's statistics, as the engine's FAQ sets out. That is the right default for a hypothetical trader and the wrong one for a reader arriving with a statement whose prices are already net, who would be charged for the same round turn twice. The cost control in the instrument above starts at nothing for that reason.

05

Which trades did the file never contain?

THE SAMPLE

Everything so far assumes the file is the record. It usually is not. The account that was funded and closed, the two weeks on a demo, the month excluded because it was a different market — each of those is a decision about which trades count, taken before any arithmetic begins, and it moves the answer further than any of the choices above.

The instrument measures it, because removing results from the bottom is the same operation as removing them from the top with the sign reversed. Take the three worst results out of the sample and expectancy per decided trade rises from $18.35 to $40.24, a gain of 119%, with the win rate moving from 51.5% to 56.7%. Take the three best out instead and it falls to -$24.10. Neither edit is visible in the file that results; both are visible in the slider.

Two smaller categories have the same character. A trade that closed exactly where it opened is neither a win nor a loss, and the three-number interface has no slot for it: put it in the wins and the win rate rises, put it in the losses and it falls, exclude it and the trade count no longer matches the file. The sample contains one, and the readouts report it rather than absorbing it. A position still open at the end has the same problem in a stronger form, since its result does not exist yet; one row of the sample is in that state and is excluded and named.

What do three correct numbers still not tell you?

This page makes three numbers correct. It does not make them stable, and those are different properties: a correctly computed average win from 34 trades is still an estimate with a wide interval around it, and a companion draft in this set, on the error bars around a simulated pass rate, is about exactly that. Nothing here says how many trades are enough, because the honest answer depends on the dispersion this article has spent its length measuring.

It also assumes your export is complete and correctly ordered, which for a file assembled by hand from several statements is worth checking before anything else. Rows out of chronological order will match against the wrong lots and produce results that are individually wrong while still summing to the right total — the same invariant that makes the matching convention harmless makes an ordering error hard to see.

And it says nothing about whether the numbers it produces describe your future. That is a question about variance and about the rule set they will meet, and neither of those is in your export. What a win rate and a pair of averages decide once a floor and a daily limit are set beside them is the subject of which rule actually ends an evaluation and of why a profitable trader still blows up. This page has one job before either of those can mean anything, which is to make sure the three numbers you hand them are yours.

Companion reads

Why the win rate is the wrong number defines the expectancy this page computes from your rows. Which rule actually ends an evaluation begins from the three numbers, and inherits whatever went wrong on the way to them.

FAQ

Which choices in the export still change the three numbers?

REFERENCE

Does it matter whether my broker matches first-in-first-out or against the average price?

Not for a completed trade's total, and that is provable rather than conventional. Between leaving flat and returning to flat, the money paid out and taken in is fixed by the fills themselves; no matching rule appears in that sum. What the convention changes is how the total is split across partial exits, which is exactly the number a row-by-row reading uses. So the matching rule is irrelevant to the trade-by-trade reading and decisive for the other one. This page's two independent implementations agree on both, and a build gate asserts the invariant on every trade in the sample.

Is the median the better number to hand a simulator?

No, and the reason is mechanical rather than a matter of taste. A simulator takes an average win and multiplies it by a count of winning trades. Only the arithmetic mean has the property that this multiplication returns the money the trades actually made; substituting the median of the sample's wins turns a realised $605.50 into a predicted -$164.33. The median is worth computing and worth looking at, as a measure of how concentrated the record is. It is not an input to this particular machine.

My export already has a realised profit column. Can I skip the matching?

Yes, for the money — a realised column has already done the lot matching for you. The grouping question is untouched by it, because that column is populated on closing fills, which is precisely the row-by-row reading. You still have to decide which rows belong to one trade. It is also worth establishing whether the column is gross or net of commission before handing the result to anything that subtracts a cost.

How many trades do I need before these three numbers mean something?

This page does not answer that, and the answer is not a fixed number. What it can say is where to look: the wider the spread of your wins and losses, the longer it takes for their means to settle, and this article's own sample is an example of a record whose average win is dominated by a single trade. Correctness and stability are separate problems, and the companion piece on error bars is about the second one.

Provenance

The fill log on this page is illustrative and constructed by figures.data.js at seed 7314, which ships beside the page and prints every value it emits when run directly. Every number in the prose comes from that generator; every number the instrument shows is computed in the page from the rows in the box and checked on each build against model.js, an implementation that reaches the same results by cash flow and unit expansion rather than by a lot queue. The grouping rule is additionally checked against hand-worked fill sequences in cases.js. No firm, broker or contract is described, and no page on this site publishes a per-firm pass rate.

  1. Expectancy and the break-even win rate: Why the win rate is the wrong number. Cited, not re-derived — this page computes the inputs that definition takes.
  2. What the simulator does with those inputs, including that it draws from average values rather than from the full distribution: how the engine works and what it will not claim.
  3. Terms used here without redefining them, R-multiple among them: the glossary.
  4. Where the three numbers go next: which rule actually ends an evaluation and why a profitable trader still blows up.
  5. No source outside this site is cited, because no claim on this page is empirical. The grouping rule, the cash-flow invariant, the expectancy identity and the percentage-base result are each derived in full above, over a file that ships with the page. No broker's export format, no contract specification and no published result is asserted anywhere on it.