Skip to content
These pages were written for PrivateACB 2.12.0 — from 2.15.0, the full up-to-date manual is built into the app: Help → PrivateACB Handbook.

Resolution Guide

This page is the same guide the app opens under Help → Resolution Guide, generated from the program itself.

PrivateACB is a privacy-first cryptocurrency tax calculator for Canada, the United States, Australia, and the United Kingdom. It runs entirely on your computer: your transactions live in one encrypted database file, calculations run locally, and nothing about your holdings is sent anywhere. The chapters that follow cover each part in depth — this one is the map.

Each jurisdiction gets its real rules, not a generic approximation. Canada: Adjusted Cost Base pooling with the superficial loss rule. The United States: lot-based cost basis under FIFO, LIFO, or HIFO, the wash sale rule, and Account-by-Account tracking from 2025. Australia: lot-based cost basis with the fifty-percent CGT discount for long-held assets. The United Kingdom: the Section 104 pool with same-day and thirty-day matching, and the Annual Exempt Amount shown on the reports. Income — staking, mining, airdrops, rewards — is taxed at its value on receipt, with automatic price lookups. The Jurisdictions chapter has the side-by-side.

CSV files. Seven exchanges are recognized automatically by their column headers — Coinbase, Kraken, Binance, NDAX, Newton, Shakepay, and Crypto.com — through ten built-in formats, plus a generic layout; a file that matches none of them is mapped automatically and shown for your confirmation. The import wizard scans every file’s transaction types before anything is committed, and lets you classify them. The Importing chapter walks the whole wizard, decision by decision.

Free, keyless sources: official exchange rates from the Bank of Canada and the Federal Reserve, and crypto prices from CoinGecko for recent dates with free deep-history sources for older ones. Manual entry and price CSVs cover anything no service carries. One honest note: fetching prices needs an internet connection — everything else, from importing to calculating to reports, works offline, and your data never leaves the machine either way.

Every asset gets a Preflight Report — seven checks covering the data, an independent balance recount, price coverage, your recorded decisions, transfer pairing, an engine dry run, and cross-year reach. The Review tab holds the deeper workbench: a full ledger with running balances, a provenance card for every row, and the fix channels — each one recorded as your decision, almost all of them reversible.

Twenty-two reports across the four jurisdictions: filing forms — Schedule 3 and the T1135, Form 8949 and Schedule D, the SA108, the ATO CGT summary — plus supporting detail and audit-provenance records that trace every number back to its source. Every report exports to PDF, and all but the audit reports also export their data as CSV. Viewing is free during the trial; exporting needs a license.

Import your files from the File menu; cover prices on the Market Data tab; run the ACB Calculator; verify on the Review tab; produce on the Reports tab. The tabs read left to right in that order, and the Getting started chapter takes it from the top.

Getting started — first launch and Settings

Section titled “Getting started — first launch and Settings”

When the app opens without a database it shows the Welcome screen, and everything starts from its two buttons: Create New Database and Open Existing Database. The buttons enable once the app finishes starting up — the status line beneath them says when it is ready — and the screen remembers the last database you used, offering its path again next time. Pressing Escape enters the program without a database; most of the app simply waits until one is open.

Creating a database means choosing a folder and a name — the dialog shows the full path it will create, one file ending in .db, defaulting to a PrivateACB folder under your Documents. The password is the part to take seriously: it must be at least eight characters, the file is encrypted with it, and the dialog’s warning is literal — the database is permanently inaccessible without it. There is no recovery: nothing about the file can reveal the password. The one copy the program keeps is encrypted by Windows for your user account on this machine — it is what lets the open dialog fill the password in for you, and it is useless on any other machine or account. Creating over an existing file asks for a second, separate confirmation before anything is overwritten.

The file is self-contained and portable: opening it on another machine needs only the file and your password. For a copy, use Export Database Copy in Settings — it produces one clean, optimized file — rather than copying the file while the app has it open.

The program never backs the database up on its own — copies are yours to make. The habits that pay: keep more than one copy, on more than one kind of storage, with one away from this machine; refresh them after large imports, after calculations, at year-end, before large deletions, and before upgrading the program; and open a backup once in a while to prove it works and the password is the one you think it is.

A raw file copy is fully functional and opens with the same password — close the program before copying, or use Export Database Copy while it is open. A backup in a cloud-synced folder is fine — the provider only ever holds encrypted bytes, never the password — but keep the working file out of actively syncing folders. And because there is no recovery, decide who could open the file if you couldn’t: the file’s location and its password, kept wherever your important papers live.

Six tabs: Dashboard, Market Data, ACB Calculator, Review, Reports, and Settings — and after importing, the workflow reads across them in order: cover prices in Market Data, run in ACB Calculator, verify in Review, produce in Reports. Importing itself lives in the File menu, as Import Transactions. Ctrl+1 through Ctrl+6 switch tabs from the keyboard, and the Data Viewer — a raw look at stored rows — sits in the View menu.

A thirty-day trial begins on first use, and the Dashboard shows a banner counting it down. During the trial everything is viewable; exporting reports is what needs a license. Activation lives in Settings under License and Activation: enter the key and press Activate. Once licensed, the panel shows the edition and what it covers; Deactivate License returns the app to trial mode and frees that machine’s activation — a license covers up to three machines.

The Settings tab holds six cards, all collapsed until opened. On day one: License and Activation matters when you have a key; Exchange Form Status matters only to United States filers; Currency API Configuration is optional, because the app runs without any key; Database Security is the password-change form, needed only when you want a new one; Export Database Copy is worth using once real data is in; Session Logging is fine as shipped. The sections below cover the ones with substance.

Exchange Form Status — United States only

Section titled “Exchange Form Status — United States only”

This panel records, per exchange and per tax year, whether that exchange issued you a Form 1099-DA and whether it reported your cost basis. The setting quietly drives how Form 8949 sorts your disposals into boxes: for 2024 and earlier everything uses boxes C and F, and from 2025 the boxes run in the G-to-L range and follow what you record here — basis reported, form received without basis, or no form at all. The default is all unchecked, which lands disposals in the no-form boxes, I and L — right for most people; your exchanges appear in the panel once their files are imported.

The app fetches prices and exchange rates without any key — the built-in sources are free and keyless, and free deep-history sources cover dates older than a year for the widely traded coins. Two optional keys exist. A paid CoinGecko key extends that service’s own history past 365 days; the free key does not change how far back it reaches, and the program tells the two apart by their shape — the free keys start with CG-. A Federal Reserve key enables their exchange-rate service, which United States users need for fetching foreign-currency rates automatically. Rates are cached for a day, so repeated fetches don’t re-ask the services.

Keys are held in Windows secure storage for your user account, not in the database file — a database moved to another machine needs its keys entered again there. Each configured key offers Test, which makes one real call and reports plainly whether it worked, and Delete.

Database Security changes your encryption password — the new one needs at least eight characters with letters and numbers, can’t repeat the current one, and a strength meter grades it as you type. The change re-keys the file in place: let it finish rather than closing the program mid-change, and if it fails, the old password still works. Export Database Copy shows the open file’s path and size, then opens a save dialog with a timestamped name and writes one optimized copy — typically smaller than the original — wherever you choose; the optimized copy is a full database, and can replace the original if you want the smaller file. Session Logging explains its own three destinations honestly: the activity banner at the bottom of the app is always on, the events table inside your database file is always on while a database is open, and the CSV session files on disk are what the toggle controls — they land in the logs folder under PrivateACB in Documents, the panel’s Open Logs Folder button takes you there, and a size cap rotates the file — with automatic deletion after thirty days by default. Export Events writes the events table itself out as a CSV. One caution: Copy System Info puts your database path on the clipboard — worth a glance before pasting it into a bug report.

The File menu holds New, Open, and Close Database, Import Transactions, Export Database Copy, and Change Encryption Key — the data items stay greyed out until a database is open, which is the usual first-day surprise. The keyboard covers all of it: Ctrl+N, Ctrl+O, and Ctrl+W for new, open, and close, Ctrl+I to import, Ctrl+E to export a copy, and Ctrl+Comma for Settings. Only one database is open at a time — closing returns to the Welcome screen without quitting, and the encryption key leaves memory when it does. The View menu switches tabs, zooms, and opens the Data Viewer. The Help menu starts with the Resolution Guide — an in-app window, not a website — followed by guides that open in your browser, and Check for Updates, which makes no network call: it tells you plainly that the app does not contact a server about your version, and points at the changelog page instead.

The complete list. Price and exchange-rate lookups send asset symbols and date ranges to the free data services — never your transactions, amounts, or files. Clicking Activate sends the license service your key, a machine identifier, your computer’s name, and the app version; nothing is sent until you click. Help links open pages in your browser. That is all: your database and everything in it stays on your machine, there is no telemetry, no auto-update, and no background calls, and the trial record lives in your operating system’s secure storage locally.

Importing is in the File menu — Import Transactions — and it stays greyed out until a database is open; the Dashboard’s Import Transactions buttons open the same wizard. The wizard runs in five steps: select the file, review and configure how it will be read, review the transaction classifications, preview and validate, and the import itself. The third step lists every transaction type the file uses — recognized ones arrive already classified, unrecognized ones are flagged for your decision. It is skipped only when the program cannot read types from the file at all. Cancelling at any point before the final step imports nothing and forgets everything.

Click the card to browse for one CSV file — a spreadsheet saved as .xlsx is refused with a failed-to-profile error, so save it as CSV first, and there is no hard size limit; very large files simply take longer. The program reads the file immediately and reports what it found: the row and column counts, the file’s shape, and — when the headers match one of the built-in exchange profiles — the profile name with a confidence figure. The built-in profiles are NDAX Trades, NDAX Staking, Coinbase, Newton, Shakepay, Kraken Trades, Kraken Ledger, Crypto.com App, Binance Transaction History, and a Generic Standard layout. A file that matches none of them is not rejected: the program maps its columns automatically and shows the detected shape with its confidence, and step two is where you confirm or correct that reading.

Kraken gets special handling. A Kraken Ledger file can optionally be enriched by attaching the matching Kraken Trades file — the Trades export carries exact execution prices and fees — and the program merges the two into a new file, saved in your Downloads folder, and continues with that. Skipping the merge costs only precision: it refines prices and fees, and never adds or removes transactions. A Kraken Trades file on its own is blocked, with the reason stated: it lacks deposits, withdrawals, and other tax-relevant events, so importing it alone would silently understate your history.

The step opens with one sentence summarizing the whole file — how many transactions, which assets, what date range, which types — followed by the column mappings and sample rows. When the program’s confidence is high the mapping table is folded away behind a link; when it is not, the table is open, and each mapping states how it was decided. You can re-point any column or set it to Skip. Columns the program did not map are skipped on their own — usually exchange metadata — and being unmapped is not an error. One consequence is worth knowing: changing a mapping tells the program your reading of the file outranks its recognition, so the built-in profile steps aside — your mappings are used exactly, and profile-specific knowledge, such as that exchange’s fee convention, no longer applies. Change mappings when the file needs it; leave them alone when the detection is right.

Below the mappings sit the import settings. The exchange name labels every row and offers names you have used before. The timezone control appears only when the file’s timestamps carry no timezone of their own: pick the zone the exchange wrote them in, and the program converts to universal time — files that state their own timezone need nothing and say so. When unsure, universal time is the safe pick; most exchanges write their exports in it. The pricing currency dropdown appears only when the file has no currency column at all: it declares what currency the file’s prices and totals are in. A tax preparer name, if entered, appears on generated reports.

One normalization happens quietly as the file is read: the major dollar-pegged stablecoins — USDT, USDC, BUSD, DAI, TUSD, and FDUSD — are recorded as United States dollars, on traded assets and on fees alike, matching how exchanges account for them; the row’s audit trail keeps the original symbol. The list is fixed and deliberate: a coin that has lost its peg is not on it.

Two checkboxes ask whether buy fees are charged in the crypto being bought, and sell fees in the crypto being sold. They are hints, not commands: the program determines each row’s fee currency from the file itself wherever the file answers — an explicit fee-currency column, the row’s own asset, the file’s internal ratios, or the exchange profile’s known convention — and your hint is consulted only when all of that is silent. When a higher source answers, the overridden hint is noted in the row’s audit trail rather than silently dropped.

When the hint does decide, the fee is recorded in the traded crypto, and the quantities follow the standard convention — a buy’s received amount is net of the fee, a sell’s disposed amount includes it. A hint that would make a fee as large as the purchase itself fails loudly, naming the row and pointing at the fee column mapping, because that shape almost always means the mapping is wrong rather than the fee.

When everything is silent — file, profile, and hint alike — the fee currency stays undetermined: the fee is still counted, valued one-to-one in your reporting currency, and the Prices check names the rows so the choice is visible rather than buried. When unsure, leave both boxes unchecked; the file usually answers.

The program shows every transaction type it found, unrecognized types first, with the class it proposes for each: Exchange for capital-gains trades, Income for rewards taxed at value on receipt — a value that then becomes those units’ own cost going forward — Transfer for movements with no tax impact, DeFi, or Ignored for rows excluded from everything. Changing a class is your decision, applied to the rows as they are read — your file is never touched. Ticking Remember stores the choice for future imports, where it shows up pre-applied and marked as yours; a remembered pattern can only be changed by re-classifying on a later import.

Each type appears once, with a count of the rows that carry it and a status: recognized, unrecognized, or saved — a choice you recorded on an earlier import. Filter buttons and a search box narrow the list, which matters when a file carries dozens of types. For unrecognized types the Remember box arrives already ticked — proceeding without touching anything still records those patterns — and patterns are kept per database, not shared across databases.

Two defaults deserve a look. A type the program has never seen is treated as Exchange — the conservative reading, but wrong for rewards, for movements between your own accounts, and for spam you never asked for, which is what Ignored is for: excluded from calculations and reports. Give sibling types the same reading — a referral bonus and a reward deserve the same class. And a decision here is by type, not by row: changing a type flips every row that carries it, so a file that mixes, say, genuine airdrops with your own deposits under one type needs the finer tools — import, then record own-coins or dust decisions on the specific rows from the Review tab.

One decision here is a one-way door, and the wizard does not flag it: income. A row classified as income at import is the only way income can ever be recorded — nothing after import can turn a deposit into income. If forks, airdrops, or rewards are in this file, classify them now; the alternative later is deleting this import and importing again. The step’s review notice is advisory — unrecognized types don’t block the import, they just deserve a look before you proceed.

Every row is validated and shown with its status: ready, warning, duplicate, or error. Each row also carries a checkbox — unchecked rows are simply not imported — with a select-all toggle above the list. Warnings never block — rows with warnings import, and clicking a row shows each issue with a suggested fix where one exists. Duplicates never block either: rows already in your database, or repeated within the file, are counted and skipped rather than imported twice. Errors are the hard stop — a single error row disables the import until it is resolved, usually by fixing a column mapping on step two, and an error report file is offered for the details. When the program’s reading of the file scores poorly against its own coherence checks, a data-quality notice appears with a button straight back to the mapping table.

Step five — the import, and what comes after

Section titled “Step five — the import, and what comes after”

The import runs with a progress bar and cannot be cancelled mid-flight; the summary that follows counts what was imported, what was skipped, and splits the skipped duplicates into already-in-database and repeated-within-file. The wizard then checks for price gaps in what just arrived and, when it finds them, names the assets and offers Go to Market Data. The next-step buttons lead to Review, to the ACB Calculator, or back to import another file. When several exchanges are involved, import them all before calculating — transfers between exchanges only pair up when both sides are present.

What can be corrected without re-importing: the four value amendments (quantity, price, and the two fee amounts, from the record card, each with a required reason and reversible), the own-coins and dust classification decisions, transfer-pair confirmations, and asset exclusion. Everything else set in the wizard — classifications, column mappings, timezone, pricing currency, the fee hints, the exchange name — is baked into the imported rows, and the remedy is the loop the Resolution Guide names: delete the import, and import the file again with the right settings.

Deleting an import lives in the Data Viewer, under the View menu: Delete Import Job lists each import with its file name and record count, and the confirmation states exactly what will be removed before anything is. Re-importing the same file afterwards is safe by design — unchanged rows that somehow remain would be recognized as duplicates and skipped. One subtlety: duplicate recognition considers a row’s classification, so importing the same file again with different step-three choices creates new rows rather than being skipped — which is exactly why delete-first is the documented loop.

Some rows carry their own price in your files — a trade usually says what it cost. Others don’t: income, rewards, and many deposits arrive as a quantity with no value attached, and valuation needs a price for every row that has tax impact. The Market Data tab (its page header reads Rates and Prices) is where that coverage is built, in two sections: exchange rates, for transactions in a currency other than your reporting currency, and cryptocurrency prices.

Everything on this tab is counted in days: one price or rate per calendar day covers every transaction on that date. So the tables speak of transaction days that need coverage, days already cached, and days still missing — not of individual rows.

Fetching happens when you ask, and only for dates your transactions actually touch — fetching ahead of need buys nothing. The rhythm that works: import, then come here, then calculate. The two sections are also independent of each other — an asset can have every exchange rate it needs and still be missing a crypto price for one staking day.

Each table lists assets with the same six columns: the asset, its status, the transaction days that need coverage, the days already cached, the days still missing with their date range, and an actions menu. Complete means zero remaining gap days — every date that needs a value has one stored in your reporting currency. Partial means some coverage exists and gaps remain. Needs Prices, or Rates Missing on the exchange-rate side, means nothing covers the gaps yet. A manual-only tag appears on assets no automatic source carries — for those, the CSV and manual routes below are the way. Completed assets stay in the list rather than vanishing, so finished work stays visible.

The exchange-rate table follows the jurisdiction: switching it changes which conversions are needed, so an asset can appear under one jurisdiction and not another. And an import history at the foot of the tab lists the last ten rate and price imports across all sources — the place to confirm a fetch actually landed.

The fetching stack is free and keyless. Recent dates — up to 365 days back — come from CoinGecko; older dates come from a free deep-history source for the widely traded coins, with an exchange-market fallback for the rest. Deep history arrives valued in US dollars, and the exchange rates needed to state it in your reporting currency are fetched automatically as part of the same run. The fallback source declines requests from some regions, including the United States; dates it can’t serve simply remain unfetched and are named, never silently skipped.

Fetch All Missing, at the top of the prices section, walks every asset that has gaps and an automatic source — one asset at a time, so a large backlog takes minutes by design. Per asset, the row’s Import menu offers Fetch Prices, which opens a panel pre-filled with the gap’s date range; after the fetch it shows what each source returned, how many prices were stored, and which dates no free source could serve — those need a price CSV or manual entry, and the panel says so rather than leaving a silent hole. When a fetch cross-rates deep history, the extra exchange-rate fetch is named in the activity line, not silent.

Two boundaries are worth knowing. The rates behind deep history reach back to the start of 2017 — older dates in a Canadian, Australian, or United Kingdom report have no keyless conversion rate, and are flagged for a rate CSV or manual entry. And which route serves a coin depends on the sources themselves: coins the deep source lists are covered; coins off that list can still be served by the exchange-market fallback when it trades a matching pair; an asset none of them carry wears the manual-only tag. A coin the recent-dates source doesn’t know at all is routed to the deep sources whatever the date — recent or old.

A transaction in a foreign currency needs a rate to your reporting currency for its day. For Canada the Bank of Canada supplies these with no key; for the United States the Federal Reserve supplies them once its free key is set in Settings; for Australia and the United Kingdom the automatic route for your own foreign-currency rows is a CSV upload or manual entry — the rates behind deep price history are still handled automatically. The Import menu on each row offers exactly the routes your jurisdiction has. Rate publishers skip weekends and holidays; the program fills such a gap day with the nearest earlier trading day’s rate, and marks the stored rate as filled.

Enter Manually, on the row’s Import menu, opens a form with one line per missing date — fill what you have and leave the rest empty; blank lines are simply skipped. Upload CSV accepts a simple two-column file of date and price, or the full five-column form of date, asset, currency, price, and source, and the panel offers a template already seeded with exactly the missing dates. Dates must be real calendar days in year-month-day form, not in the future, and a file with any invalid line is rejected whole, with the problems named. Keep commas out of the values themselves.

For the number itself, the price services’ own websites carry far more history than their free interfaces expose, and the exchange where you actually traded is often the most reliable source for a niche coin.

The program stores one price per asset, per currency, per day. Entering or fetching a value for a day that already has one replaces it — the newest write wins, and the stored source updates with it. Prices are data entry, not a recorded decision; there is no undo, because re-entering the right value is the undo.

On the ACB Calculator table, the missing-prices badge counts gaps across all years — a price gap in an earlier year blocks the cost-carrying calculation of every later year, so the count deliberately ignores the viewed year. A pending count in the conversions column is clickable and switches to Market Data. The Preflight Report’s Prices check states the same coverage as a verdict — every income and disposal date covered, or the gaps named with a Go to Market Data button.

Stored market data can be removed in the Data Viewer, in the View menu, by source. Removing a source also removes the income conversions derived from it, and the affected assets honestly reappear here as needing prices — coverage never silently survives the data behind it.

The ACB Calculator tab is where a calculation is set up and run. Top to bottom: a settings bar with the choices that define a run, the asset table with one row per asset in your data, and the Calculation History panel that appears along the bottom while runs are in progress.

A calculation always covers your full history — every year your data contains — because what something cost carries forward from year to year. The year shown in the table is a viewing choice, not a boundary; a later section explains that lens.

Jurisdiction sets which country’s tax rules apply; a license limits the flags to the jurisdictions it covers. Method sets how disposals pick their cost: Canada and the United Kingdom each have exactly one method, because their rules pool costs, while the United States and Australia choose between FIFO, LIFO, and HIFO. The currency code beside these is the reporting currency that follows from the jurisdiction — information, not a control.

Two switches appear for the United States only: Account-by-Account, which tracks holdings per exchange or wallet instead of in one universal pool, and the Wash Sale rule switch. Each asset row also carries its own method dropdown — setting it records a per-asset override, and the readiness check re-runs for that asset immediately. While a calculation is running, the settings bar is locked so a run’s settings can’t change underneath it.

Beneath the settings, a read-only rules line restates what the choices mean: the jurisdiction’s tax year and reporting currency, the method, and the jurisdiction’s special rules, marked enabled or disabled where the rule is a switch. It is a summary to check a run against, not a control.

The year dropdown sits in the transactions column header of the asset table. Calculation itself is year-less — every run covers all years — so switching the year never asks for a recalculation: it only changes what is shown. The transaction count re-scopes to the chosen year, with the all-time total beneath it; the per-exchange type breakdown follows; and completed results shown elsewhere re-filter to the chosen year.

Two things deliberately do not follow the year. Missing prices are counted across all years, because a price gap in an earlier year blocks the cost-carrying calculation of every later year. And the Last Calculated column tracks the run itself, which covers all years by definition. Switching the year does re-run the readiness check briefly — the Preflight column reads Checking until fresh verdicts land.

Left to right, a row shows: a selection checkbox and an arrow that opens this asset’s Preflight Report on the Review tab; the asset symbol; the asset’s full first-to-last date range; the transaction count for the viewed year over the all-time total; the currency your files priced the asset in, and whether conversions to the reporting currency are still pending; a price coverage badge; the readiness label; the Last Calculated column; the per-asset method dropdown; and the transaction type breakdown by source, which also clicks through to the Review tab.

The readiness label is the row’s one-glance verdict. Green reads Ready or Up to date. Amber reads Review, for advisory findings, or Recalculate, when the data changed since the last run. Red names what stands in the way — Fetch prices, Needs transfer, or Needs attention — and hovering any label states the verdict and its reason in a sentence.

Needs Calculation appears in the Last Calculated column for an asset never calculated under the current jurisdiction and method, and returns with a count of new rows when files were imported after the last run. Edits, deletions, restorations, and price changes also mark an asset as changed: the program compares a fingerprint of the asset’s current data against the one stamped on the last run, so it notices changes however they were made.

Calculate Selected runs the assets you have checked. Calculate All runs every asset that has any transactions at all, regardless of what is filtered or selected. Both buttons wait while the readiness check is still in progress.

A finding does not stop a run: an asset whose data would fail the engine fails visibly in the Calculation History panel, named, rather than being silently left out. The only assets held back are those whose readiness verdict hasn’t arrived yet, or was computed under a different method than the row now uses — those are skipped with a notice and re-checked. While a queue is running, the buttons become Stop All: stopping cancels the queued assets immediately and gives the one in flight a few seconds to finish cleanly.

Exclude, in the table’s toolbar, sets the selected assets aside from calculations and reports. Nothing is deleted — the rows are marked aside and the asset leaves the table entirely. Before confirming, the dialog shows what the exclusion covers, asset by asset.

Once anything is excluded, an Excluded button appears in the toolbar listing every set-aside asset with its own Restore button; restoring brings the asset back exactly as it was. Calculations already run are not removed by an exclusion — they show as needing recalculation instead, since the data they were run on has changed.

When a run completes, the row’s Last Calculated column shows the time; a failed run shows FAILED beside it, with the error in the hover text. The Calculation History panel along the bottom is the run’s telemetry — asset, method, status, records, speed — and remains after the run finishes.

The figures themselves live on the Review tab: balances, disposals, and the viewed year’s outcome per asset, with the verification checks beside them. The Review results button on the history panel takes you there, and the Review tab lights a quiet dot whenever fresh results are waiting.

Each asset’s Preflight Report runs the same checks: Data, Balance, Prices, Your decisions, Transfers, Engine check, and Cross-year. Each check states what the program observed in your imported files — never a conclusion about what your coins are.

When a check finds something your files alone can’t resolve, it describes the finding and points at the channels that can record your answer. This guide explains what each finding means and what each channel records. The choice stays yours — every answer is recorded as your decision.

The sections below explain each check in turn. A finding that fits none of them still surfaces in the report, under “Other findings” — nothing the program observes is dropped.

The first check states what the program is working from: every imported row for this asset across your full history, broken down by type, with the sources the rows came from. The count covers the full history because the calculation always walks every year — what something cost carries forward — while the second number counts only the rows dated in the tax year you’re viewing. Rows set aside from the calculation are counted separately, never silently.

This check fails only when the calculation couldn’t begin at all: no rows for the selection, a selection the program doesn’t support, or a failure reading the stored data. Everything subtler belongs to the checks below.

The Balance check re-adds your imported rows one by one, outside the tax engine, and compares the result at up to three junctions. First, against your files exactly as imported: any gap between the files and the data used for calculation must be accounted for by your recorded decisions — quantity amendments and classification decisions — and a gap nothing accounts for is treated as a defect to report, never as your problem to explain. Second, where a file carries the exchange’s own running-balance column, against that column: the column is also walked step by step, and a chain that doesn’t add up usually means the export is missing rows. Third, against the holdings from your last calculation, when one exists for the current data.

A difference is a warning, not an accusation — the note names the ordinary causes (units staked or locked in open orders, rounding below the display precision, movements still settling, or an export missing rows) without asserting which one applies. If you have reviewed a difference and can explain it, you can accept it: the acceptance records the exact amount and your reason, changes no figure anywhere, and the warning returns on its own if the difference later changes.

The reconciliation statement lays the whole comparison out top to bottom — each figure with the adjustments and verdicts connecting it to the next — and the ledger shows the row-by-row walk behind those totals, with the program’s running balance beside the exchange’s own where the file reports one.

See also: A balance difference with a file

Valuation needs a price for every row that has tax impact. Rows that carry their own price in your files are covered already; for the rest, the check lists the income and disposal dates no stored market price covers, in your reporting currency. A pass means every such date is covered — prices are data entry, not a recorded decision, and entering a new price for the same day replaces the old one.

The check also names fee rows whose currency the file never stated: those fees are counted, valued 1-to-1 in your reporting currency, and the check’s job is to disclose that assumption so you can judge whether it fits. That finding is a labelling question, not a missing rate — Market Data has nothing to fetch for it.

See also: Rows missing a price · Fees with no recorded currency

This check is a ledger, not a problem-finder. It lists everything you have recorded for this asset — classification decisions, confirmed transfer pairs, value amendments, accepted balance differences, and safe-harbor allocations — each stored with the date you made it. It renders even when everything else passes, because it is also the way back: classification decisions and confirmed pairs can be undone from here, amendments from each row’s card, acceptances from the Balance check.

Safe-harbor allocations are the one permanent kind — there is no edit, undo, or delete. The check warns only when a recorded allocation matches no acquisition in your data; an unmatched allocation has no effect on the calculation, which is exactly why it’s worth reviewing.

See also: What can I record? · Walkthrough: correcting a value on a row

Moving your own coins between your own accounts creates no tax event — but only when both legs are in your data. The automatic matcher pairs withdrawals and deposits of the same asset within 2% on quantity and 48 hours; the check states how many pairs matched and how many you confirmed yourself. The window is the matcher’s rule, not a limit on yours — a pair you confirm is honoured however far apart its legs sit.

The check’s main finding is a deposit with no matching withdrawal: coins arrived and the program can’t know what they cost. When the finding appears, time decides how hard it presses — only deposits that arrived by the end of the viewed tax year can affect that year, and calculation is blocked only when the asset was also sold that year. The questions under the finding walk you to the one channel that records your answer.

See also: A deposit with no matching withdrawal

The Engine check is a dry run of the real thing: the same engine that produces your reports walks the full history with nothing saved. Its question is coverage — whether every sale is backed by the holdings the calculation actually has at that moment.

It checks quantities, not costs — cost questions live with the Transfers check, and a pass here doesn’t answer them. When a finding above stops the data from even loading, the dry run doesn’t happen and the check says so, instead of claiming a pass it never made. A sale larger than holdings usually traces back to an acquisition the program never saw, so resolving the findings above it usually clears it.

See also: A sale larger than holdings

The full history is calculated as one sequence — the year you view is a lens, not a boundary. This check discloses the reach of the findings above: an issue dated in an earlier year that stays unresolved rolls forward into the viewed year’s figures, and the check names the earliest year involved.

It finds nothing of its own. The findings live in the checks above; this one only tells you when they reach further than the year on screen. A pass means the checks above found no unresolved earlier-year issues affecting this year’s figures.

Coins arrived in one of your accounts, but no imported file shows them leaving anywhere else. The program can’t know what they cost you — and cost is what the tax calculation is built on — so it asks you to say where they came from.

Each question below points at the one channel that records that answer. Most answers are undoable decisions; the income route is the exception — income can only be recorded at import, so it takes a delete and re-import.

Did these coins leave another account that’s already in your imports?

Match with a withdrawal — Pairs this deposit with that withdrawal as two legs of one movement of your own coins — no tax event, and a later sale uses your original cost.

Did you buy or earn them in an account you haven’t imported yet?

Import that account’s file — Once the missing file is imported, its withdrawal is in your data — then Match with a withdrawal links the two legs.

Were they already yours, held somewhere you won’t be importing (a private wallet, a closed account)?

These are my own coins — Records your decision that this deposit is your own coins arriving from outside your imports. It records the decision, not a cost.

Did they come from a fork, an airdrop, or a reward?

Re-import with an income classification — Income can’t be recorded after import — delete this file’s import, import it again, and classify the row’s type as income in Step 3.

Are they too small to be worth tracking?

Mark as dust — Records your decision to leave these coins out of the calculation entirely.

See also: Walkthrough: your own coins coming back · Walkthrough: coins from a fork or an airdrop

A row carries a fee amount, but the file never says which currency that fee is in. The program never guesses a label: the fee IS counted in the calculation, valued 1-to-1 in your reporting currency, and the Prices check names the rows so you can judge whether that assumption fits your situation.

If those fees really were charged in your reporting currency, the 1-to-1 valuation is exact and there is nothing to do. If they were charged in a different currency, re-import the file with its fee-currency column mapped in the import wizard, so the rows carry the currency from the start.

Some rows carry no price in your files, and no stored market price covers their dates. Valuation needs a price for every row that has tax impact, so the Prices check lists the dates that are not covered.

Fetch prices in the Market Data tab, or enter them manually. Prices are data entry, not a recorded decision — entering a new price for the same day replaces the old one.

The Balance check recounts your imported rows and compares the result against the balance column in the file (where the file carries one) and against what the tax engine holds. A difference means two records of the same account disagree — the check names the amount, and the break locator can point at the first row where the two records diverge.

If you have reviewed a difference and can explain it, you can accept it. An acceptance records the exact difference and your reason — it changes no figure anywhere, and if the difference itself changes, the warning returns on its own.

See also: Walkthrough: accepting a balance difference

A disposal needs more units than the calculation holds at that moment. The usual cause is an acquisition the program never saw — an account’s file not yet imported, or a deposit above it still unresolved — so resolving the findings above it usually clears this one.

If the shortage survives after every deposit is resolved and every file is in, the record card’s history and the ledger’s running balance show where the units went missing.

Coins leave one of your accounts and arrive in another, and the deposit is flagged because no withdrawal in your imports matches it. This walks the three shapes that story takes, strongest first.

  1. Start from the finding — The Transfers check names the deposit — how much arrived, where, and when — and says no matching withdrawal is in your imports. That is a statement about your files. The automatic match looks for a withdrawal of the same asset, within 2% on quantity, inside 48 hours of the deposit; a movement that took longer than two days, or that lost more than 2% on the way, is exactly the kind it cannot pair on its own.
  2. Look for the other leg — On the flagged row, “Match with a withdrawal…” lists the withdrawals in your imports that could be this deposit’s other half: same asset, earlier than the deposit, quantity within 2%, and not already used in another pair. A withdrawal slightly larger than the deposit is the ordinary shape when a network fee was taken in transit.
  3. Confirm the pair — Choosing a candidate raises a confirmation that states what you are recording: that the withdrawal and the deposit are two legs of one movement of your own coins. A pair you confirm is honoured even when the legs are days apart or sit on the same venue — the 48-hour window is the automatic matcher’s rule, not a limit on yours. It is recorded as your decision, and it can be undone.
  4. If the other leg isn’t imported yet — Import that account’s file first. Once its withdrawal is in your data the two legs may pair on their own; if they sit outside the window, match them by hand as above.
  5. If the other leg will never exist — Some accounts are closed and some wallets were never going to be imported. “These are my own coins” records your decision that this deposit is your own coins arriving rather than something new: no income, and no new cost.
  6. What that last one does not do — It records the decision; it does not supply a cost. The coins keep the cost already in your records — so if their purchase or income is nowhere in your imports, the calculation still holds no cost for them, and a later sale of those coins can surface on the Engine check as a sale larger than holdings. Importing the account that acquired them is what closes that; recording the decision alone does not.
  7. Where it shows afterwards — Confirmed pairs and classification decisions both appear on the Your decisions check, and both can be undone from there.

See also: A sale larger than holdings

Walkthrough: coins from a fork or an airdrop

Section titled “Walkthrough: coins from a fork or an airdrop”

Coins appear in an account without ever having been bought. The deposit is flagged like any other arrival with no matching withdrawal — but the channel that records this one is the only one that is not undoable, so it is worth being sure before taking it.

  1. Start from the finding — The Transfers check names the deposit and says no matching withdrawal is in your imports: the automatic match looked for a withdrawal of the same asset, within 2% on quantity, inside 48 hours, and found none.
  2. Read the last line of the finding — If the file is a Kraken ledger and the deposit matches an event the program recognises — by the ledger’s subtype, or by asset and date — the finding ends with a line like “Looks like an airdrop.” Nothing has been classified: the suggestion rides on the sentence and the severity is unchanged. If there is no such line, that means only that the program has no pattern for this deposit.
  3. Rule out the two answers that belong to other stories — “These are my own coins” records that the coins were already yours and their purchase or income is already somewhere in your imports — a credit that was never bought has no earlier cost to point at. “Mark as dust” sets the rows aside entirely. Both are undoable, so a wrong turn here is recoverable.
  4. The one route that records income — Income can only be recorded while a file is being imported. Delete this file’s import, import it again, and set the row’s classification in Step 3 of the wizard. Nothing after import can do this: decisions recorded later reach classification — own coins, or dust — and four numeric values (quantity, price, and the two fee amounts). Your file is not touched; the classification is applied as it is read.
  5. What changes once the rows carry it — The program adds the units to your holdings at their value on that date, and the deposit stops being an arrival with nothing behind it. Rows classified as income need a price for their date — if none is stored, the Prices check names the date and Market Data can fetch it or take yours.

See also: Rows missing a price

A row’s quantity, price, or fee amount is wrong and you know the right value. The amendment channel records your correction beside the imported value — never over it.

  1. Start from the row — On the Review tab, open the asset’s Ledger view and click the row — its card opens with the recorded transaction and the row’s full provenance. The same card opens from the All issues view via Details.
  2. Choose the field — Amend a value covers exactly four fields: quantity, price, and the two fee amounts. Nothing else is amendable — cost and gain figures are computed from these, not stored beside them.
  3. See what recording does, then give the reason — As you type the corrected value, the dialog shows the imported value beside yours and states what recording the change will do — before anything is committed. The reason is required and is recorded with the amendment and its date.
  4. What changes — Calculations use the amended value; the stored row is never overwritten. The ledger shows the value in effect marked with a star, the imported value stays on the card, and the report re-checks immediately.
  5. Undoing — Each amendment reverts independently from the row’s card — the previous value returns and the history of amendments and reverts is kept, with the imported value visible forever. Note that Undo all on the Your decisions check does not touch amendments; they are undone one by one, where they were made.

See also: What can I record?

Walkthrough: accepting a balance difference

Section titled “Walkthrough: accepting a balance difference”

The Balance check found a difference between two records of the same account, you have reviewed it, and you can explain it. Accepting records that review — it does not change the difference.

  1. Start from the finding — The flagged comparison on the Balance check offers two moves side by side: hunt the difference down, or accept it.
  2. Hunt it down first — Locate the break scans the running balances row by row and points at the first row where the two records part ways — read-only, nothing changes — with a button that opens the ledger scrolled to that row. If the cause turns up, a missing file or a wrong value, fix that instead of accepting.
  3. Accept when you can explain it — The dialog states what recording does: the difference itself is not changed, the acceptance pins exactly that amount, and your reason — required — is recorded with the date.
  4. What changes — The comparison shows a pass with your acceptance note instead of a warning, and the reconciliation statement carries the reviewed-and-accepted line. No figure changes anywhere.
  5. The check keeps watching — If the difference itself later changes, the warning returns on its own and the old acceptance is named as no longer applying. If the difference disappears, the leftover acceptance is named and removable — nothing lingers silently.
  6. Where it shows and how it undoes — The acceptance is counted on the Your decisions check, and undo lives where the decision shows — on the Balance check itself.

See also: A balance difference with a file

Every channel below records your decision or your data — the program never decides for you, and imported rows are never edited in place.

Match with a withdrawal · undoable · recorded as your decision

Section titled “Match with a withdrawal · undoable · recorded as your decision”
  • When: A deposit flagged with no matching withdrawal (Transfers check).
  • Records: Your decision that a specific withdrawal and this deposit are two legs of one movement of your own coins.
  • Changes: The pair is treated as one transfer — no tax event, and a later sale uses your original cost.
  • Never touches: Your imported rows — nothing is edited or deleted.
  • Undo: Removing the assertion restores the original state exactly.
  • Where you see it: Your decisions check (confirmed transfer pairs) and the Transfers check.

These are my own coins / Mark as dust · undoable · recorded as your decision

Section titled “These are my own coins / Mark as dust · undoable · recorded as your decision”
  • When: An unmatched deposit you recognize as your own coins arriving, or coins too small to track.
  • Records: Your classification decision for those specific rows (own coins, or dust).
  • Changes: The calculation reads the rows under your recorded classification — own coins create no income; dust rows are left out entirely.
  • Never touches: The imported rows themselves — and it can never create income (income requires re-importing with a Step 3 classification).
  • Undo: Undo all decisions removes them.
  • Where you see it: Your decisions check (classification decisions); the ledger’s override chip.

Amend a value · undoable · recorded as your decision

Section titled “Amend a value · undoable · recorded as your decision”
  • When: A row whose quantity, price, or fee amount you know is wrong (from the record card).
  • Records: Your corrected value with the original beside it, a required reason, and the date.
  • Changes: Calculations use the amended value.
  • Never touches: The stored row — the vendor’s value is never overwritten and stays visible.
  • Undo: Each amendment reverts independently; reverting re-exposes the previous value and the history is kept.
  • Where you see it: Your decisions check (value amendments); amended chips in the ledger; the record card’s history.

Record a safe-harbor allocation · PERMANENT · recorded as your decision

Section titled “Record a safe-harbor allocation · PERMANENT · recorded as your decision”
  • When: A pre-2025 allocation you already made under Rev. Proc. 2024-28 (US, Account-by-Account).
  • Records: The allocation exactly as you made it: quantity, cost basis, acquisition date, wallet.
  • Changes: Matching pre-2025 acquisitions start in the allocated wallet.
  • Never touches: Everything else — the program never computes or suggests an allocation; it records yours.
  • Undo: There is no edit, undo, or delete.
  • Where you see it: Your decisions check (permanent); the US report footnotes; the audit report.

Accept a balance difference · undoable · recorded as your decision

Section titled “Accept a balance difference · undoable · recorded as your decision”
  • When: A Balance-check difference you have reviewed and can explain.
  • Records: The exact difference, your reason, and the date.
  • Changes: The check shows a pass with your acceptance note instead of a warning.
  • Never touches: The calculation — an acceptance changes no figure anywhere.
  • Undo: Undo any time; if the difference itself changes, the warning returns on its own.
  • Where you see it: The Balance check’s reconciliation statement; Your decisions check.
  • When: Rows missing a price (Prices check; the Market Data tab).
  • Records: Price data only — data entry, not a recorded decision.
  • Changes: Valuations use the stored price.
  • Never touches: Row quantities and classifications.
  • Undo: Entering a new price for the same day replaces the old one.
  • Where you see it: The Market Data tab; the Prices check clears.
  • When: An asset you don’t want in calculations at all.
  • Records: A reversible exclusion mark on the asset’s rows.
  • Changes: The asset disappears from calculations and checks until restored.
  • Never touches: The rows’ contents — restoring brings everything back exactly.
  • Undo: Restore any time; the exclusion leaves no trace afterwards and is not counted in Your decisions.
  • Where you see it: The Restore menu; the asset leaves the tables.
  • When: A shortage on one account with holdings available on another (US, Account-by-Account).
  • Records: Two new transfer rows — a send and a deposit — marked [Create Transfer].
  • Changes: Holdings move between accounts at the recorded time.
  • Never touches: Existing rows.
  • Undo: The created rows can be deleted like any imported rows.
  • Where you see it: The ledger; the Engine check clears.

Re-import with a Step 3 classification · not undoable

Section titled “Re-import with a Step 3 classification · not undoable”
  • When: Rows whose type needs a different class — including the only route to income (forks, airdrops, rewards).
  • Records: The classification is applied to the rows at import time.
  • Changes: The rows carry the class you chose from the start.
  • Never touches: Your CSV file — classification happens in the import wizard; the file is read as-is.
  • Undo: Changing it means deleting the import and importing again.
  • Where you see it: The imported rows’ class, in the ledger.
  • When: Rows that should not be in the database at all.
  • Records: Nothing — this is a hard delete.
  • Changes: The rows are permanently removed.
  • Never touches: Rows outside the chosen range.
  • Undo: Not undoable — re-importing is the only way back.
  • Where you see it: The activity log line; the rows are gone.

The Review tab is where results are verified, not produced. The bar across the top holds the year selector — the same lens the ACB Calculator uses, one setting with two handles — beside read-only labels stating the jurisdiction, currency, method, and modes the figures were computed under, and a What can I record? button listing every fix channel with what it records and whether it can be undone. There is deliberately no Calculate button here: runs start on the ACB Calculator, and Review verifies what they produced. A quiet dot lights on the tab when a batch finishes while you are elsewhere.

The table shows one row per asset: the all-time balance from the independent recount, the viewed year’s transaction count, disposals, and net gain or loss, and the readiness verdict. The disposal and gain figures come from the completed calculation matching the row’s method and mode; a dash means there is no figure to show — either nothing was disposed that year, or no calculation matches the current selection yet. A strip above the table sums the balance story across the whole history: how many assets reconcile, need attention, or haven’t been checked yet.

The arrow on a row — or its verdict label — expands the asset into a two-view panel: Report and Ledger. Report is the asset’s Preflight Report; its Copy report button puts the whole thing on the clipboard as plain text, ready for an email to your accountant. Several assets can be open at once, and changing the jurisdiction, year, method, or mode closes every expansion — a report opened under one selection must not linger into another. Arriving from the ACB Calculator’s arrow lands here with the asset already open and scrolled into view.

The Ledger view lists the asset’s rows — the full history, not only the viewed year — with date, type, source file, quantity, price, fees, and running balances. The running balances come in two pairs. Within this file: the program’s row-by-row recount beside the balance column the file itself carries, where it carries one — two records of the same account that ought to agree. Across all accounts: the portfolio recount, in which your own transfers don’t change what you hold, beside the running balance of the last calculation, where a fresh one exists. When a column can’t be shown, a note says why instead of leaving a blank.

Opened from a warning, the ledger starts on the flagged rows only, with markers counting the rows hidden between them; a checkbox switches to the full history. Chips on a row mark findings and your recorded decisions, and an amended value is shown as the value in effect, marked with a star — the imported value stays on the row’s card.

Clicking a ledger row opens its card: the recorded transaction, the decisions and amendments on it, and the row’s full provenance — how the file was read, the raw values from the file, how they were transformed, and what the checks said at import time. Every amendment keeps the original value visible, forever.

The card is also where values are corrected. Amend a value covers four fields — quantity, price, and the two fee amounts — and recording one requires a reason; before you commit, the dialog shows the imported value and states exactly what recording the change does. Each amendment reverts independently, and the history of amendments and reverts is kept. The stored row is never overwritten — the file’s value stays visible beside yours. Rows with price findings offer a jump to Market Data, and United States users see a button for recording a pre-2025 safe-harbor allocation, the one permanent decision kind.

The All issues view lists findings across every asset, drawn from three producers: the readiness checks, the validations recorded when each file was imported, and live price-coverage gaps. It shows all years by default and says why — issues on earlier rows still feed later years’ figures — with a checkbox to narrow to the viewed year. Assets that haven’t been checked under the current selection are named in a strip rather than appearing clean. Each finding carries its own door: Details opens the record’s card in place, market findings open Market Data, and asset-level findings jump to that asset’s report.

When the Balance check finds a difference, it offers two moves side by side: hunt it down, or accept it. Locate the break scans the running balances row by row and points at the first row where the two records part ways — read-only, nothing changes — with a button that opens the ledger scrolled to that row. Accept difference records your decision that the difference is explained: the reason is required, the acceptance pins exactly that amount, it changes no figure anywhere, and if the difference itself ever changes, the warning returns on its own. Undo lives where the decision shows, on the Balance check itself.

Anything that inspects or records lives here: the Preflight Report, the ledger, record cards and amendments, balance acceptances, the break locator, and the all-issues sweep. What doesn’t live here: running calculations and changing the configuration — those stay on the ACB Calculator, and Review states the settings it is showing rather than letting them drift mid-review.

The Reports tab is a sidebar and a viewer: pick the jurisdiction, tax year, and — for the United States and Australia — the cost-basis method on the left, and the report renders on the right. Each jurisdiction has its own set, twenty-two reports in all, and they come in three kinds.

Filing reports mirror an actual tax form: Schedule 3 and the T1135 for Canada; Form 8949 and Schedule D for the United States; the SA108 Capital Gains summary for the United Kingdom; the CGT Summary for Australia, which maps to Question 18 of the ATO return’s supplementary section. Supporting reports carry the detail behind a filing report — Australia’s CGT Worksheet and the United Kingdom’s Capital Gains Details, whose own description notes that HMRC may request per-disposal computations. Records reports document rather than file: each jurisdiction’s Income Report and its Audit Provenance report, plus the per-jurisdiction detail views — Canada’s ACB Summary and Superficial Loss report, the United States’ Lot Tracking and Wash Sale reports, the United Kingdom’s Pool History. Every report carries a Learn More toggle that explains, in place, what it shows and how to read it.

A report reads from completed calculations, so the order is the pipeline’s own: import, cover prices, calculate — then report. With no completed calculation for the selected year the list says so and points back to the ACB Calculator. When the readiness checks found unresolved issues affecting the year, reports for that year are withheld and the message names the affected assets — the route is the one the message states: open each asset’s report on the Review tab, resolve, recalculate.

Reports also follow the calculation’s mode automatically. Only calculations matching the current method and — for the United States — the current Account-by-Account and wash-sale settings are offered, and when some assets were calculated under a different mode, the sidebar says which ones are not included rather than mixing modes in one report.

Selecting a report shows it immediately — there is no separate generate step for viewing. The year list shows each year with how many assets have results in it, and marks the year most people are filing for. Most reports offer an aggregate view across all assets as well as a per-asset view; the detail reports that only make sense per asset — ACB Summary, Lot Tracking, Pool History, and Audit Provenance — ask you to pick the asset. The Income Reports additionally let you choose, per income type, which reporting form label the income is presented under, and remember the choice.

A few behaviours answer most questions about the detail reports. The United Kingdom’s Capital Gains Details badges every disposal with the matching rule that decided it — same day, thirty day, pool, or mixed when more than one contributed (Sections 105, 106A, and 104 respectively) — and Pool History exists to verify the pool itself: the running balance, the average cost, and the acquisitions the matching rules diverted before they ever reached it. The SA108 form is boxes 13.1 through 13.8: the program fills the disposal counts, proceeds, costs, gains, and losses; the real-time-return boxes stay at zero, since they don’t apply to self-calculated figures, and the claims box is a code you add only when making a claim.

Australia’s CGT Worksheet gives a disposal one row per parcel it drew on, each with its own discount eligibility — which is why one sale can span several rows — and its Lot Tracking measures holding periods against the end of June, the jurisdiction’s own year-end. The United States’ Lot Tracking marks each lot active or exhausted as sales consume it. Only the United States has per-account sections: Australia and the United Kingdom have no per-wallet tracking to report, by design.

One reconciliation surprises Canadians: the T1135 reports the maximum cost reached during the year, not the year-end position, so it can legitimately exceed the ACB Summary’s closing figures — heavy buying early in the year raises the maximum even when little remains by December.

Every report exports to PDF, and all but the four Audit Provenance reports also export their data as CSV. Both buttons open a save dialog — files go wherever you choose — and the suggested name carries the report, jurisdiction, asset or aggregate scope, the method where it varies, and the tax year written in the jurisdiction’s own style; never a date suffix, so re-exports overwrite rather than multiply.

During the trial, every report can be viewed but not exported — the export buttons carry a lock and say so plainly — and copying report data is held back the same way. When a trial expires, the program says so once per session and then keeps every report viewable; export stays locked. A license unlocks export for its jurisdictions.

A sensible package for a professional is one of each kind: the filing report for the year, its supporting detail where the jurisdiction has one, and the Audit Provenance report — which traces every number back to its source, documenting where the data came from, how it was transformed, and which tax rules were evaluated for each disposal. Its six sections are the same in every jurisdiction — data sources, the import audit trail, calculation metadata, data reconciliation, rule applications, and system events — so a professional who has read one can read them all. For a United States filer using specific identification, the Audit Provenance report together with Lot Tracking states its own role as the books and records behind the method. The Review tab’s Copy report button — the plain-text Preflight Report — makes a good cover note, because it states what was checked and what you decided.

The sidebar’s method selector filters which calculations feed the report, and each United States report states in its header which tracking mode its calculation used — universal, or Account-by-Account. Schedule D nets the short-term and long-term totals automatically when they run in opposite directions, and carries the annual loss limit and the carryover to the following year into the form. In Account-by-Account mode the Audit Provenance report gains a further section covering per-account cost basis and transfer movements, and Lot Tracking notes whether a safe-harbor allocation has been recorded. Which Form 8949 boxes your disposals land in is driven by the Exchange Form Status panel in Settings — recorded per exchange, per year, as the getting-started chapter describes.

The Dashboard is the tab the program opens on: one screen that answers how far along the season’s work is and where your position stands. It reads top to bottom as status before numbers — a readiness strip states whether the data underneath the figures is settled, and a last-activity line names the most recent thing that happened. When the strip says you are not ready, the cards below still render, but the honest reading is to fix the readiness gap first and trust the numbers after. An Import History section at the bottom lists what has been brought in.

A control bar filters everything on the screen: jurisdiction, tax year, and — for jurisdictions with more than one cost-basis method — the method. Every figure on the Dashboard follows the selected method, so if you have calculated an asset under more than one, switching the method control flips the whole view to that method’s results. The tax year is written the way the jurisdiction writes it: a calendar year for Canada and the United States, a July-to-June span for Australia, an April-to-April span for the United Kingdom.

The Tax Summary card is the position readout, and its fields follow the jurisdiction’s own vocabulary: proceeds, cost base, gains and losses, the taxable portion after the jurisdiction’s inclusion or discount treatment, and the rule-specific lines — losses denied under the superficial loss rule, losses deferred under the wash sale rule, the discount applied to long-held Australian gains, the United Kingdom’s Annual Exempt Amount shown against the year’s net gains.

One Australian reading deserves care: the Dashboard’s net figure is gains less losses before the discount, while the CGT Summary report’s net capital gain is the after-discount figure the return asks for. Compared side by side the two differ by exactly the discount amount — both are right; they answer different questions.

The card offers rate choices — a marginal rate, a long-term rate for the United States, an income tax rate for the United Kingdom — and none of them touch the calculation. They exist only to turn your already- calculated result into an estimated tax figure for situational awareness, and the estimate is display-only: the reports carry the gross figures unchanged, whatever the dropdowns say.

Crypto income — staking, mining, airdrops, rewards, interest — rolls up into its own figure, valued as of each receipt. Income is counted in full: the inclusion and discount treatments that reduce taxable capital gains do not apply to it, which is why the income line and the gains line can feel differently sized for the same year.

The insights panel surfaces what the current year’s results imply: rules that fired (superficial losses denied, wash sales deferred, the Australian discount used, the United Kingdom exempt amount consumed), data problems worth fixing (missing prices, holdings with no recorded cost, calculations gone stale behind newer data), and one nudge that is deliberately a question rather than an assertion — when Canadian cost basis crosses the foreign-property reporting threshold, the program cannot know where your coins are custodied, so the insight says the requirement may apply and leaves the answer to you and your tax professional. Insights with an action carry a button; the rest are informational by design.

The pipeline card tracks each asset through the three stages the season runs in — data imported, prices covered, calculation done — with a count of how many assets are fully ready. An asset that is held but was never disposed of shows a quiet no-disposals mark rather than figures. The stage that needs attention is the door: the card jumps to Market Data for missing prices and to the calculator for assets not yet calculated.

Cost carries forward. What you paid for something years ago is what decides the gain when you sell it this year, so a calculation that started at January first would be starting in the middle of the story. The program therefore always calculates your full history as one sequence — there is no such thing as calculating only one year — and every disposal in the result is stamped with the tax year it falls in.

The year selector never asks for a recalculation, because there is nothing to recalculate: switching year re-reads the same stamped results through a different slice. That is why the switch is instant, and why the program calls the year a lens rather than a setting.

The lens moves what is shown: the transaction counts on the ACB Calculator rows, the type breakdowns, the disposals and outcomes on the Review tab, and which year a report covers. It deliberately does not move three things. Missing prices are counted across all years, because a price gap in an earlier year blocks the cost-carrying calculation of every later year. The Last Calculated column and the staleness signal belong to the run itself, which covers all years by definition. And the asset list is the asset list — an asset with no rows in the viewed year is still there, with its in-year count reading zero.

The Cross-year check in the Preflight Report is this chapter as a verdict: when a finding dated in an earlier year stays unresolved, the check says so, because the one-sequence calculation rolls it forward into the year you are viewing.

Your database file carries an internal format version. When a newer version of the app opens an older file, it upgrades the format in place, automatically, as part of the open — your rows are carried over unchanged; only the file’s internal structure moves forward. A file that just sits on disk is never touched: only opening it does this.

The door is one-way. Once a file has been upgraded, older versions of the app can no longer open it. The reverse is also announced rather than mangled: if you ever point an older app at a newer file, the open fails with a plain message on the Welcome screen instead of damaging anything.

Make a copy first. Export Database Copy, in Settings, writes one clean copy of your database wherever you choose — do that before installing a new version of the app, and name the copy so you can tell it apart later. If you ever need to go back to the older app version, the copy made before the upgrade is what still opens there; the upgraded original will not.

This is rarely needed — upgrades carry your data forward exactly, and going backward is the unusual case. But a copy costs a moment, the door only swings one way, and your tax records deserve the moment.

Every transaction type the program reads resolves to one of five classes, and the class decides the tax treatment. Exchange rows are the capital-gains world: buys, sells, and trades. Income rows are taxed as income at their value on the day they arrive — rewards, staking, mining, airdrops. Transfer rows are your own coins moving between your own accounts: tracked, but no tax event. DeFi rows follow their operation — swaps and liquidity events dispose and acquire like trades. Ignored rows are set aside from everything: spam, failed transactions, internal bookkeeping.

Two defaults are worth knowing. A type the program has never seen is treated as Exchange — the conservative reading, and the reason unrecognized types are worth a look in the import wizard’s classification step. And a type whose name starts with an underscore is Ignored, a convention some export tools use for their internal rows.

Generated from the running program’s registry.

ClassTax treatmentTypes
Exchangecapital gains15
Incomeincome at value on receipt15
Transferno tax event10
DeFicapital gains13
Ignoredleft out entirely14

The full vocabulary, exactly as the running program holds it. The import step maps each file’s own wording onto these types — a file’s “Purchase” becomes buy, a “Staking Reward” becomes staking — and the classification step of the import wizard is where a type’s class can be changed for the rows being imported.

All 67 registered types — generated, never hand-copied.

TypeClassWhat it isIncome category
buyExchangeAn acquisition — the units enter your holdings at what they cost.
futuresExchangeA derivatives row; acts through its buy or sell side.
limitExchangeAn order-type label; acts through its buy or sell side.
limit_buyExchangeA buy placed as a limit order — an acquisition.
limit_sellExchangeA sell placed as a limit order — a disposal.
marginExchangeA margin-trading row; acts through its buy or sell side.
marketExchangeAn order-type label; acts through its buy or sell side.
market_buyExchangeA buy placed as a market order — an acquisition.
market_sellExchangeA sell placed as a market order — a disposal.
optionsExchangeAn options row; acts through its buy or sell side.
rolloverExchangeA periodic financing charge on an open margin position (Kraken).
sellExchangeA disposal — the units leave and the gain or loss is realized.
settledExchangeSettlement of a margin position on spot (Kraken).
stopExchangeAn order-type label; acts through its buy or sell side.
tradeExchangeOne asset for another; the program reads the row’s buy or sell side.
airdropIncomeCoins distributed to you unsolicited — income on receipt.windfall income
bonusIncomeA bonus credit — income at its value on receipt.passive income
cashbackIncomeCashback paid in crypto — income at its value on receipt.passive income
dividendIncomeA dividend paid in crypto — income at its value on receipt.passive income
forkIncomeCoins created by a chain split — income on receipt.windfall income
hard_forkIncomeCoins created by a chain split — income on receipt.windfall income
interestIncomeInterest paid in crypto — income at its value on receipt.passive income
invite_bonusIncomeA sign-up or invite credit — income on receipt.windfall income
miningIncomeMined coins — income at their value on receipt.passive income
realized_pnlIncomeAn exchange-reported trading profit or loss, taken as income.trading income
referralIncomeA referral payment — income at its value on receipt.passive income
rewardIncomeA reward credited to you — income at its value on receipt.passive income
rewardsIncomeA reward credited to you — income at its value on receipt.passive income
stakingIncomeA staking reward — income at its value on receipt.passive income
yield_farmingIncomeYield-farming proceeds — income at their value on receipt.passive income
depositTransferCoins arriving at an account — the Transfers check looks for the matching withdrawal.
internal_transferTransferA movement inside one venue — no tax event.
receiveTransferCoins received — no tax event; their cost carries from wherever they left.
sendTransferCoins sent out — no tax event; a movement, paired where possible.
spendTransferCoins leaving, recorded as a movement — no gain is computed for this type.
transferTransferA movement of your own coins; the program pairs its two legs where it can.
transfer_inTransferCoins arriving — no tax event; their cost carries from wherever they left.
transfer_outTransferCoins leaving — no tax event; the other leg should arrive somewhere in your data.
unstakeTransferStaked units returning to you — a principal return, not new income.
withdrawalTransferCoins leaving an account — no tax event; often the other leg of a deposit.
borrowingDeFiBorrowed units arriving — treated as an acquisition.
bridgeDeFiA cross-chain movement; on its own it neither adds nor removes units.
collateralDeFiUnits posted as collateral — treated as a disposal.
flash_loanDeFiA same-transaction loan; on its own it neither adds nor removes units.
lendingDeFiUnits lent into a protocol — treated as a disposal.
liquidationDeFiA position closed by the protocol; on its own it neither adds nor removes units.
liquidity_addDeFiUnits placed into a pool — treated as a disposal.
liquidity_inDeFiUnits placed into a pool — treated as a disposal.
liquidity_outDeFiUnits returned from a pool — treated as an acquisition.
liquidity_removeDeFiUnits returned from a pool — treated as an acquisition.
lp_depositDeFiUnits placed into a pool — treated as a disposal.
lp_withdrawDeFiUnits returned from a pool — treated as an acquisition.
swapDeFiOne token exchanged for another through a contract — a disposal and an acquisition.
approvalIgnoredA contract permission, not a movement of value — set aside.
approveIgnoredA contract permission, not a movement of value — set aside.
borrowIgnoredA loan-drawdown label some exports use — set aside; the DeFi borrowing type is the one that adds units.
contract_callIgnoredA contract interaction with no value moved — set aside.
contract_interactionIgnoredA contract interaction with no value moved — set aside.
dustIgnoredAmounts too small to track — set aside.
dust_attackIgnoredTiny amounts sent to bait interaction — set aside.
failedIgnoredA transaction that did not complete — set aside.
failed_transactionIgnoredA transaction that did not complete — set aside.
internalIgnoredA venue’s internal bookkeeping row — set aside.
null_transactionIgnoredA placeholder row with no value — set aside.
repayIgnoredA loan-repayment label — set aside.
revokeIgnoredA permission withdrawn, not a movement of value — set aside.
spamIgnoredUnrequested tokens — set aside from all calculations.

Income categories and where they typically report

Section titled “Income categories and where they typically report”

Income types carry a category that suggests which form the income typically reports on in each jurisdiction. Typically is the operative word: the Income Reports let you choose the form label per income type, and your choice is remembered — the table below is the starting point, not a ruling.

Typical forms by jurisdiction — Canada, United States, Australia, United Kingdom.

CategoryCanadaUnited StatesAustraliaUnited Kingdom
business incomeT2125Schedule CItem 15SA103
passive incomeLine 13000Schedule 1Item 24SA100 Box 17
windfall incomeLine 13000Schedule 1Item 24SA100 Box 17
trading incomeLine 13000Schedule 1Item 24SA100 Box 17

The program recognizes these exports by their column headers, and only claims a match when the headers fit almost perfectly — a near-miss falls through to automatic column mapping rather than a wrong guess. A file that matches nothing is not rejected: its columns are mapped automatically and shown for confirmation in the import wizard’s second step.

Each format declares how its rows are shaped, how related rows group together, and — where the exchange is consistent about it — which currency its fees are charged in. Where a format’s fee convention reads as not declared, the program determines fee currency from the file itself, row by row, and the Prices check names anything it could not determine.

Generated from the running program’s format registry.

FormatRow shapeFee conventionNotes
NDAX Tradestrading-pair rowsfees in what the trade receivedFee behavior verified against real NDAX exports — fees are charged in what the trade received.
NDAX Stakingone row per transactionnot declared — determined per fileA staking-only export with no fee column — rewards carry no fees.
Generic Standardone row per transactionnot declared — determined per fileThe simple layout the program documents itself: date, type, asset, quantity, price, currency, fee, exchange, notes.
Coinbaseone row per transactionfees in the pair’s quote currencyMatches the USD-denominated Coinbase export. The newer multi-currency export is not yet a built-in — its columns map automatically instead.
Newtonsent/received columnsa fee-currency column states itCarries its own fee-currency column — the one built-in format that states fee currency explicitly.
Shakepaysent/received columnsnot declared — determined per fileThe real 11-column export; it carries no fee column — Shakepay prices through its spread.
Kraken Tradestrading-pair rowsfees in the pair’s quote currencyVerified against a real 16-column export. Not importable alone — attach it to a Kraken Ledger file, which carries the deposits and rewards this file lacks.
Kraken Ledgerledger entries, groupedfees in the row’s own assetMatches the current 12-column export; older variants map automatically. Fees are in each row’s own asset.
Crypto.com Appsent/received columnsnot declared — determined per fileSent and received columns, with the amount’s sign giving direction; the export carries no fee column.
Binance Transaction Historyledger entries, groupedfees in the row’s own assetLedger-style rows grouped by time; fee rows carry their own coin.

For each built-in format, the columns it expects and what each is read as, in the file’s own order. Columns a file carries beyond these are left alone — unmapped columns are never guessed at.

NDAX Trades

File columnRead as
PAIRpair
SIDEtradeType
TYPEorderType
AMOUNTamountBase
VALUEamountQuote
PRICEprice
FEEfees
TX_IDtransactionHash
ORDER_IDorderId
DATEtimestamp

NDAX Staking

File columnRead as
ASSETassetSymbol
AMOUNTamountBase
TYPEtradeType
DATEtimestamp

Generic Standard

File columnRead as
Datetimestamp
TypetradeType
AssetassetSymbol
QuantityamountBase
Priceprice
CurrencyquoteCurrency
Feefees
ExchangeexchangeName
NotesmemoInternal

Coinbase

File columnRead as
Timestamptimestamp
Transaction TypetradeType
AssetassetSymbol
Quantity TransactedamountBase
USD Spot Price at Transactionprice
USD SubtotalamountQuote
USD Total (inclusive of fees)totalQuote
USD Feesfees
NotesmemoInternal

Newton

File columnRead as
Datetimestamp
TypetradeType
Received QuantityreceivedAmount
Received CurrencyreceivedCurrency
Sent QuantitysentAmount
Sent CurrencysentCurrency
Fee Amountfees
Fee CurrencyfeeCurrency

Shakepay

File columnRead as
Transaction TypetradeType
Datetimestamp
Amount DebitedsentAmount
Debit CurrencysentCurrency
Amount CreditedreceivedAmount
Credit CurrencyreceivedCurrency
Buy / Sell Rateprice
DirectiontradeType
Spot Rateprice
Source / DestinationwalletAddress
Blockchain Transaction IDtransactionHash

Kraken Trades

File columnRead as
txidtransactionHash
ordertxidorderId
pairpair
timetimestamp
typetradeType
ordertypeorderType
priceprice
costamountQuote
feefees
volamountBase

Kraken Ledger

File columnRead as
txidtransactionHash
refidorderId
timetimestamp
typetradeType
assetassetSymbol
amountamountBase
feefees

Crypto.com App

File columnRead as
Timestamp (UTC)timestamp
Transaction DescriptiontradeType
CurrencysentCurrency
AmountsentAmount
To CurrencyreceivedCurrency
To AmountreceivedAmount
Native CurrencyquoteCurrency
Native AmountamountQuote
Native Amount (in USD)price
Transaction KindorderType

Binance Transaction History

File columnRead as
UTC_Timetimestamp
OperationtradeType
CoinassetSymbol
ChangeamountBase
RemarkmemoInternal

The jurisdiction sets everything downstream: the reporting currency, the cost-basis methods available, when the tax year starts, and which special rules the calculation applies. Switching jurisdiction re-reads the same imported data under the other country’s rules — nothing about your data changes.

Generated from the running program’s jurisdiction registry.

CountryCurrencyMethodsTax year startsSpecial rules
CanadaCADACBJanuary 1superficial loss
United StatesUSDFIFO, LIFO, HIFOJanuary 1wash sale · Account-by-Account (2025+)
AustraliaAUDFIFO, LIFO, HIFOJuly 1CGT discount
United KingdomGBPACBApril 6Section 104 matching

Canada pools costs: every unit of an asset shares one average cost, and the superficial loss rule sets a loss aside when the same asset is re-bought within thirty days either side of the sale — the denied loss is added to the cost of the re-bought units rather than lost, and when only part of the sold amount is re-bought, only that part of the loss is set aside. The rule is always applied for Canada — there is no switch.

The United States tracks individual lots, choosing which lot a sale consumes by the selected method, and the wash sale rule defers a loss in full when a re-purchase falls within its thirty-day window — onto the replacement units’ cost, with no proration, unlike Canada’s rule. From 2025, Account-by-Account tracking keeps each exchange or wallet as its own population of lots. The method also decides which lots remain: first-in-first-out consumes the oldest so the newest are left, last-in-first-out the reverse, and highest-in-first-out consumes the most expensive so the cheapest are left — worth knowing when a Lot Tracking report shows holdings you did not expect.

Australia tracks lots the same way, with no wash-sale rule; instead, units held longer than twelve months qualify for the capital gains discount, and the reports show discounted and undiscounted amounts separately. The netting order matters and the program follows the return’s: losses are applied against non-discount gains first, then against discount-eligible gains, and the discount reduces only what remains.

The United Kingdom pools costs like Canada, but with two matching rules that run before the pool: a sale first matches purchases made the same day, then purchases within the following thirty days, and only the remainder draws on the pool. An acquisition consumed by those matching rules never enters the pool — the Pool History report marks it as diverted, which is why a purchase can appear there with a reduced or zero pool change. The annual exempt amount is shown on the reports for reference and is never deducted from the figures.

This chapter starts from symptoms — what you can see going wrong — and names the usual causes and the way out. It covers the problems that live outside the program’s own checks. When a calculation is blocked or a check reports a finding, the report’s own rows are the better door: each carries a Learn more link into the section that explains it.

A message about the database being locked usually means another copy of PrivateACB has the file open — close the other window — or the file sits in a cloud-synced folder that is mid-sync. Let the sync finish, and prefer keeping the working file outside actively syncing folders; a synced copy kept as a backup is fine.

A rejected password is case-sensitive: check Caps Lock, type it slowly, or paste it from a password manager. If the password is genuinely lost, the file cannot be opened and there is no recovery. A backup made before a password change still opens with its old password; otherwise the only path is a fresh database and a re-import of your exchange files.

If the password is right and the file still will not open, check that the file is intact: a zero-byte file, an interrupted copy or download, or a failing disk are the common causes of a damaged database. Try your most recent backup copy first.

If you cannot find the file at all: the title bar shows the full path whenever a database is open, so an earlier look at it is the fastest pointer. Otherwise search the machine for .db files and check the Recycle Bin, cloud folders, and external drives. Large databases also open noticeably faster from an internal drive than from an external one.

Signs that an import went in badly: every row carries the same timestamp or a date around 1970, amounts are all zero, asset symbols are blank, or every transaction became the same type when you know the file mixes buys and sells. Wrong dates split into two distinct causes — the wrong column was mapped as the timestamp, or the wrong timezone was chosen — and the fix is the same loop either way: delete the import job, adjust the setting in the wizard, and import the file again, as the Importing chapter’s starting-over section describes.

An import that fails partway leaves nothing behind: the write is all-or-nothing, so an error mid-import rolls every row back rather than leaving half a file in the database. Duplicate warnings on a file you have never imported before usually mean the file itself repeats a row — the program skips true duplicates on its own either way.

A fetch that reports zero stored rates usually asked for days the source has nothing for: rate publishers skip weekends and holidays, and the program covers those gap days with the nearest earlier trading day’s rate instead of storing empties. Repeating a fetch over the same days is also quiet — new values simply overwrite the old, newest wins.

When a deep-history date stays unfetched, the pattern usually names the cause. Dates before 2017 in a Canadian, Australian, or United Kingdom report have no keyless currency-conversion rate available, so those dates are flagged for manual entry or a rate CSV. A coin the free sources do not carry shows as manual only — its prices can still be entered by hand or imported from a price CSV, as the Prices chapter describes.

Report figures do not match your own arithmetic

Section titled “Report figures do not match your own arithmetic”

When a report’s totals disagree with a spreadsheet of your own, the usual causes are legitimate: a loss the rules denied or deferred moved into a later cost basis; fees changed proceeds or cost; or a foreign-currency trade was converted at the official rate for the disposal date rather than the rate your spreadsheet used. Settle it row by row, not total by total: the per-transaction reports and the Review tab’s ledger show every disposal with the rule that touched it, so the first row that disagrees names the cause.

When the problem is a finding, not a fault

Section titled “When the problem is a finding, not a fault”

Blocked calculations, unmatched receives, balance differences, and price gaps are not faults — they are findings, and they carry their own doors. The checks chapter explains what each check examines, the Resolution Guide chapter walks the fix channels, and every check row’s Learn more link lands on the section that explains it. When you have an exact message in front of you, search is the fastest route: the search box matches the text of every chapter.