Skip to content
All library documents

Average-Cost Accounting for Fill Allocation and Trade Attribution

Article Quant Q&A · Author: Matt Wolf

Summary

The document compares ways to group fills and calculate realized performance in a position accounting system. It advises against FIFO or LIFO when the goal is performance analysis rather than tax accounting, since those conventions may not reflect how gains are economically realized. Instead, fills that increase exposure contribute to the position’s average cost, while fills that reduce exposure realize gains or losses against that cost. A fill that crosses through zero should be split conceptually at zero so the old position closes before the new one opens.

For trade-level reporting, the responses describe grouping activity from flat to flat, treating each position-reducing fill as a trade, or using an algorithm’s opening and closing labels to define logical trades. A separate decision-quality analysis plots price movement around execution, optionally scaled by trade size, to reveal patterns such as slippage or a small subset of decisions driving results. These approaches answer different questions: position-based grouping accounts for exposure, while the event plot evaluates individual decisions and does not account for the overall position. The document offers practitioner perspectives rather than a formal industry standard.

Key ideas

  • Average-cost accounting assigns opening fills to the position’s weighted average cost and realizes gains or losses on reducing fills.
  • FIFO and LIFO are primarily useful when tax accounting requires them, but may impose arbitrary performance groupings.
  • A flat-to-flat interval can define one trade, while each reducing fill can instead be reported separately.
  • Fills that cross zero should close the existing position before establishing exposure in the opposite direction.
  • Price paths around execution can help assess decision quality and slippage, but omit portfolio position context.

Tags

Full text
# How do Order Management/Matching Systems match/allocate orders (and filled prices)?


# How do Order Management/Matching Systems match/allocate orders (and filled prices)?












I am working on an improvement of my company's order allocation system. We run a central Order Management System (OMS) but currently performance attribution from filled orders leaves room for improvement.

I look to understand how other systems handle order and trade allocation.

Example: Asset 'A'

```
Fill1; buy A 500 shares; avg px x1
Fill2; buy A 300 shares; avg px x2
Fill3; sell A 700 shares; avg px x3
Fill4; sell A 100 shares; avg px x4
```

One example how a trade could be defined is as follows:

Trade1, avg entry px=x1; avg exit px=x3 Trade2, avg entry px=x2; avg exit px=(2*x3+x4)/3

To compute performance of individual trades (not total performance as that is trivial) would you apply a FIFO-like approach or allocate filled shares and their filled price in a different way? The reason I attempt to break it down is for various reasons, among others TCA and to better analyze algorithm predictive power in detail.

Can you please share how you would approach this issue and if you know what you believe industry standard is? I want to have a better understanding before having it all spec'ed up and implemented by developers.

Edit:

To avoid confusion, my question is not at all related to order matching on the exchange/ecn side, but fill allocation and trade performance attribution on the liquidity taking side.

## Answer by Brian G. Peterson (score 8, accepted)

https://quant.stackexchange.com/a/9215

Approaches like FIFO and LIFO are most useful for tax accounting. If you don't have a tax accounting reason to do them, I'd recommend avoiding them, as they don't reflect actual realized gains (it's very rare for a position accounting system to move cash in and out of your account based on FIFO or LIFO).

I'm going to discuss everything here in Gross of Fees terms, since Net of Fees complicates the discussion a bit.

Most position accounting systems use average cost accounting. So, the average cost of your position is zero when you are flat (you have no position), and changes as your position gets further away from zero.

You realize gains when your position gets closer to zero/flat. The average cost of that position does not change. Your realized gain or loss is the difference between this "closing" transaction value and the average cost.

Now, how to discuss trades? I think there are two practices that are rational and widely used in this space.

One approach is "flat to flat". If your positions are typically opened and closed in round lots, then flat to flat can make a lot of sense. Even if you tend to open or close positions with partial fills, flat to flat measurement can make a lot of sense, and is pretty easy to do as the cumulative realized P&L of all transactions between the first opening trade and the last closing trade.

The other approach is to count every transaction that reduces the position (moves it closer to zero/flat) as a "trade". This allows you to report the realized P&L from that "trade" as well as track other statistics like time in market, excursion, drawdown, etc.

The third approach that I'll discuss is very algorithm specific, and widely used but not exactly generic. If your algo can tag transactions as opening or closing fills, then you can do average cost accounting and use either the flat to flat or position-reducing methods described above on 'logical' rather than 'physical' positions and "trades". I think that this is some of the rationale behind things like LIFO and FIFO: trying to logically group transactions into "trades". I think that actually having the algo tag the fills and declare whether the transaction should be considered an opening or closing transaction avoids the subjective and arbitrary approaches provided by FIFO and LIFO, letting the intent of the algorithm control the definition.

## Answer by Louis Marascio (score 5)

https://quant.stackexchange.com/a/9233

I'll add my own experience here based on what we do at our firm, simply to provide more support for what Brian said in his answer.

Fills that move a position further away from 0 contribute to the average price of the position.

Fills that move a position closer to 0 "book profits" against the average price of the position to that point in time.

Any fill that causes a position to cross 0 must be handled so that it hits 0 first, and then crosses to the other side to ensure proper accounting.

In our world we refer to a "trade" as having an open time of the timestamp of the first fill that moves away from open position size of 0. The trade is closed or finalized when the size reaches 0 again. So the lifetime of the trade is simply the time spent not at position size of 0.

From your example, what you refer to as "trades" we call fills. The "trade" is the entire sequence of events that encompass moving from net position size of 0 and back again.

```
t0 we own 0 shares of A
t1 buy  500 A at x1
t2 buy  300 A at x2, average price is now the wavg of the fills
t3 sell 700 A at x3, book x3 - avg price, position now 100 shares
t4 sell 100 A at x4, book x4 - avg price, position now 0 shares
position or "trade" is now closed and we start over again
```

`t1` is the open time of the trade. `t4` is the closing time of the trade. The trade is made up of 4 total fills, 2 of which are "opening" fills and 2 are "closing" fills. A fill is an opening fill if it moves net size farther from 0. It is a closing fill if it moves net size closer to 0. Any time you reach 0 (or cross it) you close the trade and, in the case of crossing 0, start a new one. When I refer to "crossing 0" it is because we model long positions as positive size and short positions as negative size.

## Answer by Serg (score 0)

https://quant.stackexchange.com/a/9230

Here is a suggestion for performance analysis. It visualizes the quality of individual decisions, taken by the trading strategy. For simplicity purposes lets consider only BUY trades (the SELL trades may be multiplied by -1). Define reasonable trading horizon. Organize all trades in the same graph where:

- x-axis is time around the execution, such that executions always occurs at t=0.

- y-axis is the asset's price minus avg. execution price

Optionally, multiply each timeseries by corresponding trade's size. In this case the timeseries represents each trade's P&L.

Such view may provide very important insights about the strategy in addition to total performance. For example, you may observe that only a few trades contribute to total performance while the rest are "noise" trades. Then you can study what distinguishes these "special" decisions. Also, different effect like slippage can be easily observed and measured. You can also add a line that represents the average response. However, this method has its drawbacks, for instance, it doesn't account the position, but only the quality of individual decisions.

Shown in full with attribution under the source's licence. Licence: CC BY-SA 4.0 (Stack Exchange)

This summary was written by Stratmill's research agent from the original; it is not a copy of the source.