๐ Weighted Average Cost (WAC)
๐ก What is WAC?
The Weighted Average Cost (WAC) is the average unit cost of an asset in a portfolio, weighted by the quantity acquired at each price.
It answers the question: "On average, how much did I pay per unit for this asset?"
Other names
- PMC โ Prezzo Medio di Carico (Italy)
- ACB โ Average Cost Basis (Canada, US)
- CMP โ Coรปt Moyen Pondรฉrรฉ (France)
๐งฎ Formula
The WAC is computed iteratively as each transaction is processed chronologically:
Where:
- \(WAC_{current}\) = current weighted average cost before this transaction
- \(Q_{pool}\) = total quantity held in the pool before this transaction
- \(Cost_{unit}\) = per-unit acquisition cost of the new transaction
- \(Q_{tx}\) = quantity added by the new transaction
โ๏ธ How LibreFolio Computes WAC
LibreFolio uses an inventory-aware iterative algorithm that processes all qualifying transactions for a given (broker, asset) pair in chronological order.
๐ท๏ธ Transaction Effects
Each transaction contributes to the WAC computation in one of these ways:
| Effect | Condition | Impact on WAC |
|---|---|---|
| Weighted | qty > 0 and unit_cost > 0 |
WAC moves toward the new acquisition cost |
| Quantity reduced | qty < 0 |
Exits at current WAC โ WAC unchanged, pool shrinks |
| Dilution | qty > 0 but unit_cost = 0 |
Pool grows, numerator unchanged โ WAC decreases |
| Auto WAC | qty > 0, cost_basis_mode = "auto" |
Pool unchanged โ units enter at current WAC |
๐ Same-Day Ordering
When multiple transactions occur on the same date:
- Additions first (qty > 0) โ processed before reductions
- Reductions second (qty < 0) โ ensures the pool doesn't go transiently negative
๐ป Pool Depletion
- When
new_qty = 0: WAC resets to 0 (position closed) - When
new_qty < 0(rounding edge case): clamped to 0
๐ Practical Examples
Example 1: Two Buys โ WAC rises
| Date | Type | Qty | Unit Cost | Pool Qty | WAC |
|---|---|---|---|---|---|
| Apr 1 | BUY | 10 | $150 | 10 | $150.00 |
| Apr 15 | BUY | 5 | $180 | 15 | $160.00 |
The second buy at a higher price pulls the WAC up.
Example 2: Buy then Sell โ WAC unchanged
| Date | Type | Qty | Unit Cost | Pool Qty | WAC |
|---|---|---|---|---|---|
| Apr 1 | BUY | 10 | $150 | 10 | $150.00 |
| Apr 15 | SELL | -5 | (at WAC) | 5 | $150.00 |
The SELL removes units at the current WAC ($150). The WAC stays unchanged โ only the pool shrinks.
Example 3: Zero-Cost Acquisition โ Dilution
| Date | Type | Qty | Unit Cost | Pool Qty | WAC |
|---|---|---|---|---|---|
| Apr 1 | BUY | 10 | $150 | 10 | $150.00 |
| May 1 | ADJUSTMENT | +5 | $0 | 15 | $100.00 |
The WAC is diluted because 5 units entered at zero cost (e.g. stock split, airdrop, gift).
๐ Cost Basis Override
For transfers and adjustments, LibreFolio supports a cost basis override: a user-specified unit cost that represents the historical cost of the transferred units.
When set (manual mode):
- The transaction enters the WAC computation as a normal weighted acquisition
- This preserves cost continuity across brokers (e.g., when transferring from broker A to broker B)
When not set (no mode specified):
- The transaction enters with
unit_cost = 0(dilution effect) - This is appropriate for stock splits, gifts, or airdrops where no purchase price exists
When auto mode (cost_basis_mode = "auto"):
- The transaction enters at the current pool WAC โ the WAC remains algebraically unchanged
- This is appropriate for transfers or adjustments where the cost basis should be inherited from the source broker's pool
Auto WAC in the UI
In the transaction form, the "Auto" toggle uses this mode. The qualifying table shows the Auto WAC (or Auto PMC in Italian) effect badge, indicating that the units entered at the current pool cost without altering the WAC.
Example 4: Transfer in Auto Mode โ WAC unchanged
| Date | Type | Qty | Unit Cost | Pool Qty | WAC |
|---|---|---|---|---|---|
| Apr 1 | BUY | 10 | $150 | 10 | $150.00 |
| Apr 15 | BUY | 5 | $180 | 15 | $160.00 |
| May 1 | TRANSFER (auto) | +3 | $160 (=WAC) | 18 | $160.00 |
The transfer receiver in auto mode inherits the current WAC as its unit cost. The pool grows but the WAC stays unchanged.
๐ Multi-Currency Handling
When a portfolio contains acquisitions in different currencies, LibreFolio:
- Determines the target currency (most frequent among acquisitions)
- Converts all unit costs to the target currency using historical FX rates
- Computes WAC in the unified target currency
FX Rate Availability
If a required FX rate is missing, the WAC computation may be incomplete. The UI warns about missing FX pairs and provides quick-actions to add or sync them.
๐ฏ Where WAC is Used in LibreFolio
- Transfer form: auto-suggests cost_basis_override for outgoing transfers
- P&L computation: realized gains = sell_price โ WAC (FIFO at runtime, WAC for cost basis)
- Portfolio view: average entry price per holding