Coinbase, Binance and Kraken: how the three biggest exchanges' tax CSVs actually differ

A user with accounts at all three of the largest US-accessible crypto exchanges who tries to file a single tax return will discover that none of the three CSV exports is in the same format, none uses the same field names, and none classifies internal transfers the same way. Here is a side-by-side of what each one ships and how to reconcile them.

Topics: CryptoTaxBrokers

The tax workflow for a US retail crypto investor with accounts on more than one exchange has the same shape every time. You log into each platform in turn, find the "tax" or "history" export, click download, and end up with three CSV files on your desktop that look superficially similar and are in fact incompatible. Field names differ. Date formats differ. Quantity precision differs. The classification of a transfer to your own wallet differs. None of the files can be concatenated as-is and fed into a tax tool.

This article is a side-by-side audit of the three biggest exchanges as of early 2026, focused specifically on the things that break automated reconciliation. The point is not to complain - the exports are documented and the data is there - but to make clear what work the customer is actually being asked to do.

Coinbase: the "Gain/Loss Report" and the "Transactions" CSV

Coinbase produces two distinct downloads with overlapping but non-identical content, both reachable from the Tax Reports and Forms section:

  • Gain/Loss Report (CSV). Pre-calculated capital gains by lot, in USD. Useful at a glance, but Coinbase computes the basis using its own assumptions for any coin that originated outside Coinbase. The cost basis FAQ explicitly notes that transferred-in coins may show a missing or zero cost basis.
  • Transactions CSV. The raw event log: buys, sells, sends, receives, conversions, rewards. Has a "Transaction Type" column, an "Asset" column, a "Quantity Transacted" column, a "Spot Price at Transaction" column, and a "Subtotal / Fees / Total" trio. This is the file you actually want to feed into a tax tool.

Two quirks in the Transactions CSV catch out automated parsers:

  1. "Convert" is its own transaction type, not a pair of sell/buy events. A USDC-to-ETH conversion shows up as one row with both assets implied. Tools that expect every disposal to have a paired acquisition can mis-classify these.
  2. "Send" and "Receive" are both used for transfers. Coinbase does not flag whether the destination is one of the customer’s own wallets. The customer has to mark these manually if they do not want them treated as taxable disposals.

Binance.US: the "Transaction History" CSV

Binance.US documents its tax exports on the tax statements page. The primary export is a single Transaction History CSV with the following column structure (paraphrased; exact names have changed across years):

FieldWhat it contains
UTC TimeISO 8601 timestamp; second precision
OperationBuy / Sell / Deposit / Withdrawal / Distribution / Staking Rewards / Commission Rebate
Account"Spot", "Earn", "Margin" — routing flag for which sub-account
CoinAsset symbol
ChangeSigned quantity (negative for outgoing, positive for incoming)
RemarkFree text. Sometimes has the trade pair, sometimes blank

The first quirk: a single trade is recorded as two or three rows. A spot buy of ETH with USDT shows up as one row debiting USDT, one row crediting ETH and one row debiting the fee in BNB. The pairing is implicit from the timestamp; tools have to group rows that share the second-precision UTC time and the same account into a single trade event. This is one of the most common parsing failures in automated importers.

The second quirk: Binance does not record a USD spot price for non-USD pairs. A trade of ETH for SOL is recorded with the on-platform book price, which may differ from the IRS-relevant USD spot at the second of execution. For US filing, that USD value has to be looked up from an independent price source (CoinGecko and Kaiko both publish second-level historical spot for major pairs).

Kraken: the "Trades" and "Ledgers" CSVs

Kraken’s exports are documented in the account history support article. The platform produces two complementary CSVs:

  • Trades CSV. One row per trade, with the pair, type (buy/sell), price, cost, fee, and volume. Easiest to read.
  • Ledgers CSV. One row per balance change, including trades, deposits, withdrawals, fees and staking accruals. The most complete record of any of the three exchanges in this article.

The Ledgers CSV is what most calculators want to ingest, because it captures everything that affects the customer’s position, including staking rewards as their own line items with timestamps and asset balances. The trade-off is that to reconstruct a single trade you have to join two rows from the Ledgers file by the "refid" column, which is the only field that links the asset-out row to the asset-in row.

One Kraken-specific quirk: the asset symbols are prefixed. BTC is "XXBT", ETH is "XETH", USD is "ZUSD". The "X" and "Z" prefixes are Kraken’s internal shorthand for cryptocurrency vs fiat. Tools have to strip the prefix and remap to the standard symbol, otherwise the asset will not match anything in the price database.

The fields nobody agrees on

FieldCoinbaseBinanceKraken
Timestamp formatISO 8601 with timezoneUTC second precision, no timezone markerUnix epoch with sub-second decimals
Trade representationOne row per trade, paired implicitlyTwo or three rows per trade, grouped by timestampTwo rows per trade, joined by refid
Internal transfer flagNone; "Send" / "Receive"None; "Withdrawal" / "Deposit"None; "withdrawal" / "deposit"
Asset symbolStandard tickerStandard tickerPrefixed (XXBT, XETH, ZUSD)
Fee currencySame as proceedsOften a different asset (BNB, BUSD)Always quoted currency of the pair
USD value for non-USD pairsComputed and providedNot provided; must be looked upNot provided; must be looked up

Why this matters for the customer

Three implications follow from the audit above:

You cannot just concatenate the CSVs. A tax tool that asks you to "upload your exchange data" has to know which exchange each file came from, and apply the right parser per file. Generic "drop your CSV in" tools either fail silently on edge cases or pre-process to a common format and lose information.

Internal transfers must be reconciled across exchanges. If you withdrew 0.5 BTC from Coinbase on 1 March and deposited 0.499 BTC into Kraken on 1 March (the difference being the network fee), neither exchange knows the destination of the other side. Both will treat their leg as a one-sided event. The reconciliation has to happen at the calculator level, by matching withdrawals out of Exchange A to deposits into Exchange B within a few hours, and flagging them as a same-owner transfer.

USD price lookups are not optional. For any year with non-USD pair trades, somebody has to fill in the USD value at the second of execution. Tools that skip this step silently produce a tax bill that does not match what the IRS expects to see. Tools that do it well use a high-frequency historical price source and document the lookup in the audit trail.

How our calculator handles it

The SafeFinance Crypto Tax Calculator ships with explicit per-exchange parsers for Coinbase, Binance and Kraken, plus a generic CSV mode for everything else. The user picks the exchange in the upload dialog, the right parser fires, and the tool emits a normalised internal representation that is identical regardless of which exchange the data came from. Internal transfers are auto-detected by amount + timestamp matching across files. USD spot prices for non-USD pairs are filled in from a cached public price source, with the lookup time-stamped in the audit log.

The choice of three explicit parsers (rather than one generic one) is deliberate, and it is the result of the kind of audit above. A generic parser will get you 80 percent of the way through a clean year. The remaining 20 percent is where a $5,000 mis-classification hides, and it is the one the IRS notices.