Important
Supported Platforms: Currently, this tool is designed to work specifically with Binance and Bitvavo CSV exports. Other platforms are not officially supported yet.
Warning
Potential Calculation Errors: While the engine is backed by a robust automated test suite, cryptocurrency tax rules are highly complex. This tool is provided "as is" and may contain bugs or miscalculations. Always cross-verify the results and consult a professional tax advisor before filing.
A high-precision Python CLI tool that parses platform transaction exports, resolves historical prices in EUR, applies a global FIFO engine with anti-wash sale rules, and generates detailed tax reports for the Spanish tax authorities (Hacienda Estatal - Modelo 100 or Hacienda Foral de Gipuzkoa - Modelo 109).
- Global FIFO Engine with High Precision: Uses Python's
Decimalclass for all mathematical calculations, preventing rounding errors common with standard float values. - Dual Tax Regimes (Gipuzkoa vs. State):
- Gipuzkoa (Modelo 109): Maps transactions to boxes 37, 38, 03, and 06.
- State / Territorio Común (Modelo 100): Maps transactions to boxes 1626, 1631, 0033, and 0304.
- Anti-Wash Sale Rules (365-day Window): Implements the legally correct Spanish/Gipuzkoa anti-application of losses (regla anti-aplicación). If you sell an asset at a loss and repurchase it within ±365 days, the loss is deferred and added to the cost basis of the repurchased assets.
- Transfer Matching & Reconciliation Engine: Automatically matches a withdrawal from exchange A to a deposit on exchange B if they occur within a 2-hour window. The difference between the withdrawal and deposit amounts is recognized as a network transfer fee, which is deducted from the oldest FIFO lots and capitalized into the remaining lot units to preserve original cost basis.
- Data Health Check & Sanity Report: Chronologically pre-sweeps your transactions to detect negative balances (attempting to trade/withdraw more crypto than is present in the inventory) and missing price resolutions (resolving to 0.0 EUR), flagging potential missing CSV imports or API resolution issues.
- Non-Taxable Transfer Handling: Categorizes unmatched deposits and withdrawals (e.g. transfers to/from personal external wallets) as non-taxable transfers. These update the exchange balances without triggering phantom gains or generating new FIFO lots.
- Fair Transaction Fee Division: Groups transactions sharing a timestamp (e.g. swaps/converts) and splits the fee equally among the active legs, preventing transaction fees from being double-counted.
- Multi-Source Price Resolution:
- Primary: minute-by-minute historical data from the Binance API.
- Fallback: daily historical prices from CoinGecko.
- Fiat Conversion: conversion of USD/other values using official ECB / Frankfurter API rates.
- Staking, Airdrops & Deferred Income: Separates staking rewards (Rendimientos del Capital Mobiliario) from airdrops (Base General) and handles locked assets (e.g. welcome incentives) using an unlock schedule.
Ensure you have Python 3.12+ installed.
- Clone or navigate to the workspace directory:
cd CryptoFifoCalculator - Set up a virtual environment and install the required dependencies (using
uvorpip):python -m venv .venv source .venv/bin/activate # On Linux/macOS # .venv\Scripts\activate # On Windows pip install -r pyproject.toml # or use `uv pip install -r pyproject.toml`
- main.py: CLI entry point for configuring and running the analysis.
- config.py: Configures transaction mappings, tax box definitions, token rebrandings, and API maps.
- transaction_service.py: Processes transactions in chronological groups, distributes fees, and tracks balances.
- fifo_service.py: Core FIFO calculator implementing lot queueing and anti-wash sale window logic.
- price_service.py: Parallel price prefetcher and resolver with local persistent caching.
- console_renderer.py: Formats and renders estimated liquidations, tax boxes, and warnings to the console.
- report_service.py: Exports detailed transaction audit logs to CSV format.
- logger_config.py: Setting up concurrent file-based (
session.log) and custom console-based logging. - loaders/: Platform-specific loader modules for parsing CSV formats of different exchanges.
- tests/: Comprehensive pytest suite covering loaders, services, and core calculations.
To run the calculator, you must place your platforms' transaction exports as CSV files inside a folder named plataforms/ in the project root directory.
To process your Binance operations correctly, you must download two separate histories and place them in plataforms/:
- Full Transaction History (
plataforms/Binance.csv): Retrieve this by going to Binance's Data Download Center and exporting your complete transaction history. - Simple Earn History (
plataforms/BinanceSimpleEarnFlexible.csv): Retrieve this by going to Binance's Data Download Center and exporting your complete Simple Earn.
- Transaction History (
plataforms/Bitvavo.csv): Export the full transaction ledger in CSV format from your Bitvavo dashboard.
Runs the calculator for all transactions and prints the summary mapped to Gipuzkoa's Modelo 109 boxes:
python main.pyRuns the calculator using the Spanish State tax regime and prints the summary mapped to the Modelo 100 boxes:
python main.py --regime comun
# or
python main.py -r comunFilter calculations for a specific tax year:
python main.py --year 2021Focuses on auditing a single coin (e.g. BTC) and prints every FIFO lot entry, consumption event, and cost basis adjustment in detail:
python main.py --trace BTCClear the price cache and fetch fresh historical market prices:
python main.py --clear-cache| Argument | Description | Default |
|---|---|---|
-r, --regime |
Tax regime to use: gipuzkoa (Modelo 109) or comun (State Modelo 100). |
gipuzkoa |
-y, --year |
Specific year(s) to process. | All years |
-d, --dust |
Filters out wallet balances below this EUR threshold from the final report. | 0.01 |
-l, --limit |
Limits execution to the first N transactions (Diagnostic Mode). | None |
--from |
Start date filter (YYYY-MM-DD). | None |
--to |
End date filter (YYYY-MM-DD). | None |
-c, --check-only |
Performs calculations and checks logic without saving CSV reports. | False |
-o, --output |
Custom directory to save CSV reports. | reports |
--no-cache |
Ignores the local JSON price cache. | False |
--clear-cache |
Deletes the local JSON price cache before starting. | False |
-t, --trace |
Traces FIFO queue history for a specific coin (Diagnostic Mode). | None |
--detailed |
Print detailed transaction-by-transaction logs to the terminal. | False |
-v, --verbose |
Shows detailed debug output. | False |
-q, --quiet |
Suppresses progress logging. | False |
You can customize the calculator to match your specific cryptocurrency transactions and asset migrations by modifying config.py. The key configuration parameters include:
UNLOCK_SCHEDULE: Adjust or add entries to define specific UTC release dates for locked promotional tokens (e.g., welcome rewards, signup bonuses, vesting schedules). Once the date passes, the engine automatically unlocks the assets for active trading.COIN_MAPPING: Define token rebrandings and migrations (such asMATICtoPOLorKLAYtoKAIA). This instructs the FIFO engine to treat both tickers as the same continuous lot sequence, maintaining cost basis correctly.COIN_RATIO: Define split ratios for migrations (e.g.,MCtoBEAMXwith a multiplier ratio of100.0). The system automatically scales your token quantities and reduces the acquisition cost basis proportionately.DEFAULT_CG_ID_MAP: Set unique CoinGecko API ID slugs for custom or exotic coins (e.g., mapping tickerBTCto ID slugbitcoin). Use this if a coin ticker fails to resolve automatically on CoinGecko.MANUAL_PRICES: Provide price overrides for specific tokens on specific dates in format'COIN_YYMMDD' : price_in_eur. Useful if APIs miss pricing data or for private OTC transactions.
The project features a comprehensive pytest suite testing FIFO queues, loaders, price resolving, and the transaction processor.
Run the tests using uv (recommended) or direct python/pytest commands:
uv run pytest
# or
.venv/bin/pytestWe use Ruff for lightning-fast Python linting and formatting. It enforces PEP-8 rules, imports sorting, clean exception handling, and common bug prevention logic (defined in pyproject.toml).
- Check for code style / quality errors:
uv run ruff check . - Auto-format source files:
uv run ruff format .
This software is an analytical tool designed to help you process cryptocurrency transaction logs. The estimations and tax box mappings generated are not official tax advice. Cryptocurrency tax regulations are subject to frequent updates; always consult with a qualified tax advisor (Asesor Fiscal) before submitting any tax returns.