The year-end loss harvest maximiser is a one-shot variant of the tax-aware DI engine with a calendar gate and a different objective. Instead of jointly trading off TE against tax cost, it maximises realised losses subject to a gain ceiling of zero and the wash-sale lookback. It runs in November and December, when the holder knows what the year's external gains look like and wants to bank as much loss as possible before December 31.
Maximise loss, hold gains to zero, respect wash-sale
max Σ_i realised_loss_i(sell_i, lot_i)
sell, lot
s.t. Σ_i realised_gain_i(sell_i, lot_i) = 0 (one-sided)
sell_i ∈ [0, holding_i] (no shorting)
wash_lock(t-30, t+30) for any harvested ticker (US §1091)
TE_drift(w_after) ≤ δ_max (optional)Three things distinguish this from the daily DI engine:
- One-sided. The optimizer will not realise a gain. The constraint Σ realised_gain = 0 forces the harvest to be loss-only — the planner assumes any external gains the household will offset are already known elsewhere.
- Calendar gate. The window is "today through December 31." The wash-sale lock spills into January for late-December sells, but those locks don't matter for the current tax year — the loss is already booked into the prior year.
- TE drift, not TE budget. The constraint is on residual TE after harvest — typically δ_max = 25–50 bp — to ensure the post-harvest portfolio isn't dramatically off-track. δ_max controls how aggressive the harvest is allowed to be.
$2M tax-aware DI account, snapshot December 5
Representative output: a $2M tax-aware DI account with 18 lots showing embedded losses; 6 of those lots are wash-sale locked from a November harvest run (the lock expires January 4).
| Eligible loss-bearing lots | 12 of 18 |
| Total realisable loss | $71,400 |
| TE drift after harvest | +14 bp |
| Locked names · expires Jan 4 | 12 |
| Net loss available against external gains | $71,400 |
Across US large-cap (100), US all-cap (1,000), and a 50-name concentrated book
Running the maximiser against a December 5 snapshot for ten years of historical data, three universes:
| Universe | Median harvest / NAV | 10th pctile | 90th pctile |
|---|---|---|---|
| US large-cap (100) | 0.9% | 0.2% | 2.1% |
| US all-cap (1,000) | 1.4% | 0.4% | 3.6% |
| 50-name concentrated book | 1.7% | 0.5% | 5.2% |
Why the November harvest matters more than people think
A common mistake: running the year-end maximiser only in late December. The 30-day lookback means any name harvested between December 1 and December 31 will be locked into January. For names sold close to year-end, the lockout doesn't matter for the current tax year. But for the highest-velocity harvests, a better strategy is to start in early November:
What this tool is and isn't
- Not a strategy. The maximiser doesn't manage an ongoing account. It runs once, returns a sell list, and exits. The continuous tax-aware DI strategy is what runs the rest of the year.
- Assumes external gains exist. The maximiser's value to the holder depends on having gains to offset. Loss carryforwards work too, but the present-value math is weaker for losses banked against carryforwards 3+ years out.
- No automatic substitution. The maximiser flags lots to sell. The implementation of the replacement-security purchase (to maintain factor exposure during the lock) is left to the daily DI engine that runs the same account, or to a manual buy ticket if the account isn't on a daily strategy.
For the underlying replacement-security selection logic, see replacement-security selection. For the multi-period tool that handles transition rather than year-end, see the transition planner.
- Israel & Liberman (2020). Tax-Loss Harvesting with Uncertainty.
Educational illustration · numbers illustrative.