You hold Bitcoin in self-custody. Good. You buy through multiple brokers. Even better. And now the tax authority asks which coins you bought when, which of them are tax-free and exactly how high your taxable gain is.
For exactly this problem there is the BTC Tax Tool — an open-source CLI tool I developed myself for my own tax return. It reads your CSV exports from BitBox, 21bitcoin, Bison, Swissquote, Strike and Pocket and automatically calculates what has to go to the tax office and what remains tax-free.
"Don't Trust, Verify — including your accountant. If you understand how the calculation works, you're not at anyone's mercy."
1. The Foundation: What German Tax Law Says
Bitcoin is classified in Germany as a private disposal transaction (§ 23 EStG). The rules:
| Situation | Tax treatment |
|---|---|
| BTC held less than 365 days, then sold | Profit taxable |
| BTC held more than 365 days, then sold | Profit tax-free |
| Transfer between your own wallets/accounts | Not a taxable event |
| Profit under 600 EUR/year (until 2023) | Exemption threshold — not a single cent in tax |
| Profit under 1,000 EUR/year (from 2024) | Exemption threshold — not a single cent in tax |
The method is called FiFo — First In, First Out. That means: what you buy first, you also sell first. Sounds simple, but gets complicated quickly when you buy from five brokers and your BTC moves between multiple wallets.
The Exemption Threshold Is a Trap
Many people think: "I'm under 1,000 EUR, so it's irrelevant." Wrong. The exemption threshold is not a tax allowance. If you exceed it, the entire taxable profit becomes taxable — not just the part above it. A profit of 1,001 EUR is therefore fully taxable — not just that one euro.
2. The Problem with Self-Custody
Tax apps like CoinTracking or Blockpit work well for exchanges that record everything. For genuine self-custody holders with hardware wallets, problems arise:
- You transfer BTC from your BitBox to an exchange for a sale — this looks like a purchase.
- You have multiple wallets — the cost basis travels with them.
- Swissquote buys in USD — the historical exchange rate must be correctly factored in.
- You enter your complete financial data into a cloud app — that contradicts the whole point of self-custody.
The BTC Tax Tool runs locally on your machine. No cloud, no registration, no third-party servers. Your data stays with you.
3. Installation (one-time)
You need Python 3 — on Linux and macOS it is already installed. On Windows you may need to install it first (python.org).
Mac / Linux:
git clone https://github.com/Alien-Investor/btc-steuertool.git cd btc-steuertool python3 -m venv .venv .venv/bin/pip install -r requirements.txt
Windows:
git clone https://github.com/Alien-Investor/btc-steuertool.git cd btc-steuertool python -m venv .venv .venv\Scripts\pip install -r requirements.txt
That's it. No database, no server, no subscription.
4. Place Your CSV Files
Export your CSV files from the respective apps and place them in the corresponding folders.
The folders bitbox/ and Broker/ don't exist yet after cloning —
they are listed in .gitignore so your financial data never accidentally ends up on GitHub.
You need to create them once yourself:
Mac / Linux:
mkdir -p bitbox Broker
Windows:
mkdir bitbox mkdir Broker
| Source | Folder | Filename |
|---|---|---|
| BitBox (hardware wallet) | bitbox/ |
any name, all *.csv files are loaded |
| 21bitcoin | Broker/ |
must start with 21bitcoin |
| Bison | Broker/ |
Bison-CSV-Gesamt.csv |
| Swissquote | Broker/ |
Swissquote_CSV-Gesamt.csv |
| Strike | Broker/ |
strike_2024.csv, strike_2025.csv etc. |
Broker/ |
must start with Pocket |
|
| noKYC purchases (Bisq, Robosats, P2P, cash) | Project folder | manual_buys.csv — optional, create yourself |
| Private sales (P2P without broker) | Project folder | manual_sales.csv — optional, create yourself |
Your data stays local
The folders bitbox/ and Broker/ as well as the files
manual_buys.csv and manual_sales.csv are listed in
.gitignore — they will never accidentally be checked into Git
or put online. Your financial data stays on your machine.
noKYC Purchases and Private Sales
Anyone who buys BTC without a KYC broker — via Bisq, Robosats, HodlHodl or directly person-to-person —
has no broker CSV. For this there is manual_buys.csv: a simple text file
in the project folder where you enter each purchase with date, BTC amount and EUR amount.
date,btc_amount,eur_amount,note 2024-03-10,0.01000000,550.00,Bisq P2P purchase 2024-07-22,0.00500000,280.00,Robosats trade
Same principle for private sales without a broker: manual_sales.csv in the same format.
The tool reads both files automatically and processes them like any other purchase or sale.
On the legal situation: You are not required to disclose your complete wallet fingerprint. As long as acquisition costs are correctly stated and taxable gains are fully reported, this is unproblematic under tax law. The tax authority has no claim to your complete UTXO history.
5. Your First Report
Output a report for a specific year:
.venv/bin/python src/main.py --year 2024
All years at once:
.venv/bin/python src/main.py --all
With formal documentation for your accountant or tax office:
.venv/bin/python src/main.py --year 2024 --csv --nachweis
The result lands in reports/: a readable tax report, a print-ready
formal proof of calculation and optionally CSV tables for Excel.
6. What You Submit to the Tax Office
The proof alone is not enough. The tax office wants to know that the purchase data is genuine. So always submit two parts:
- The tax proof — what the tool generates (
steuernachweis_YEAR.txt). - The original broker CSVs — as evidence that the purchases actually took place.
The tool shows in the proof under "Source" exactly which broker provided which lot — so you can trace every single sale without gaps.
7. What This Tool Is Not
Not a replacement for a tax advisor. If you have taxable gains, have the results reviewed — especially in the first year. The tool calculates correctly according to FiFo, but you are responsible for the accuracy of your inputs.
What it is: a tool that informs and prepares you — instead of leaving you blindly trusting a cloud app you don't control.
Open Source on GitHub & Codeberg
The complete code is public, free and open-source. You can verify how every line of the calculation works. Fictional sample data for all supported brokers is included as well — so you can test the tool before loading your real data.
github.com/Alien-Investor/btc-steuertool · 🔗 codeberg.org/Alien-Investor/btc-steuertool