Research Task
Section titled “Research Task”- Deep research on what (FOSS) investment analysis libraries account for taxation in the most comprehensive ways, accounting for taxation on ALL different types of investment distributions: interest, dividends, taxable capital gains, deferred capital gains, return of capital, and different types of accounts: taxable (open), deferred (RRSP, 401-k), tax-free (TFSA)
- Ideal language: Python
Parameters
Section titled “Parameters”Geography
- Global
- Specify: Canada, USA
Depth
- Moderate (fast scan, key facts, 1–2 search passes)
- Deep (comprehensive, parallel searches, cited sources)
Search Strategy
- Scout first (quick angle scan → focused deep dive — recommended)
- Direct dive (single-pass research, v1 behavior)
Goal (choose one or more)
- Understand the landscape
- Assess risks
- Identify opportunities
- Decision support
Sources
- Cited in report
- No citations needed
AI Sources
- Claude (always active)
- ChatGPT (requires OPENAI_API_KEY)
- Gemini (requires GEMINI_API_KEY)
- Grok (requires GROK_API_KEY)
Output
- Append to task file (always)
- Also export to Google Doc
Additional Context
Section titled “Additional Context”Research Report
Section titled “Research Report”Generated: 2026-03-16 · Claude Sonnet 4.6
Executive Summary
Section titled “Executive Summary”No single free and open-source Python library exists that comprehensively handles investment taxation across distribution types (interest, dividends, capital gains, return of capital) and account types (taxable, tax-deferred, tax-free) for either Canada or the US. The FOSS landscape is structurally fragmented: portfolio optimization libraries (PyPortfolioOpt, Riskfolio-Lib, skfolio) contain zero tax logic; income tax calculators (Tax-Calculator, tenforty, habutax) model form-level computations but do not integrate with portfolio analytics; and tax-loss harvesting utilities (danguetta/rebalancer, fava_investor) address narrow operational tasks tied to specific accounting systems. The academic literature has formalized tax-aware portfolio construction — notably Boyd et al.’s convex optimization framework and Dammon-Spatt-Zhang’s dynamic programming model — but these papers have not produced maintained open-source implementations. For a practitioner seeking comprehensive tax-aware investment analysis, the realistic path is composing multiple existing tools (cvxportfolio for optimization, Beancount/fava_investor for tax-lot accounting, custom code for jurisdiction-specific tax rules) rather than finding or extending a single library.
Landscape Overview
Section titled “Landscape Overview”Confidence: Medium (score: 72)
The FOSS Python ecosystem for investment analysis is rich in pre-tax portfolio optimization but nearly barren in tax-aware computation. This gap is not a missing feature — it is a structural absence across three distinct tool categories that, in a comprehensive system, would need to work together but currently do not.
Category 1: Portfolio optimization libraries. PyPortfolioOpt (~4.6k GitHub stars), Riskfolio-Lib (~3k stars), skfolio (~1.3k stars), and pyfolio (~5.5k stars) provide mean-variance optimization, Black-Litterman models, hierarchical risk parity, CVaR optimization, and performance analytics [1][2][3][4]. None contains any tax logic whatsoever. skfolio’s transaction cost and turnover constraint framework is the closest structural analog to what a tax-cost model would require, but no tax-specific implementation exists [3].
Category 2: Income tax calculators. PSLmodels Tax-Calculator provides the most granular US federal tax computation, covering 200+ parameters across 18 income types with explicit separation of qualified vs. ordinary dividends and short-term vs. long-term capital gains [5][6]. tenforty implements US federal tax with Form 8960 (Net Investment Income Tax) coverage [7]. habutax handles 1099-DIV, 1099-INT, and 1099-R forms but lacks Schedule D for capital gains [8]. On the Canadian side, cdn_tax_calc accepts eligible and ineligible dividends separately with RRSP deductions for Ontario and Quebec, but uses 2019 rates and is unmaintained [9]. kronostechnologies/tax-ca (TypeScript, not Python) includes modules for RRSP, TFSA, RRIF, and LIF with dividend credit computation [10]. All of these tools answer “given these income amounts, what is my tax?” — none answers “given this portfolio, what are my after-tax returns?”
Category 3: Tax-loss harvesting and accounting utilities. danguetta/rebalancer implements per-lot capital gains tracking, wash sale avoidance, and gain-minimizing lot selection, but is eTrade-specific and single-period [11]. fava_investor (incorporating the former fava_tax_loss_harvester) provides tax-loss harvesting identification and wash-sale detection within the Beancount double-entry accounting ecosystem, but is an identification tool, not an optimizer [12][13]. The tsiemens/acb calculator (Rust, not Python) is the most feature-complete open-source adjusted cost base tool for Canada, handling the superficial loss rule and affiliated persons across account types [14].
The gap between these FOSS tools and commercial platforms is not incremental but structural. SEI LifeYield’s Unified Managed Household suite coordinates asset location, cross-account tax-loss harvesting, tax-smart withdrawals, and household-level rebalancing simultaneously — an independent EY evaluation found this multi-account tax coordination improves investor outcomes by up to 33% [15][16]. BlackRock’s Aladdin Wealth includes a tax-intelligent optimizer [17]. Parametric Portfolio Associates has operated direct-indexing tax management for over 30 years [18]. No FOSS tool approaches this level of integration.
Key Players & Entities
Section titled “Key Players & Entities”Confidence: Medium (score: 74)
Portfolio Optimization Libraries (No Tax Logic)
Section titled “Portfolio Optimization Libraries (No Tax Logic)”| Library | Language | Stars | Tax Features | Best Use |
|---|---|---|---|---|
| PyPortfolioOpt | Python | ~4.6k | None | Mean-variance, Black-Litterman, HRP [1] |
| Riskfolio-Lib | Python | ~3k | None | 13 risk measures, CVaR, drawdown optimization [2] |
| skfolio | Python | ~1.3k | Transaction cost constraints (not tax) | scikit-learn-compatible optimization [3] |
| pyfolio / pyfolio-reloaded | Python | ~5.5k | None | Performance/risk tear sheets [4] |
| cvxportfolio | Python | — | Zero (but extensible cost model) | Multi-period optimization, backtesting [19][20] |
Tax Calculators
Section titled “Tax Calculators”| Tool | Language | Jurisdiction | Distribution Types Modeled | Account Types |
|---|---|---|---|---|
| PSLmodels Tax-Calculator | Python | US Federal | Interest, ordinary/qualified dividends, ST/LT capital gains, Section 1250, 28% rate gains | None [5][6] |
| tenforty | Python | US Federal + 12 states | Interest, ordinary/qualified dividends, ST/LT capital gains, ISO gains | None [7] |
| habutax | Python | US Federal + NC | Interest, dividends (via 1099), retirement distributions | None [8] |
| cdn_tax_calc | Python | Canada (ON, QC) | Eligible/ineligible dividends, capital gains | RRSP deductions [9] |
| kronostechnologies/tax-ca | TypeScript | Canada (all provinces) | Dividend credit, income tax | RRSP, TFSA, RRIF, LIF [10] |
Tax-Loss Harvesting & ACB Tools
Section titled “Tax-Loss Harvesting & ACB Tools”| Tool | Language | Jurisdiction | Key Features | Limitations |
|---|---|---|---|---|
| danguetta/rebalancer | Python | US | Per-lot gains tracking, wash sale avoidance, TLH | eTrade-only, single-period [11] |
| fava_investor | Python | US | TLH identification, wash-sale detection, gains minimizer | Beancount-only, identification not optimization [12][13] |
| tsiemens/acb | Rust | Canada | ACB calculation, superficial loss rule, affiliated persons, CAD/USD rates | No ROC, no distribution types [14] |
| cad-capital-gains | Python | Canada | ACB, superficial loss (full only), Bank of Canada rates | No partial superficial loss, no ROC [21] |
| AdjustedCostBase.ca | Web (closed) | Canada | ACB, ROC, reinvested distributions, stock splits | Not FOSS; superficial loss detection is manual [22][23] |
Retirement Simulators with Tax Modeling
Section titled “Retirement Simulators with Tax Modeling”| Tool | Language | Jurisdiction | Account Types | Tax Depth |
|---|---|---|---|---|
| Owl (mdlacasse) | Python | US | 401(k), Roth IRA, taxable | Federal brackets, Medicare, ACA, Social Security, RMDs, Roth conversions [24] |
| fplan (willauld) | Python | US | Traditional IRA, Roth, after-tax | 2017 federal brackets, 15% flat capital gains [25] |
| retirement_drawdown_simulator_canada | Ruby | Canada | RRSP, TFSA, taxable | Federal/provincial brackets (all provinces except QC), CPP/OAS, RRIF conversion [26] |
| retirement-planner (mjcrepeau) | TypeScript | US + Canada | RRSP, TFSA, RRIF, LIRA, LIF, FHSA, 401(k), Roth, IRA, HSA | Capital gains inclusion rate (50%/66.67%), dual-country brackets [27] |
Academic Contributors
Section titled “Academic Contributors”| Author(s) | Contribution | Publication |
|---|---|---|
| Dammon, Spatt, Zhang (2004) | Dynamic programming model of optimal asset location with taxable/tax-deferred accounts | The Journal of Finance [28] |
| Moehle, Kochenderfer, Boyd, Ang (2021) | Convex relaxation for tax-aware portfolio construction with tax-lot granularity | Journal of Optimization Theory and Applications [29][30] |
| Haugh, Iyengar, Wang (2016) | Duality-based tax-aware dynamic allocation with exact cost-basis tracking | Operations Research [31] |
| Idzorek (2023) | Multi-account alpha-tracking-error framework unifying asset location, TLH, and rebalancing | Financial Analysts Journal [32] |
| Reichenstein & Jennings | After-tax asset allocation methodology and “extended portfolio” concept | CFA Research Foundation [33][34] |
How It Works
Section titled “How It Works”Confidence: Medium (score: 68)
A comprehensive tax-aware investment library must integrate four computational layers that currently exist only in isolation across the FOSS landscape.
Layer 1: Distribution Type Taxonomy
Section titled “Layer 1: Distribution Type Taxonomy”Every investment distribution must be classified by type, as each receives different tax treatment depending on jurisdiction and account type. The CFA Institute’s private wealth curriculum defines the core accumulation formulas [35]:
- Annual accrual taxation (interest, non-qualified dividends):
FVIF = [1 + r(1-t)]^T - Deferred capital gains taxation:
FVIF = (1+r)^T(1-t_cg) + t_cg - Deferred gains with cost basis:
FVIF = (1+r)^T(1-t_cg) + t_cg * B - Blended taxation (mixed income + capital components): combines the above
In Canada, additional complexity arises from eligible dividends (38% gross-up with federal/provincial tax credits) vs. non-eligible dividends (15% gross-up), and return of capital distributions that reduce adjusted cost base rather than creating immediate taxable income [22][23][36]. Canadian ETFs commonly distribute ROC, and failing to track ACB adjustments for phantom (non-cash reinvested) distributions can result in significant over-taxation — Invesco documented $421 in unnecessary tax on a modest holding from this error alone [36].
No surveyed FOSS tool models all distribution types computationally. Tax-Calculator comes closest for US federal, with explicit fields for taxable interest, qualified dividends, ordinary dividends, and short/long-term capital gains [5][6]. For Canada, no Python tool was found that handles the eligible/non-eligible dividend gross-up mechanism, return of capital ACB adjustments, and capital gains inclusion rates in a unified computation.
Layer 2: Account-Type Tax Treatment
Section titled “Layer 2: Account-Type Tax Treatment”The same distribution is taxed entirely differently depending on account type:
| Distribution Type | Taxable (Non-Registered) | Tax-Deferred (RRSP/401k) | Tax-Free (TFSA/Roth) |
|---|---|---|---|
| Interest | Ordinary income rate, annually | Deferred; ordinary on withdrawal | Tax-free |
| Qualified/Eligible Dividends | Preferential rate (US) / Gross-up + credit (Canada) | Deferred; ordinary on withdrawal | Tax-free |
| Long-term Capital Gains | Preferential rate on realization | Deferred; ordinary on withdrawal | Tax-free |
| Return of Capital | Reduces cost basis (deferred) | N/A (no ACB tracking needed) | Tax-free |
The academic literature converges on the “asset location” principle: place the most tax-inefficient assets (bonds, REITs) in tax-deferred accounts, tax-efficient assets (broad equity) in taxable accounts, and highest-expected-return assets in tax-free accounts [28][33][34]. No FOSS optimizer implements this logic. Retirement simulators (Owl, fplan) model account-level withdrawals with bracket-aware taxation [24][25] but do not decompose returns by distribution type within each account.
Layer 3: Tax-Lot Accounting
Section titled “Layer 3: Tax-Lot Accounting”In taxable accounts, each purchase lot has its own cost basis, holding period, and unrealized gain/loss. The Boyd et al. convex optimization framework operates at the individual tax lot level, producing trade lists specifying shares to buy per asset and shares to sell from each lot [29][30]. Their method handles wash sale avoidance and the non-convex nature of tax-lot optimization through a two-stage convex relaxation solvable via CVXPY — but no public code was released. danguetta/rebalancer is the only FOSS tool implementing per-lot gain-minimizing sell logic with wash sale avoidance [11]. For Canada, the superficial loss rule (61-day window, extending across affiliated persons including RRSPs and TFSAs) adds cross-account complexity that only tsiemens/acb addresses in FOSS, and that tool is written in Rust [14].
Layer 4: Optimization Integration
Section titled “Layer 4: Optimization Integration”The optimization problem is: given current holdings across multiple accounts, target allocation, tax rules, and distribution forecasts, what trades minimize tax drag while achieving the desired portfolio? cvxportfolio provides the most extensible framework — its custom cost model classes could theoretically encode tax costs — but all tax logic must be built from scratch [19][20]. skfolio’s constraint framework could proxy tax drag through turnover and transaction cost constraints [3]. Neither has been extended for tax-aware optimization in any public implementation.
Trends & Developments
Section titled “Trends & Developments”Confidence: Medium (score: 62)
1. The academic-to-FOSS pipeline is broken. Boyd et al.’s tax-aware convex optimization paper (2021) provides a rigorous, implementable mathematical framework, and cvxportfolio exists from the same Stanford group — but the tax-specific code was never open-sourced [19][29][30]. Haugh et al.’s duality-based approach (2016) achieved sub-optimality gaps of only 3-10 basis points with 25 securities [31], but similarly has no public implementation. The gap between published methods and available code represents the single largest missed opportunity in the FOSS investment tooling landscape.
2. Institutional convergence on multi-account household coordination. SEI’s acquisition of LifeYield signals that multi-account, household-level tax coordination is the competitive frontier for wealth management platforms [15][16]. Idzorek’s 2023 paper in the Financial Analysts Journal formalizes this as a unified optimization problem across multiple accounts with different tax treatments [32]. No FOSS tool attempts this level of coordination.
3. Canadian tooling is especially sparse. The academic literature is overwhelmingly US-focused. Canadian-specific features — eligible vs. non-eligible dividend gross-up and tax credit, TFSA mechanics, RRSP deduction limits, the 2024 capital gains inclusion rate change (50% to 66.67% above $250k), superficial loss rules across affiliated persons — are largely unaddressed in both academic and FOSS implementations [14][21][26][27]. The sunsetting of ACBTracking.ca’s distribution database in 2025 removes a key resource that Canadian investors relied on for phantom distribution and ROC data, creating demand for FOSS alternatives [37].
4. Retirement simulators lead on tax awareness but lack distribution granularity. Tools like Owl and retirement-planner model progressive brackets, benefit clawbacks, and account-type withdrawal strategies [24][27]. However, every retirement simulator treats account-level withdrawals as a single taxable event rather than modeling the underlying distribution character — a fundamental limitation for accurate after-tax projection.
5. The Beancount ecosystem is the strongest accounting foundation. fava_investor provides tax-lot tracking, TLH identification, wash-sale detection, and a gains minimizer within the Beancount double-entry accounting system [12][13]. While it is an identification/reporting tool rather than an optimizer, its accounting layer is the most complete FOSS foundation for the data that a tax-aware optimizer would need.
6. Compose, don’t build from scratch. Given the landscape, the most viable path for a solo developer or small team is composing existing tools: cvxportfolio for multi-period optimization [19][20], Beancount/fava_investor for tax-lot accounting [12][13], tenforty or Tax-Calculator for US tax rate computation [5][7], tsiemens/acb’s logic for Canadian ACB and superficial loss rules [14], and custom Python for the orchestration layer that bridges these components with account-type awareness and distribution-type decomposition. The critical custom work concentrates on three pieces: a jurisdiction-specific tax rules engine, an account-type coordinator, and the optimization bridge that translates lot-level tax costs into optimizer constraints.
Next Steps
Section titled “Next Steps”- Evaluate cvxportfolio’s cost model extensibility. Determine whether its custom cost class framework can encode tax-lot-level capital gains costs and wash sale constraints without architectural modifications.
- Prototype a distribution-type tax engine in Python. Starting from tenforty’s US tax logic and the CFA accumulation formulas, build a standalone module that computes after-tax returns for each distribution type across account types for both US and Canadian jurisdictions.
- Assess tsiemens/acb for Python bindings or port. The Rust ACB calculator is the most feature-complete Canadian tool; determine whether FFI bindings (via PyO3) or a Python port is more practical for integration.
- Monitor Boyd group for code release. The Stanford tax-aware optimization paper’s methods are directly implementable in CVXPY; any future code release would be the single most impactful addition to the FOSS landscape.
- Engage the fava_investor community. As the strongest FOSS accounting foundation, assess whether fava_investor’s data model can serve as the lot-level input to a tax-aware optimizer without requiring Beancount as the sole data source.
Sources
Section titled “Sources”- [1] PyPortfolioOpt — Financial portfolio optimisation in Python — GitHub. Secondary.
- [2] Riskfolio-Lib — Portfolio Optimization and Quantitative Strategic Asset Allocation — GitHub. Secondary.
- [3] skfolio — Portfolio optimization built on scikit-learn — GitHub / skfolio.org. Secondary.
- [4] pyfolio — Portfolio and risk analytics in Python — GitHub. Secondary.
- [5] Tax-Calculator — PSLmodels microsimulation — PSLmodels. Secondary.
- [6] Tax-Calculator Input Variables — PSLmodels. Secondary.
- [7] tenforty — Python library to compute US federal taxes — GitHub. Secondary.
- [8] habutax — Open-source tax solver for US personal income tax — GitHub. Secondary.
- [9] cdn_tax_calc — Canadian tax calculator — GitHub. Partial.
- [10] kronostechnologies/tax-ca — GitHub. Secondary.
- [11] rebalancer — Etrade Portfolio Rebalancer with tax-loss harvesting — GitHub. Secondary.
- [12] fava_investor — GitHub. Secondary.
- [13] fava_tax_loss_harvester — Tax loss harvester plugin for Fava/Beancount — GitHub. Secondary.
- [14] acb — Adjusted cost base calculator — GitHub. Secondary.
- [15] LifeYield Launches Multi-Account UMA Tax Overlay — SEI LifeYield. Partial.
- [16] SEI acquires LifeYield — Investing.com. Partial.
- [17] Aladdin Wealth — BlackRock. Secondary.
- [18] Direct Indexing — Parametric — Parametric / Morgan Stanley. Partial.
- [19] cvxportfolio — Portfolio optimization and back-testing — GitHub. Secondary.
- [20] Cvxportfolio Documentation v1.5.0 — cvxportfolio.com. Secondary.
- [21] cad-capital-gains — CLI tool for Canadian capital gains and ACB — GitHub. Secondary.
- [22] AdjustedCostBase.ca — AdjustedCostBase.ca. Secondary.
- [23] Return of Capital and How it Affects Adjusted Cost Base — AdjustedCostBase.ca Blog. Secondary.
- [24] Owl: Retirement planner with great wisdom — GitHub. Secondary.
- [25] fplan: Retirement planning financial calculator — GitHub. Secondary.
- [26] retirement_drawdown_simulator_canada — GitHub. Secondary.
- [27] retirement-planner (mjcrepeau) — GitHub. Secondary.
- [28] Optimal Asset Location and Allocation with Taxable and Tax-Deferred Investing — The Journal of Finance / Wiley. Partial.
- [29] Tax-Aware Portfolio Construction via Convex Optimization (arXiv) — arXiv. Primary.
- [30] Tax-Aware Portfolio Construction via Convex Optimization (Stanford) — Stanford / Boyd Group. Primary.
- [31] Tax-Aware Dynamic Asset Allocation — Operations Research / INFORMS. Partial.
- [32] Personalized Multiple Account Portfolio Optimization — CFA Institute / Financial Analysts Journal. Primary.
- [33] After-Tax Asset Allocation (Reichenstein) — SSRN / Financial Analysts Journal. Partial.
- [34] Is Asset Location Strategy Worth the Effort? — Fictitious Capitalist. Secondary.
- [35] Inflation and Tax on Investments (CFA Level III) — AnalystPrep. Primary.
- [36] How to handle phantom distributions from ETFs to avoid double taxation — Invesco Canada. Secondary.
- [37] ACBTracking.ca — ACBTracking.ca. Partial.
- [38] Adjusted cost base — finiki — finiki (Canadian Financial Wiki). Secondary.
- [39] Applying the Superficial Loss Rule with AdjustedCostBase.ca — AdjustedCostBase.ca Blog. Secondary.
- [40] Tax treatment of mutual funds — Canada.ca — CRA / Government of Canada. Partial.
- [41] okama — Investment portfolio analyzing tools — GitHub. Secondary.
- [42] stay-the-course — Lazy portfolio rebalancer for GnuCash — GitHub. Secondary.
- [43] py1040 — A U.S. personal income tax calculator — GitHub. Secondary.
- [44] The Asset Location Decision Revisited — Financial Planning Association. Primary.
- [45] Asset Location in Tax-Deferred and Conventional Savings Accounts (NBER) — NBER. Partial.
- [46] Tax-Adjusted Portfolio Optimization and Asset Location: Extensions and Synthesis — The Journal of Wealth Management. Partial.
- [47] Taxation, Risk and Return (CFA Level III) — AnalystPrep. Primary.
- [48] capital-gains-calculator (richardwu) — GitHub. Secondary.