Strategy · deep dive

One construction, four tax engines: cross-jurisdiction direct indexing

The same optimizer, swapped between US §1091, Canadian ACB averaging, Australian 50% CGT discount, and Indian STT + grandfathering. Where the after-tax alpha lands when the tax engine changes underneath.

May 202616 min read

The same direct-indexing engine is run in four jurisdictions on this platform. The optimizer is identical across them — same objective, same constraint set, same risk model. What changes, underneath, is the tax engine: lot identification, wash-sale equivalent, holding-period boundary, and any jurisdiction-specific exemptions or surcharges. This post is about what bites where, and what the after-tax dollar looks like at the end of a five-year backtest when the same construction is swapped between US, Canadian, Australian, and Indian rules.

Jurisdictions
US · CA · AU · IN
Lot methods
HIFO · ACB · FIFO · FIFO
Wash-sale eq.
§1091 · superficial · n/a · n/a
Special rules
AU 50% · IN STT + grandfathering
The four engines, side by side

What changes when the jurisdiction selector flips

Tax engine summary
USCAAUIN
Lot IDHIFO (configurable)ACB averaging (statutory)FIFO (with discount window)FIFO (with grandfathering)
Wash-sale equivalent§1091 · 30 days both sidesSuperficial loss · 30 days both sidesATO 'mischief' guidance · case lawNone statutory
Long-term boundary12 monthsn/a (single rate)12 months (50% CGT discount)12 months (LTCG @ 10%)
Headline rate (top band)37% st / 23.8% lt (incl. NIIT)33% federal + provincialMarginal × 0.5 for LT10% LTCG > ₹1L; 15% STCG
Transaction taxSTT 0.1% buy + sell
GrandfatheringPre-31-Jan-2018 basis = max(cost, FMV)
For the long-form per-jurisdiction posts, see United States, Canada, Australia, and India.
The model

One optimizer, four pluggable τ functions

The objective is the same one the long-only deep-dive describes — a TE penalty against the local benchmark plus a tax-cost penalty. The variable that changes is τ, the tax-cost function:

Tax engine plug-in
τ_𝒥(w) = Σ_t  rate_𝒥(holding_period_t)  ·  realised_gain_𝒥(t, w)
                +  surcharge_𝒥(realised_𝒥)
                +  transaction_tax_𝒥(turnover)

where  𝒥 ∈ {US, CA, AU, IN}
       rate_𝒥, realised_𝒥, surcharge_𝒥, transaction_tax_𝒥 are the
       jurisdiction's lot-identification rule + applicable rate schedule
Source: TaxView optimizer, multi_jurisdiction_di. The same Problem object is solved with a different tax engine selected by Account.jurisdiction.

The lot-identification piece is the consequential one. Under HIFO the optimizer can target the highest-cost lot to maximise the realised loss on a sale; under ACB it can't — every sale realises a slice of the average basis, so the harvest signal has to be larger in magnitude before the trade clears. Under FIFO with a discount window (AU) the optimizer trades off early realisation against waiting for the long-term gate to open, so the timing dimension becomes load-bearing.

The backtest

Same vintage, same universe, four engines

The cleanest comparison: same start date (Jan 2 2019), same universe (US large-cap, 100 names — used as a stand-in for "large-cap liquid index" in each jurisdiction; production runs use the local large-cap index in CA, AU, and IN), same TE budget (5%), same starting capital ($1M), and only the tax engine swapped underneath.

After-tax alpha by jurisdiction · annualised over 5 yrs[Illustrative · real backtest pending]
After-tax α (bp/yr)Lifetime harvest / NAV (%)
United States · HIFO + §1091130 / 7Canada · ACB + superficial loss50 / 3Australia · FIFO + 50% discount88 / 4India · FIFO + STT + ₹1L LTCG exempt62 / 5
Source: TaxView backtest, multi_jurisdiction_di, vintage 2019, $1M, US large-cap (100). Local statutory rates and lot methods enabled per jurisdiction. After-tax alpha measured against the same gross-of-tax benchmark in each engine.
Per-jurisdiction summary
JurisdictionPre-tax CAGRAfter-tax CAGRαHarvest / NAV / yrTurnover
United States12.6%12.0%+130 bp1.4%26%
Canada12.4%11.4%+50 bp0.6%18%
Australia12.5%11.6%+88 bp0.8%22%
India12.5%11.7%+62 bp1.0%32%
US wins because HIFO gives the optimizer maximum surgical control over which lot to realise. AU wins second because the 50% discount on long-term lots dramatically loosens the holding-period cost, so the optimizer can afford to take more long-term gain to free up substitutions. IN's higher turnover is partly STT-driven optimisation around the grandfathering crossover. CA's flat ACB suppresses the harvest signal — every sale moves the average basis instead of removing a high-basis lot.

Tax alpha is not portable. The same optimizer, on the same names, on the same dates, produces 50 bp in Canada and 130 bp in the US — because lot mechanics, not portfolio construction, are what HIFO turns on.

What's specific to each engine

The interesting edge cases

  • CA · ACB averaging. When the optimizer would otherwise sell into a small embedded loss, the ACB rule means the realised loss is fractional of the average — you have to dispose of the entire position to fully realise it. The optimizer respects this and will sometimes hold a partial loss rather than realise a smaller fraction.
  • AU · holding-period gate. A name 11 months 28 days into a long-term hold has a dramatically different marginal tax cost than the same name 12 months 2 days in. The optimizer's tax penalty is a step function across that gate, and the solver makes timing trades (delay a sell by a few days) when the discount kicks in.
  • IN · grandfathering crossover. For lots acquired before 31 Jan 2018, basis is max(historical cost, FMV on 31 Jan 2018). The optimizer's lot record carries both numbers and uses the right one when computing realised gain. Without this, harvest signals on long-tenured pre-2018 lots are systematically wrong.
  • US · NIIT and AMT interactions. The 3.8% NIIT layer sits on top of long-term capital gains for high earners, so the effective long-term rate is 23.8% rather than 20%. The optimizer reads marginal-rate inputs on a per-account basis to handle this.
Limitations

What's not in the engine

  • State / provincial tax. The engines compute federal-equivalent tax only. State (US), provincial (CA), and other sub-national layers are passed through as a marginal-rate adjustment but not modelled with their own statutes.
  • Cross-border treaties. The engine assumes a single jurisdiction per account. Treaties are not applied; if you need a treaty position computed, that's a separate workflow.
  • Inheritance / step-up. Step-up at death, gifting basis-carryover, and pension-vehicle wrappers are not modelled here. They sit downstream of the optimizer in the household-planning layer.
Notes & references
  1. United States — IRC §1091 (wash sales), §1259 (constructive sales), §1411 (NIIT), §1(h) (capital gain rate schedule).
  2. Canada — Income Tax Act §40(2)(g)(i) (superficial loss), §47 (identical properties / ACB rule).
  3. Australia — Income Tax Assessment Act 1997, Part 3-1 (CGT). The 50% discount is in §115-25; the ATO's 'wash sale' guidance is in TR 2008/1.
  4. India — Income Tax Act §10(38), §112A (LTCG on listed equity), STT under the Finance (No. 2) Act, 2004. Grandfathering provision in §112A(4).

Educational illustration · numbers illustrative. Nothing here is investment, tax, or legal advice; jurisdictional rules change.

Related