A single-file TypeScript tool that calculates your Canadian crypto taxes from Coinbase and Kraken account statements, following CRA rules.
- Parses your Coinbase CSV exports and Kraken transaction data
- Fetches daily USD/CAD and EUR/CAD exchange rates from the Bank of Canada API
- Calculates the Adjusted Cost Base (ACB) using the CRA-mandated average cost method
- Identifies all taxable disposal events (sells, trades, conversions) for your tax year
- Outputs a full console report and four CSV files ready for your tax preparer
- Cryptocurrency is treated as a commodity, not currency
- The Average Cost Base method is used (required by CRA)
- 50% capital gains inclusion rate on net gains
- Crypto-to-crypto trades (e.g. USDC → UNI) are treated as taxable disposals
- Staking/reward income is reported separately at fair market value
- T1135 foreign asset threshold check ($100,000 CAD)
experiments/
├── crypto-tax.ts ← the calculator (single file)
├── package.json
├── tsconfig.json
├── statements/
│ ├── coinbase/
│ │ └── *.csv ← Coinbase "Raw Transaction History" exports
│ └── kraken/
│ └── *.csv ← Kraken data (see formats below)
└── output/ ← generated CSV reports (created on run)
├── schedule3_disposals_YYYY.csv ← every disposal for Schedule 3
├── staking_income_YYYY.csv ← staking/reward income
├── holdings_acb_YYYY.csv ← year-end holdings & ACB
└── tax_summary_YYYY.csv ← one-page summary
| File | Required? | Where to get it | What the tool does with it |
|---|---|---|---|
| Raw Transaction History (CSV) | YES | Desktop → Taxes → Documents → Generate Report | Parses all buys, sells, converts, rewards, sends, deposits |
| Transaction History (PDF) | No | Same place as CSV | Same data as the CSV - kept for your records only |
| Annual Performance Report (PDF) | No | Delivered by Coinbase annually | Portfolio return summary - no transaction data |
| Charges & Compensation Report (PDF) | No | Delivered by Coinbase annually | Fee summary - fees are already in each CSV row |
How to download:
- Log in on desktop (not mobile)
- Go to Taxes or Documents
- Click Generate Report → Raw Transaction History
- Set the date range to cover the full tax year (e.g. Dec 31 2024 → Jan 5 2026)
- Download the CSV file
- Drop it into
statements/coinbase/
| File | Required? | Where to get it |
|---|---|---|
| Trades CSV export | YES | History → Export → Trades |
| Ledgers CSV export | YES | History → Export → Ledgers |
- Trades filename must contain the word
trade(e.g.kraken_trades_2025.csv) - Ledgers filename must contain the word
ledger(e.g.kraken_ledgers_2025.csv) - Drop both into
statements/kraken/
If you used Instant Buy/Sell, the Trades export will say "Account had no activity." In this case, you need to extract your transactions from Kraken's monthly PDF account statements into a simple CSV.
| File | Required? | Where to get it |
|---|---|---|
| Monthly Account Statements (PDFs) | YES (as reference) | Account → Documents → Statements → download all 12 months |
| Hand-built CSV from those PDFs | YES | You create this (see format below) |
| Spot Trades PDF | No | History → Export → Trades (PDF) - will be empty for Instant trades |
| Stocks/ETFs Ledgers PDF | No | History → Export → Ledgers - has transaction IDs but no clean CSV format |
How to build the Kraken CSV from monthly statements:
- Download all 12 monthly PDF statements from Kraken
- Open each PDF and look at the Activity section
- Create a CSV with this format:
date,type,asset,quantity,price_cad,fee_cad
2025-07-23 19:13:05,buy,VIRTUAL,82.6234,2.3270,0
2025-08-12 22:53:05,sell,ETH,0.10253936,6321.5068,0
2025-09-07 16:46:11,income,TIA,0.010138,2.2761,0| Column | Description |
|---|---|
date |
UTC timestamp from the statement |
type |
buy, sell, or income (for staking/earn rewards) |
asset |
Crypto symbol (ETH, BTC, TIA, etc.) |
quantity |
Amount of crypto (positive number) |
price_cad |
CAD price per unit - taken directly from the "Price (CAD)" column in the PDF |
fee_cad |
Fee in CAD (usually 0 for Instant trades; Kraken embeds fees in the spread) |
- Lines starting with
#are treated as comments (useful to organize by month) - Skip "Auto Allocate Earn" rows (moving assets to/from staking pools - non-taxable)
- Skip "Deposit" and "Withdrawal" of CAD (non-taxable)
- For "Spend Instant" + "Receive Instant" pairs: record the Receive side as a
buyand skip the Spend side (it's just the CAD/USD you paid) - For staking rewards ("Reward Earn"): record as
incomewith the price from the statement - Drop the file into
statements/kraken/- the tool auto-detects this format from thedateheader
statements/
├── coinbase/
│ ├── coinbase_txn-2025.csv ← USED: 118 rows → 84 parsed transactions
│ ├── coinbase_txn-2025.pdf ← NOT USED (PDF of same data)
│ ├── coinbase_performance_2025.pdf ← NOT USED (portfolio summary)
│ └── coinbase_charges&compensation_reports_2025.pdf ← NOT USED (fee summary)
└── kraken/
├── kraken_instant_ledger_2025.csv ← USED: 42 transactions (built from PDFs below)
├── kraken_spot_trades_2024-12-31-2026-01-06.pdf ← NOT USED (empty - Instant trades)
├── kraken_stocks_etfs_ledgers_2024-12-31-2026-01-06.pdf ← NOT USED (reference only)
└── kraken_spot_account_statement_2025-*.pdf (×12) ← NOT USED directly (data extracted into CSV above)
Follow the "Required input files" section above to get your CSVs into the right folders.
npm run tax # defaults to 2025
npm run tax:2024 # prior year
npx tsx crypto-tax.ts 2025 # manualThe tool prints a full report to the console and saves four CSV files to output/:
| File | Purpose |
|---|---|
schedule3_disposals_YYYY.csv |
Line-by-line disposals with proceeds, ACB, fees, gain/loss - enter on Schedule 3 |
staking_income_YYYY.csv |
Staking/reward income at FMV - report as Other Income |
holdings_acb_YYYY.csv |
Year-end holdings and ACB per asset - carry forward to next year |
tax_summary_YYYY.csv |
One-page summary: Line 12700 amount, income total, T1135 check |
The tool uses the Average Cost Base method across all accounts combined (as required by CRA):
ACB per unit = Total cost of all units owned / Total quantity owned
On disposal:
Gain/Loss = Proceeds − (ACB per unit × quantity sold) − fees
All historical transactions are processed chronologically to build the running ACB, but only disposals within the selected tax year appear in the report.
| Situation | Form |
|---|---|
| Capital gains/losses | Schedule 3 → Line 12700 |
| Staking/reward income | Other Income on T1 |
| Foreign assets > $100k CAD (cost) | T1135 |
| Business income (day trading) | T2125 |
USD/CAD and EUR/CAD rates are fetched from the Bank of Canada Valet API for the tax year. Weekend/holiday dates fall back to the most recent trading day (up to 7 days).
Buy, Sell, Advanced Trade Buy/Sell, Convert (USDC → crypto), Reward Income, Send, Receive, Deposit
Trades (buy/sell via order book), Instant Buy/Sell, Staking Rewards (Earn), Ledger entries
- This tool is for personal investment (capital gains) tax reporting. If the CRA considers you a business trader, 100% of gains are taxable - consult a tax professional.
- Crypto-to-crypto trades on Coinbase via "Convert" are only tracked when the disposed asset is USDC. If you converted between two non-stablecoin assets, you may need to add those manually.
- The tool does not track transfers between your own wallets for ACB continuity. If you transferred crypto from Coinbase to Kraken (or vice versa), make sure both the send and receive appear in your data.
- Kraken Earn reward prices from the ledger export are set to $0 and flagged - use the monthly CAD statement format (Option B above) for accurate income reporting.
This tool is provided "as is", without warranty of any kind, express or implied. It is intended for informational and educational purposes only and does not constitute tax, financial, or legal advice.
- The author(s) are not accountants, tax professionals, or financial advisors.
- You are solely responsible for verifying the accuracy of all calculations and for filing your own tax returns.
- Tax laws change frequently. This tool reflects the author's understanding of CRA rules as of early 2026 and may not reflect the latest regulations.
- Always consult a qualified Canadian tax professional before relying on any output from this tool for filing purposes.
- The author(s) accept no liability for errors, omissions, or any losses arising from the use of this tool.
Use at your own risk.