Zyvo ← All posts
Tax Reporting

Why Your Portfolio Tracker Shows a Fake Taxable Sale After a Broker Transfer

You moved 100 shares of a stock from Broker A to Broker B, in-kind, without selling anything. A week later your tracker shows a $4,000 capital gain that doesn't exist. Nothing was sold — but the tracker doesn't know that, because it never saw a transfer. It saw a sell at Broker A and a buy at Broker B, in two completely separate import files, with nothing connecting them.

The core issue: an in-kind (ACATS) transfer is not a disposal, so it isn't taxable and shouldn't appear on Form 8949 at all. But most portfolio trackers build your history broker-by-broker from independent CSV exports or API feeds — there is no field in either file that says "this was actually one transfer, not two trades."

Why the tracker can't tell the difference on its own

Broker A's export says: sold 100 shares on March 3rd. Broker B's export says: bought 100 shares on March 5th. Read separately, those are two ordinary trades. Read together, they're obviously the same event — same symbol, same quantity, a few days apart, different brokers. The signal is there, but only if something is actually looking across both files for the pattern, rather than importing each one in isolation.

What to look for manually: a sell and a buy of the same symbol, for a matching quantity (allow tiny rounding, not an exact match if your broker reports fractional shares slightly differently), at two different brokers, within roughly a week of each other. That combination is almost always a transfer, not two independent trading decisions.

The obvious fix is incomplete

Once you've spotted the pair, the instinct is to just delete both the fake sell and the fake buy. That removes the phantom gain — but it also erases the cost basis and acquisition date that were attached to those transactions, and does nothing to tell your records that the shares now sitting at Broker B are the same shares you originally bought years earlier at Broker A.

For most US filers this is a smaller problem: cost-basis lots are tracked per taxpayer, not per broker, so as long as the original buy transaction (the one that funded the position before the transfer) still exists somewhere in your history, the lot survives. But it's a real problem anywhere lots are tracked per account — Germany's FIFO-per-Depot rule under § 20 EStG is the clearest example. If the surviving lot is still labeled with the old broker, the next time you actually sell at the new broker, there's no lot history there at all — and the sale gets reported with zero cost basis and the full proceeds as taxable gain. The fix built to remove one phantom gain ends up creating a bigger one.

What actually needs to happen

Correcting this properly means three things at once: removing the fake sell and buy, and re-labeling the surviving open lot(s) at the source broker onto the receiving broker — oldest lots first, up to the quantity that was transferred, leaving anything beyond that amount where it is (a partial transfer is a real scenario, not an edge case to ignore). Get any one of those three wrong and you've either still got a phantom gain, a lot with no broker, or a lot that got moved when only part of the position actually was.


Not every same-symbol pair is a transfer. A coincidental sell at one broker and buy at another — a real trading decision, not a transfer — can occasionally match on symbol, quantity, and timing by chance. Any detection like this should be a suggestion you confirm or dismiss, not something applied silently.
Zyvo checks every sell against buys at other brokers within a 7-day window and flags a likely transfer automatically — after CSV import and after a broker sync. One click removes both legs and re-labels the correct number of surviving lots onto the receiving broker, with undo available. Try it in the live demo →
Related reading: Stock splits & broker transfers · The wash sale rule across brokers