Skip to content
  • 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

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

Generated: 2026-03-16 · Claude Sonnet 4.6

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.


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.


Confidence: Medium (score: 74)

Portfolio Optimization Libraries (No Tax Logic)

Section titled “Portfolio Optimization Libraries (No Tax Logic)”
LibraryLanguageStarsTax FeaturesBest Use
PyPortfolioOptPython~4.6kNoneMean-variance, Black-Litterman, HRP [1]
Riskfolio-LibPython~3kNone13 risk measures, CVaR, drawdown optimization [2]
skfolioPython~1.3kTransaction cost constraints (not tax)scikit-learn-compatible optimization [3]
pyfolio / pyfolio-reloadedPython~5.5kNonePerformance/risk tear sheets [4]
cvxportfolioPythonZero (but extensible cost model)Multi-period optimization, backtesting [19][20]
ToolLanguageJurisdictionDistribution Types ModeledAccount Types
PSLmodels Tax-CalculatorPythonUS FederalInterest, ordinary/qualified dividends, ST/LT capital gains, Section 1250, 28% rate gainsNone [5][6]
tenfortyPythonUS Federal + 12 statesInterest, ordinary/qualified dividends, ST/LT capital gains, ISO gainsNone [7]
habutaxPythonUS Federal + NCInterest, dividends (via 1099), retirement distributionsNone [8]
cdn_tax_calcPythonCanada (ON, QC)Eligible/ineligible dividends, capital gainsRRSP deductions [9]
kronostechnologies/tax-caTypeScriptCanada (all provinces)Dividend credit, income taxRRSP, TFSA, RRIF, LIF [10]
ToolLanguageJurisdictionKey FeaturesLimitations
danguetta/rebalancerPythonUSPer-lot gains tracking, wash sale avoidance, TLHeTrade-only, single-period [11]
fava_investorPythonUSTLH identification, wash-sale detection, gains minimizerBeancount-only, identification not optimization [12][13]
tsiemens/acbRustCanadaACB calculation, superficial loss rule, affiliated persons, CAD/USD ratesNo ROC, no distribution types [14]
cad-capital-gainsPythonCanadaACB, superficial loss (full only), Bank of Canada ratesNo partial superficial loss, no ROC [21]
AdjustedCostBase.caWeb (closed)CanadaACB, ROC, reinvested distributions, stock splitsNot FOSS; superficial loss detection is manual [22][23]
ToolLanguageJurisdictionAccount TypesTax Depth
Owl (mdlacasse)PythonUS401(k), Roth IRA, taxableFederal brackets, Medicare, ACA, Social Security, RMDs, Roth conversions [24]
fplan (willauld)PythonUSTraditional IRA, Roth, after-tax2017 federal brackets, 15% flat capital gains [25]
retirement_drawdown_simulator_canadaRubyCanadaRRSP, TFSA, taxableFederal/provincial brackets (all provinces except QC), CPP/OAS, RRIF conversion [26]
retirement-planner (mjcrepeau)TypeScriptUS + CanadaRRSP, TFSA, RRIF, LIRA, LIF, FHSA, 401(k), Roth, IRA, HSACapital gains inclusion rate (50%/66.67%), dual-country brackets [27]
Author(s)ContributionPublication
Dammon, Spatt, Zhang (2004)Dynamic programming model of optimal asset location with taxable/tax-deferred accountsThe Journal of Finance [28]
Moehle, Kochenderfer, Boyd, Ang (2021)Convex relaxation for tax-aware portfolio construction with tax-lot granularityJournal of Optimization Theory and Applications [29][30]
Haugh, Iyengar, Wang (2016)Duality-based tax-aware dynamic allocation with exact cost-basis trackingOperations Research [31]
Idzorek (2023)Multi-account alpha-tracking-error framework unifying asset location, TLH, and rebalancingFinancial Analysts Journal [32]
Reichenstein & JenningsAfter-tax asset allocation methodology and “extended portfolio” conceptCFA Research Foundation [33][34]

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.

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.

The same distribution is taxed entirely differently depending on account type:

Distribution TypeTaxable (Non-Registered)Tax-Deferred (RRSP/401k)Tax-Free (TFSA/Roth)
InterestOrdinary income rate, annuallyDeferred; ordinary on withdrawalTax-free
Qualified/Eligible DividendsPreferential rate (US) / Gross-up + credit (Canada)Deferred; ordinary on withdrawalTax-free
Long-term Capital GainsPreferential rate on realizationDeferred; ordinary on withdrawalTax-free
Return of CapitalReduces 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.

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].

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.


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.


  1. 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.
  2. 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.
  3. 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.
  4. 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.
  5. 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.