v1.0.0 to v1.1.0
44 added, 24 removed. Audit A to A.
---
name: cross-strategy-tax-lot-optimization
- description: Quantitative tax optimization engine for cross-strategy tax-lot selection
- (HIFO, Specific ID, LTCG optimization), internal order netting, and wash-sale rule
- interception.
+ description: US tax-lot selection engine for multi-strategy entities - HIFO / Specific
+ Lot Identification and LTCG-preferring ordering under Treas. Reg. 1.1012-1(c), internal
+ cross-strategy order netting, and an IRC 1091 wash-sale interception screen across
+ sub-strategies.
domain: Tax Accounting & Optimization
subdomain: Tax-Lot Accounting
tags:
- tax-lot
- hifo
- tax-loss-harvesting
- wash-sale
- internal-netting
- capital-gains
- cross-strategy
brokers_frameworks:
- IRS Form 8949
- Python Dataclasses
- version: "1.0.0"
+ version: "1.1.0"
author: algo-trading-skills-contributors
license: Apache-2.0
---
## When to Use
- Use this skill in multi-strategy funds, wealth management engines, and unified tax-managed accounts where multiple sub-strategies trade the same asset universe under a single tax entity. Selling shares without specific tax-lot selection defaults to FIFO, causing unnecessary capital gains tax drag. This module applies **Highest-In-First-Out (HIFO)** and **Long-Term Capital Gain (LTCG)** optimization, performs cross-strategy order netting, and intercepts 30-day wash-sale rule violations.
+ Use this skill in multi-strategy funds, wealth-management engines, and unified tax-managed accounts where several sub-strategies trade the same asset universe **under a single US tax entity**. A sell order placed without a specific-lot identification is charged against the earliest lot acquired — FIFO — by default under Treas. Reg. § 1.1012-1(c)(1)(i), which often realizes short-term gains that a higher-basis lot would have avoided.
+ This module:
+
+ - Ranks open tax lots by **HIFO** (highest cost basis first) or **LTCG-preferring** order, implemented as Specific Lot Identification.
+ - Nets offsetting sub-strategy orders internally so only the residual is routed externally and only the residual is treated as a disposition.
+ - Screens the resulting loss lots against the **IRC § 1091 61-day window** (30 days before the sale, the sale date, 30 days after) and reports a quantity-limited disallowance.
+
+ ## When NOT to Use
+
+ - **§ 475(f) mark-to-market electors.** For securities in an elected trading business, gains and losses are ordinary, and the wash-sale rules and capital-loss limitations do not apply ([IRS Topic 429](https://www.irs.gov/taxtopics/tc429)). Applying this skill's wash-sale screen there produces a disallowance that does not exist. See `mark-to-market-election-for-active-traders-us`.
+ - **Non-US tax entities.** Every rule implemented here is US federal. Other jurisdictions use different matching rules (for example a same-day/30-day share-pooling regime rather than HIFO), and state treatment may differ from federal.
+ - **Pods that are separate tax entities.** This module assumes one taxpayer. If pods file separately, an internal cross is a real transaction between two taxpayers and one pod's buy does not create a wash sale for another.
+ - **Cent-exact tax filing.** Monetary values are `float`. Use this for lot *selection*, then re-derive reportable figures in a decimal ledger — see `automated-tax-lot-reporting-pipeline`.
+
## Prerequisites
- - Active tax-lot inventory with attributes: `acquisition_date`, `cost_basis_price`, `quantity`, `holding_days`.
- - Current market price for target security ($P_{\text{mkt}}$).
+ - Open tax-lot inventory carrying `lot_id`, `strategy_id`, `symbol`, `acquisition_date` (YYYY-MM-DD), `days_held`, `cost_basis_per_share`, and `quantity`.
+ - Current market price for the target security.
+ - **Operational prerequisite for anything other than FIFO:** an adequate identification must reach the broker no later than the earlier of the settlement date or the settlement time required by Exchange Act Rule 15c6-1 — T+1 for most US equities since 28 May 2024 — or a standing instruction on the account (Treas. Reg. § 1.1012-1(c)(8)). Without it the IRS treats the sale as FIFO regardless of what this module selected.
+ - Known replacement purchases across **all** sub-strategies for the traded symbol, with signed day offsets relative to the loss sale.
## Workflow
- 1. **Tax Lot Selection (HIFO / Specific ID)**:
- - Rank open tax lots for sell order:
- - For Tax Loss Harvesting / Gain Minimization: Rank by highest cost basis price ($\max P_{\text{cost}}$).
- - Separate Long-Term ($> 365$ days) vs Short-Term ($\le 365$ days) lots.
- 2. **Cross-Strategy Order Netting**:
- - Aggregate buy orders and sell orders across sub-strategies for symbol $S$.
- - Compute $\text{Net Order} = \sum Q_{\text{buy}} - \sum Q_{\text{sell}}$.
- 3. **Wash Sale Interception**:
- - Check if any sub-strategy purchased symbol $S$ within 30 days prior to or after a loss-realizing sell order.
- - If wash sale triggered $\implies$ Disallow loss deduction and defer cost basis adjustment.
- 4. **Audit Report Generation**: Generate structured `TaxLotOptimizationReport`.
+ 1. **Net cross-strategy orders first.** Call `net_cross_strategy_orders(orders)` for the symbol. The internally crossed quantity never leaves the tax entity, so it realizes nothing; only `net_quantity` is a disposition. Running lot selection on the gross sell quantity double-counts realized losses and overstates harvested capital losses.
+ 2. **Select the method deliberately.** `HIFO_MIN_TAX` maximizes near-term loss realization; `LTCG_OPTIMIZED` takes long-term lots first to pay the preferential rate, then the highest basis within each holding-period bucket; `FIFO` is the statutory default. An unrecognized method string raises — it is never silently downgraded to FIFO.
+ 3. **Register replacement purchases with signed offsets.** `register_replacement_purchase(symbol, strategy_id, days_from_sale, quantity)` — negative for buys before the loss sale, positive for buys after, `0` for same-day. The post-sale side matters most: a pod that buys back the day after another pod harvests a loss triggers § 1091 just as surely as a pre-sale buy.
+ 4. **Run `optimize_sell_order`.** Pass `sale_date` whenever you have it: without it the long-term test falls back to `days_held > 365`, which misclassifies any lot whose holding period spans a leap day. Use `dry_run=True` to score several methods against the same inventory before committing.
+ 5. **Escalate the disallowance.** `total_disallowed_loss_usd` is this sale's § 1091 disallowance only. The offsetting basis increase on the replacement shares (§ 1091(d)) and holding-period tacking (§ 1223(3)) are **not** applied here — hand the executions to `wash-sale-rule-tracking-us` to close the loop.
> Full procedure: see `references/workflows.md`.
> Standards reference: see `references/standards.md`.
> Printable pre-flight checklist: see `assets/checklist.md`.
## Common Pitfalls
- - **Defaulting to Broker FIFO**: Accepting default broker FIFO accounting, realizing short-term capital gains first instead of high-cost lots.
- - **Cross-Strategy Wash Sale Triggers**: Pod A selling AAPL at a loss while Pod B buys AAPL on the same day, triggering an IRS Wash Sale violation.
- - **Un-netted Execution Drag**: Sending Pod A's sell 1000 shares and Pod B's buy 1000 shares to the market separately, incurring double commissions and bid-ask spread costs.
+ - **Selecting HIFO without identifying the lot to the broker.** The selection is only respected if adequate identification is delivered by the earlier of settlement date or the Rule 15c6-1 settlement time (T+1). A HIFO decision made internally on T+2 is legally FIFO, and the realized gain on the 1099-B will not match the internal ledger.
+ - **Scanning the wash-sale window backwards only.** IRC § 1091 covers 30 days *after* the loss sale as well as before. Harvesting a loss in Pod A on Monday and letting Pod B rebalance into the same name on Tuesday disallows the loss.
+ - **Assuming internal netting launders the wash sale.** Crossing Pod B's buy against Pod A's sell removes the market impact, not the tax event. Where the pods are separate taxpayers the buy is still a replacement purchase.
+ - **Taxing the gross rather than the net.** Pod A sells 1,000 and Pod B buys 600 inside one entity; only 400 shares are disposed of. Feeding 1,000 into lot selection invents 600 shares of realized loss that no return can claim.
+ - **Treating the disallowance as all-or-nothing.** § 1091 disallows the loss only on shares actually replaced. Replacing 40 of 100 loss shares disallows 40%; the rest stays deductible.
+ - **Using `days_held > 365` as the long-term test.** The statutory test is "more than one year". A lot bought 1 Jan 2024 and sold 1 Jan 2025 is 366 calendar days old but is still short-term.
+ - **Flagging profitable sales as wash sales.** A wash sale requires a realized loss. Warning on a gain lot inside the window trains operators to ignore the alert.
## Verification
- - Instantiate `CrossStrategyTaxLotOptimizer`. Add 3 tax lots for AAPL: Lot A (\$150, 400 days old), Lot B (\$200, 100 days old), Lot C (\$100, 50 days old). Market price = \$180. Submit a sell order for 100 shares using `HIFO_MIN_TAX`. Verify optimizer selects Lot B (\$200 cost basis), realizing a \$20/share capital loss. Verify wash-sale check flags clean execution.
- - Run `python scripts/test_cross_strategy_tax_lot_optimization.py`.
+ - Instantiate `CrossStrategyTaxLotOptimizer`. Add three AAPL lots: A (\$150, acquired 2025-01-01, 400 days), B (\$200, 2025-10-01, 100 days), C (\$100, 2025-12-01, 50 days). At \$180, `HIFO_MIN_TAX` for 100 shares must select Lot B and realize a \$2,000 short-term loss with no wash sale flagged.
+ - Register a replacement buy at `days_from_sale=25, quantity=40` and re-run: exactly \$800 of the \$2,000 loss must be disallowed and \$1,200 must remain deductible.
+ - Net `SELL 1000 / BUY 600` and confirm `net_quantity == 400` and `internally_crossed_quantity == 600`.
+ ```bash
+ python -m unittest discover -s skills/cross-strategy-tax-lot-optimization/scripts
+ ```
+
## Related Skills
- `wash-sale-rule-tracking-us`
- `fifo-vs-specific-lot-tax-accounting-methods`
- ---
+ - `mark-to-market-election-for-active-traders-us`
+ - `automated-tax-lot-reporting-pipeline`