taxjson

Open source · Canada (US engine experimental) · runs on your machine

Your broker's CSV in. Schedule 3 out.

taxjson computes capital gains by the rules the CRA publishes, each one cited (a US engine for the IRS rules ships as experimental): one average-cost pool per security across all of your accounts, the superficial-loss rule checked against your RRSP and TFSA too, written-option premiums recognised in the year written as s.49 says, renames as dated events, splits, spin-offs and mergers handled with elections you choose. Nothing leaves your computer.

bash -c "$(curl -fsSL https://taxjson.com/install.sh)"

One line on Linux or macOS; it installs taxjson and its short name tjs. Try it first on made-up exports: tjs init --demo ~/taxjson-demo. For your own books, tjs init --country canada (or usa) in the folder for your taxes, drop every year's exports into inputs/, and tjs run in this year's folder (2026/). Not sure what comes next? tjs checklist lists every step and, in a project, checks what is done and names the next one.

tjs sum  ·  tjs init --demo, tax year 2024
FOR THE RETURN — taxable accounts (crypto, ib, margin,
questrade, webull), CAD (Schedule 3, tax year 2024)
GAIN = PROCEEDS − COST(ACB) − OUTLAYS, the allowed gain;
superficial losses denied: 467.49.
shares & fund units (P1) (10689/10690)
  proceeds 71,112.60   cost(acb) 63,568.08   outlays 14.89
  gain 7,529.63   denied 0.00

shares & fund units (P2) (13199/13200)
  proceeds 21,986.83   cost(acb) 21,432.29   outlays 11.00
  gain 543.54   denied 467.49

options, crypto & other properties (P2) (15199/15300)
  proceeds 22,775.26   cost(acb) 15,675.27   outlays 89.20
  gain 7,010.79   denied 0.00

RETURN
  proceeds 115,874.69   cost(acb) 100,675.64
  outlays 115.09   gain 15,083.96   denied 467.49

! 1 sale with no purchase NOT in these totals (SAMPG.US) — tjs find-missing-history
! FX on foreign cash (line 15300): not in the rows; its estimate is NOT RELIABLE — tjs fx-cash
Not in the rows: T3/T5 slip capital gains (lines 17600, 17400). More: tjs sum --details

What you get

Every account in one summary

The whole of tjs sum on the demo project: eight made-up accounts, five taxable (an IB margin account, Questrade, Webull, crypto) and three sheltered (a TFSA, an RRSP and a locked-in LIRA). Gains, options, dividends and fees per account; the sheltered ones shown but kept out of the return; then the Schedule 3 lines, with the superficial losses denied (one of them for good, because the RRSP bought the stock back) and a ! line for anything the totals leave out. Run tjs init --demo ~/taxjson-demo, cd ~/taxjson-demo/2024, tjs run and tjs sum to see it yourself.

tjs sum  ·  tjs init --demo, tax year 2024  ·  synthetic figures
REALIZED-GAINS SUMMARY — CAD, tax year 2024, basis: wash-adjusted
REALIZED = NON-OPT (shares, units, futures, crypto) + OPTION; TOTAL = REALIZED + DIVIDEND + PIL.
DIVIDEND of crypto is staking rewards: ordinary income, not dividends.

TAXABLE ACCOUNTS
ACCOUNT      NON-OPT    OPTION   REALIZED  DIVIDEND   PIL    FEES      TOTAL
----------------------------------------------------------------------------
crypto      5,439.28      0.00   5,439.28     23.85  0.00  150.09   5,463.13
ib          3,032.88      0.00   3,032.88    102.22  0.00    6.90   3,135.10
margin         64.67    206.36     271.03    681.75  0.00    8.28     952.78
questrade   2,718.25      0.00   2,718.25     24.69  0.00   31.99   2,742.94
webull      2,257.37  1,365.14   3,622.51      0.00  0.00   39.58   3,622.51
----------------------------------------------------------------------------
SUBTOTAL   13,512.45  1,571.50  15,083.95    832.51  0.00  236.84  15,916.46

SHELTERED ACCOUNTS — not taxable
ACCOUNT    NON-OPT   OPTION  REALIZED  DIVIDEND   PIL   FEES     TOTAL
----------------------------------------------------------------------
lira        235.15     0.00    235.15    420.00  0.00  19.80    655.15
rrsp        471.51  -275.27    196.24    132.93  0.00   7.65    329.17
tfsa      3,143.45     0.00  3,143.45    528.00  0.00  39.80  3,671.45
----------------------------------------------------------------------
SUBTOTAL  3,850.11  -275.27  3,574.84  1,080.93  0.00  67.25  4,655.77

ALL ACCOUNTS — sheltered included
ACCOUNT      NON-OPT    OPTION   REALIZED  DIVIDEND   PIL    FEES      TOTAL
----------------------------------------------------------------------------
crypto      5,439.28      0.00   5,439.28     23.85  0.00  150.09   5,463.13
ib          3,032.88      0.00   3,032.88    102.22  0.00    6.90   3,135.10
lira          235.15      0.00     235.15    420.00  0.00   19.80     655.15
margin         64.67    206.36     271.03    681.75  0.00    8.28     952.78
questrade   2,718.25      0.00   2,718.25     24.69  0.00   31.99   2,742.94
rrsp          471.51   -275.27     196.24    132.93  0.00    7.65     329.17
tfsa        3,143.45      0.00   3,143.45    528.00  0.00   39.80   3,671.45
webull      2,257.37  1,365.14   3,622.51      0.00  0.00   39.58   3,622.51
----------------------------------------------------------------------------
TOTAL      17,362.56  1,296.23  18,658.79  1,913.44  0.00  304.09  20,572.23

FOR THE RETURN — taxable accounts (crypto, ib, margin, questrade, webull), CAD (Schedule 3, tax year
2024)
GAIN = PROCEEDS − COST(ACB) − OUTLAYS, the allowed gain; superficial losses denied: 467.49.
SCHEDULE 3 LINE                                          PROCEEDS   COST(ACB)  OUTLAYS       GAIN
-------------------------------------------------------------------------------------------------
shares & fund units (P1) (10689/10690)                  71,112.60   63,568.08    14.89   7,529.63
shares & fund units (P2) (13199/13200)                  21,986.83   21,432.29    11.00     543.54
options, crypto & other properties (P2) (15199/15300)   22,775.26   15,675.27    89.20   7,010.79
-------------------------------------------------------------------------------------------------
RETURN                                                 115,874.69  100,675.64   115.09  15,083.96

! 1 sale with no purchase NOT in these totals (SAMPG.US) — tjs find-missing-history
! FX on foreign cash (line 15300): not in the rows; its estimate is NOT RELIABLE — tjs fx-cash
Not in the rows: T3/T5 slip capital gains (lines 17600, 17400). More: tjs sum --details
REALIZED-GAINS SUMMARY — CAD, tax year 2024, basis: wash-adjusted
REALIZED = NON-OPT (shares, units, futures, crypto) +
OPTION; TOTAL = REALIZED + DIVIDEND + PIL.
DIVIDEND of crypto is staking rewards: ordinary income, not
dividends.

TAXABLE ACCOUNTS
crypto
  non-opt 5,439.28   option 0.00   realized 5,439.28
  dividend 23.85   pil 0.00   fees 150.09   total 5,463.13

ib
  non-opt 3,032.88   option 0.00   realized 3,032.88
  dividend 102.22   pil 0.00   fees 6.90   total 3,135.10

margin
  non-opt 64.67   option 206.36   realized 271.03
  dividend 681.75   pil 0.00   fees 8.28   total 952.78

questrade
  non-opt 2,718.25   option 0.00   realized 2,718.25
  dividend 24.69   pil 0.00   fees 31.99   total 2,742.94

webull
  non-opt 2,257.37   option 1,365.14   realized 3,622.51
  dividend 0.00   pil 0.00   fees 39.58   total 3,622.51

SUBTOTAL
  non-opt 13,512.45   option 1,571.50   realized 15,083.95
  dividend 832.51   pil 0.00   fees 236.84   total 15,916.46

SHELTERED ACCOUNTS — not taxable
ACCOUNT    NON-OPT   OPTION  REALIZED  DIVIDEND     TOTAL
---------------------------------------------------------
lira        235.15     0.00    235.15    420.00    655.15
rrsp        471.51  -275.27    196.24    132.93    329.17
tfsa      3,143.45     0.00  3,143.45    528.00  3,671.45
---------------------------------------------------------
SUBTOTAL  3,850.11  -275.27  3,574.84  1,080.93  4,655.77

ALL ACCOUNTS — sheltered included
crypto
  non-opt 5,439.28   option 0.00   realized 5,439.28
  dividend 23.85   pil 0.00   fees 150.09   total 5,463.13

ib
  non-opt 3,032.88   option 0.00   realized 3,032.88
  dividend 102.22   pil 0.00   fees 6.90   total 3,135.10

lira
  non-opt 235.15   option 0.00   realized 235.15
  dividend 420.00   pil 0.00   fees 19.80   total 655.15

margin
  non-opt 64.67   option 206.36   realized 271.03
  dividend 681.75   pil 0.00   fees 8.28   total 952.78

questrade
  non-opt 2,718.25   option 0.00   realized 2,718.25
  dividend 24.69   pil 0.00   fees 31.99   total 2,742.94

rrsp
  non-opt 471.51   option -275.27   realized 196.24
  dividend 132.93   pil 0.00   fees 7.65   total 329.17

tfsa
  non-opt 3,143.45   option 0.00   realized 3,143.45
  dividend 528.00   pil 0.00   fees 39.80   total 3,671.45

webull
  non-opt 2,257.37   option 1,365.14   realized 3,622.51
  dividend 0.00   pil 0.00   fees 39.58   total 3,622.51

TOTAL
  non-opt 17,362.56   option 1,296.23   realized 18,658.79
  dividend 1,913.44   pil 0.00   fees 304.09
  total 20,572.23

FOR THE RETURN — taxable accounts (crypto, ib, margin,
questrade, webull), CAD (Schedule 3, tax year 2024)
GAIN = PROCEEDS − COST(ACB) − OUTLAYS, the allowed gain;
superficial losses denied: 467.49.
shares & fund units (P1) (10689/10690)
  proceeds 71,112.60   cost(acb) 63,568.08   outlays 14.89
  gain 7,529.63   denied 0.00

shares & fund units (P2) (13199/13200)
  proceeds 21,986.83   cost(acb) 21,432.29   outlays 11.00
  gain 543.54   denied 467.49

options, crypto & other properties (P2) (15199/15300)
  proceeds 22,775.26   cost(acb) 15,675.27   outlays 89.20
  gain 7,010.79   denied 0.00

RETURN
  proceeds 115,874.69   cost(acb) 100,675.64
  outlays 115.09   gain 15,083.96   denied 467.49

! 1 sale with no purchase NOT in these totals (SAMPG.US) — tjs find-missing-history
! FX on foreign cash (line 15300): not in the rows; its estimate is NOT RELIABLE — tjs fx-cash
Not in the rows: T3/T5 slip capital gains (lines 17600, 17400). More: tjs sum --details

On a narrow terminal tjs sum stacks each account's figures, as above on a phone; tjs sum <account> shows one account, tjs sum --details what the short view leaves out.

How it works

Three steps, all on disk

Export

Download the activity CSV from each broker — Interactive Brokers, Questrade, RBC Direct Investing, Webull, Kraken, Coinbase — and drop every year's files into inputs/<account>/, one folder shared by all your tax years; or let tjs fetch download Questrade and IBKR for you (the taxjson-fetch plugin, installed by default; --without-fetch leaves it out). Registered accounts are declared as sheltered in taxjson.toml.

Run

tjs run parses every file, converts at the Bank of Canada rate for each settlement date (Valet API), pools identical securities, applies renames, splits and corporate actions on their dates, then runs the superficial-loss pass across taxable and registered accounts.

Read

Per-account summaries, Schedule 3 or Form 8949 rows, the wash radar ("safe to sell at a loss?"), harvest candidates, T1135, a tax and minimum-tax estimate land in reports/ and behind the commands. Every number traces back to the rows that produced it.

tjs init makes one folder for your taxes: inputs/ with every year's exports, and a folder per tax year (2025/, 2026/, …; tjs new-year starts the next one from this one). Each year's folder holds the two files you edit: taxjson.toml (the tax year, country, province, accounts and the figures you enter by hand — prior-year carryovers, fund distributions) and ticker.map (symbol mappings), plus that year's broker positions snapshots in holdings/ and the results. In Canada, tobase.map beside the year folders holds the TSX / US interlisted pairs that ship with taxjson, one file every year reads (tjs update-tobase-map brings it up to date). What a broker didn't export — an old purchase, a transfer in, a rename on its date — goes in plain-text .tt files in the account's folder. tjs years shows every year at a glance.

Rules with receipts

Every rule cites its source

Tax software usually asks you to trust it. taxjson ships REFERENCES.md: each computation names the section of the Act and the CRA or IRS document it follows — and each thing it deliberately does not do names the provision it skips.

Superficial loss, across accounts

s.54 / s.40(2)(g) / s.53(1)(f), sized with CRA's formula for each sale: the least of the units sold, the units bought in the 61-day window and the units held at day 30. The RRSP and TFSA are affiliated persons (s.251.1); a loss denied because the plan repurchased is reported as permanently denied, not quietly deferred.

Identical properties

s.47 average cost, IT-387R2: a US listing and its TSX listing are the same pool; a CDR is not. Trades count on the settlement date, as T4037 says.

Renames are events

A ticker change happens on a date: the pool, its cost and the acquisition dates move to the new symbol then. A later trade in the old ticker is never silently pooled — tjs renames lists it, and the rename's .tt line (RENAME <date> OLD NEW late=…) says whether it is the same shares or another company.

Options and warrants

s.49(1)–(4), IT-479R: a written option's premium is a gain in the year written, a buy-back a loss in its own year, an assignment folds the premium into the shares, and an exercised warrant's cost goes into the shares (s.49(3)). tjs option-boundary says whether a filed year needs a T1-ADJ.

Income in the right year

A dividend belongs to the year it is paid (s.82(1)); a Canadian trust's distribution to the year it became payable (s.104(13)), dated by its record date. Payments in lieu, return of capital and reinvested distributions each have their own rule.

Corporate actions

Splits, spin-offs (s.86.1), mergers with the s.85.1 rollover election, return of capital — with the election recorded and the filing reminder printed at every run.

Minimum tax and carry-forwards

tjs amt shows the 2024+ AMT line by line with its 7-year carryover (s.120.2); close-year records the year's carry-forwards and next year's estimate, carryover and handoff start from them.

US (experimental)

IRC §1091 wash sales across your accounts, Rev. Rul. 2008-5 for IRA repurchases, lots carried between your own accounts, §355 spin-offs and §356 boot per lot (Reg. 1.358-2, 1.356-1(b)), Form 8949 codes.

Crypto

Property, per the CRA guide: every swap, spend and gift is a disposition at fair value; a network fee paid in the coin is one too; identical-property pooling and the superficial-loss rule apply per coin.

tjs tax-logic prints every rule taxjson applies for your project's country, one line each, with your settings filled in. It is the spec: each rule has an id the tests cite, the build fails on a rule with no test, and Canadian and US rules never mix — a project has one country, and the other country's settings and commands are refused.

Verification

Checked against the one thing that can't lie: your broker's positions

Internal reports can all agree and still be wrong. taxjson sanity compares the positions the books say you hold against the positions your broker says you hold, account by account. Any difference is either a trade that hasn't reached the CSV yet or a booking problem — there is no third kind. Save a positions snapshot per broker account in the year's holdings/ folder (tjs fetch --positions writes one): each is matched to its account by the account number inside it or its file name, with no setting, and every taxjson run then finishes with the same check.

8,500+ tests

Every fix lands with a regression test that failed before it, tagged with the tax-logic rule it pins. No mocks for tax math.

Two full audits

After eight review rounds and a pre-release security audit, two full-coverage audits of the whole codebase: about 1,300 findings, then 1,600 in the re-audit that also checked the first round's fixes. Every confirmed finding reproduced, fixed and pinned.

Fuzzers and mutation testing

Three property fuzzers (gains conserved under the superficial-loss rule, transfer netting, split-during-settlement books) run thousands of random ledgers per run; mutation testing of both engines finds the boundaries no test pins.

Every figure traced

tjs audit recomputes each disposition from its broker row through FX, the cost pool and the loss rule, and ties it to the reports; check-filed recomputes every year you locked and reports drift.

Dates checked

tjs check-dates holds every trade and settlement date to its market's calendar; edge-cases lists what lands on a year end or a 30-day boundary, and why.

Published limits

KNOWN_ISSUES.md lists what is out of scope and what to do by hand, with the citation.

Commands

One pipeline, a few dozen views on it

Set up

checklist lists every step from install to filing and, in a project, checks each and names the next; init makes the exports folder and the year's project (--demo: a made-up one to try), years and new-year handle the year folders, align, format, format-map and migrate keep the files tidy and current, fetch downloads Questrade and IBKR activity (plugin), elect records corporate-action elections, ticker-map adds the lines a run suggested, update-tobase-map updates the interlisted pairs (Canada).

Build the books

run parses, converts, pools, applies corporate actions and the wash pass, and ends with the broker cross-check; crypto-sends, find-missing-history and opening settle what the exports leave open.

Summaries

sum for the year by form line, estimate and amt for the tax and minimum tax, instalments, stats for wins and losses on closed trades, fx-cash for currency gains on foreign cash, div-estimate for the dividends your holdings should pay next, from their own history.

Positions

list per account (or as of a date), shares combined across accounts.

Row listings

events, trades, divs, dil, roc, gains, fees, leaps and transfers: the rows behind the numbers, over any window.

Totals by type

winners and losers ranked, and per-ticker totals: divs-sum, dil-sum, roc-sum, trades-sum, fees-sum, ccd-sum, leaps-sum.

Before you trade

wash-radar, buy-check and sell-check answer "is this safe from the superficial-loss rule today?"; rebuy lists what you sold at a loss and the first day you can buy each back; harvest shows unrealized gains and losses at current prices; tips gives tax-efficiency advice for next year; watch reports changes from cron.

Before you file

form-export for Schedule 3 / Form 8949 rows, t1135, reconcile-slips against the T5008 / 1099-B, slip-audit for T5 / T3 slips, carryover, option-boundary, close-year to lock what you filed, check-filed for drift, and handoff to start the next year from it.

Explain and check

audit traces every gain to its broker row, wash-sales lists each denied loss and why, tax-logic states every rule, edge-cases and check-dates look at the boundaries, sanity compares with your broker, journals, renames, spinoffs and splits show each event.

Tools

redact strips personal details from an export so you can share it; help shows the grouped list (--all: both countries' commands).

tjs with no command lists every command under these headings, one line each — inside a project only your country's (tjs help --all shows both). Every command takes -h; most take --json, and --details brings back the explanations the default view leaves out. Each command in full: docs/commands.md; a short overview is in the deck.

Brokers

Reads the exports you already have

Interactive Brokers (Flex / activity)QuestradeRBC Direct InvestingWebullKrakenCoinbaseAny other broker's CSV, with a column mappingPlain-text .tt for anything else

Questrade and IBKR Flex activity can be downloaded directly with tjs fetch through the taxjson-fetch plugin, a separate package the installer installs by default (--without-fetch leaves it out). The core itself holds no broker client and reads no credential; a fetcher for another broker is a plugin of its own. Every parser accounts for every row it reads: rows it recognises but doesn't translate are counted and named, never silently dropped. Where each broker's download is, and its quirks: docs/brokers.md.

Install

Your first books in ten minutes

bash -c "$(curl -fsSL https://taxjson.com/install.sh)"

Installs the stable release into ~/.local/share/taxjson with its own Python environment and links taxjson and its short name tjs into ~/.local/bin. Re-run to upgrade. Needs git and Python 3.9+; nothing else. Add _ --channel beta (or latest, dev for the development branch, or a version like v0.30.1) to pick another channel; the installer remembers it, so re-running upgrades along the same channel.

The Questrade / IBKR auto-fetch plugin comes with it; it contacts a broker only when you run tjs fetch for a configured account. To leave it out (remembered on upgrade; _ --with-fetch puts it back):

bash -c "$(curl -fsSL https://taxjson.com/install.sh)" _ --without-fetch

To try it first, a project of made-up exports (six accounts, tax year 2024) with the commands to run:

tjs init --demo ~/taxjson-demo

Your own books:

mkdir -p ~/taxes && cd ~/taxes
tjs init --country canada   # or usa; inputs/ for every year, 2026/ for this one
cd 2026                     # each year's folder: its taxjson.toml, ticker.map, results
tjs checklist               # every step: what is done, what is next
# drop broker CSVs, all years together, into ../inputs/margin/, ../inputs/rrsp/, …
tjs run                     # books, reports, wash pass, broker check
tjs sum                     # the year, by Schedule 3 line
tjs wash-radar              # "can I sell this at a loss today?"
tjs rebuy                   # when can I buy back what I sold at a loss?
tjs checklist               # again at year end: ready to file?

Prefer a clone? git clone https://github.com/taxjson/taxjson && cd taxjson && scripts/dev-setup.sh. Coming from an older version? docs/upgrading.md lists what each release asks of you. A step-by-step first project is in docs/getting-started.md.

Privacy and security

Nothing personal leaves the machine

Local by construction

Parsing, pooling and the wash pass run on your computer — no account, no server, no web UI; just commands and files. A run goes online only for what its cache lacks: exchange rates from the Bank of Canada (Yahoo Finance before May 2007, for currencies the Bank does not publish, and for a US-dollar base), and from Yahoo Finance a price for a crypto row the export left unpriced or a close for an in-kind move to or from a registered account. It sends a currency pair or a symbol and a date, nothing about you. TAXJSON_OFFLINE=1 forbids every lookup.

No credentials in the core

The core holds no broker client and reads no broker credential. Auto-fetch is the separate taxjson-fetch package, which the installer adds by default (--without-fetch leaves it out): it does nothing until you run tjs fetch, talks only to your broker, keeps its token outside your project, and sends it nowhere else. harvest and tips --online look up current prices, so Yahoo sees those symbols.

The project guards itself

A personal-data scan runs in every build and as the pre-push hook, fails closed, and reads a private denylist kept outside the repository. tjs redact strips the account numbers, names and contact details it recognises from an export while keeping every row shape — review the copy before you share it.

SECURITY.md lists every network call, what it sends and how to turn it off, and how to report a vulnerability. The core package needs nothing beyond Python's standard library (tomli before Python 3.11); the one-line installer also adds the fx extra (yfinance and pandas, for the Yahoo Finance rates and prices) and the taxjson-fetch plugin, which uses only the standard library.

Frequently asked

Before you file

taxjson is a calculator, not tax advice. It applies published rules to the rows you give it and shows its work; the return is yours, and a professional should review anything unusual — elections, cross-border reorganisations, business-income questions.
Does it send my data anywhere?

No. Parsing, pooling and the wash pass all run locally. A run looks up only what its cache lacks: FX rates from the Bank of Canada (Yahoo Finance before May 2007, for currencies the Bank does not publish, and for a US-dollar base), and from Yahoo Finance the price of a crypto row the export didn't price or the close for an in-kind move to or from a registered account; TAXJSON_OFFLINE=1 disables every lookup. harvest and tips --online look up current prices, so Yahoo sees those ticker symbols; the optional fetch plugin talks only to your broker. SECURITY.md lists every egress.

Canada or US?

Canada is the supported product: average-cost ACB with the superficial-loss rule and settlement-date timing, validated against real multi-account books and the brokers' own positions. A US engine ships too — FIFO with §1091 wash sales across your accounts, lots carried between your own accounts, short/long-term classification and Form 8949 codes — but it is experimental: unit-tested, never validated on a real account. Use it as a draft; if it gets something wrong on your US books, open an issue with a made-up file that shows it (see "How do I get help?"). A project is one country; the two rule sets never mix.

How do I know I'm ready to file?

tjs checklist. It is the filing checklist as a command: each step is proved by running the command behind it — a clean run, the broker cross-check, no missing cost basis, every disposition audited, the T5008 reconciled, no year-end option needing an amendment — and the steps only you can confirm are marked with --done. --walk takes you through the open ones.

What about the tax years I already filed?

tjs close-year locks the numbers you filed; check-filed and every later run flag any drift so an engine fix or a late row shows up as a candidate for an adjustment rather than a silent change. The lock also records what next year needs — the positions and cost at Dec 31, the trades that settle in January, the net capital loss and minimum-tax carry-forwards — and next year's tjs handoff checks the new project starts from exactly that.

My broker isn't listed.

Parsers are small, self-contained modules with a row-accounting contract; a new one is an afternoon's work given the export's layout. Open an issue with its header line and a few made-up rows in the same shape (never a raw export; see "How do I get help?"). Meanwhile the generic importer reads any CSV through a column mapping you write, and the plain-text .tt format covers the rest (docs/brokers.md).

How is it verified?

An 8,500+-test suite that every change must pass, each tax test tagged with the rule it pins; three property fuzzers and mutation testing; eight review rounds and two full-coverage audits (about 1,300 and 1,600 findings) logged in the changelog; and — the one that matters — tjs sanity against your broker's own position export. Every computation names its ITA / CRA / IRC source in REFERENCES.md, and tjs tax-logic states each rule as the code applies it.

I used an older version of taxjson.

Upgrade by re-running the installer, then read docs/upgrading.md: it lists, release by release, every change that asks something of you. Most come down to tjs migrate (--dry-run first): since v0.27.0 it turns a missing_history.json into .tt lines, and since v0.27.1 it makes the per-year copies of tobase.map one shared file beside the year folders. A command that needs it stops and names the file until you do. The same page lists the problems an upgrade alone fixes.

How do I get help?

First tjs checklist in your project: it names the next step and its command. For a message you don't understand, search docs/troubleshooting.md for its text (on an older release, also the fixes by release). For a bug, open an issue with the bug-report template. Never attach a raw export: reproduce the problem on a made-up file first (copy your broker's demo CSV from examples/ and edit its rows). Only if that is not possible, tjs redact a copy — it strips account numbers, names and addresses but keeps amounts and dates — read all of it, and share it only after that review.